effect-app 4.0.0-beta.24 → 4.0.0-beta.241

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 (244) hide show
  1. package/CHANGELOG.md +1060 -0
  2. package/dist/Array.d.ts +3 -2
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +4 -4
  5. package/dist/Chunk.d.ts +1 -1
  6. package/dist/Chunk.d.ts.map +1 -1
  7. package/dist/Config/SecretURL.d.ts +4 -2
  8. package/dist/Config/SecretURL.d.ts.map +1 -1
  9. package/dist/Config/SecretURL.js +3 -6
  10. package/dist/Config/internal/configSecretURL.d.ts +1 -1
  11. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  12. package/dist/Config/internal/configSecretURL.js +2 -2
  13. package/dist/Config.d.ts +7 -0
  14. package/dist/Config.d.ts.map +1 -0
  15. package/dist/Config.js +6 -0
  16. package/dist/ConfigProvider.d.ts +39 -0
  17. package/dist/ConfigProvider.d.ts.map +1 -0
  18. package/dist/ConfigProvider.js +42 -0
  19. package/dist/Context.d.ts +42 -0
  20. package/dist/Context.d.ts.map +1 -0
  21. package/dist/Context.js +67 -0
  22. package/dist/Effect.d.ts +11 -10
  23. package/dist/Effect.d.ts.map +1 -1
  24. package/dist/Effect.js +5 -7
  25. package/dist/Function.d.ts +1 -1
  26. package/dist/Function.d.ts.map +1 -1
  27. package/dist/Inputify.type.d.ts +1 -1
  28. package/dist/Layer.d.ts +11 -7
  29. package/dist/Layer.d.ts.map +1 -1
  30. package/dist/Layer.js +3 -2
  31. package/dist/NonEmptySet.d.ts +4 -2
  32. package/dist/NonEmptySet.d.ts.map +1 -1
  33. package/dist/NonEmptySet.js +2 -2
  34. package/dist/Option.d.ts +2 -1
  35. package/dist/Option.d.ts.map +1 -1
  36. package/dist/Option.js +3 -1
  37. package/dist/Pure.d.ts +8 -6
  38. package/dist/Pure.d.ts.map +1 -1
  39. package/dist/Pure.js +17 -14
  40. package/dist/Schema/Class.d.ts +66 -20
  41. package/dist/Schema/Class.d.ts.map +1 -1
  42. package/dist/Schema/Class.js +192 -23
  43. package/dist/Schema/FastCheck.d.ts +1 -1
  44. package/dist/Schema/FastCheck.d.ts.map +1 -1
  45. package/dist/Schema/Methods.d.ts +1 -1
  46. package/dist/Schema/SchemaParser.d.ts +5 -0
  47. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  48. package/dist/Schema/SchemaParser.js +6 -0
  49. package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
  50. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  51. package/dist/Schema/SpecialJsonSchema.js +118 -0
  52. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  53. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  54. package/dist/Schema/SpecialOpenApi.js +123 -0
  55. package/dist/Schema/brand.d.ts +5 -3
  56. package/dist/Schema/brand.d.ts.map +1 -1
  57. package/dist/Schema/brand.js +3 -1
  58. package/dist/Schema/email.d.ts +1 -1
  59. package/dist/Schema/email.d.ts.map +1 -1
  60. package/dist/Schema/email.js +7 -4
  61. package/dist/Schema/ext.d.ts +339 -56
  62. package/dist/Schema/ext.d.ts.map +1 -1
  63. package/dist/Schema/ext.js +358 -53
  64. package/dist/Schema/moreStrings.d.ts +108 -26
  65. package/dist/Schema/moreStrings.d.ts.map +1 -1
  66. package/dist/Schema/moreStrings.js +45 -16
  67. package/dist/Schema/numbers.d.ts +55 -15
  68. package/dist/Schema/numbers.d.ts.map +1 -1
  69. package/dist/Schema/numbers.js +60 -12
  70. package/dist/Schema/phoneNumber.d.ts +1 -1
  71. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  72. package/dist/Schema/phoneNumber.js +6 -3
  73. package/dist/Schema/schema.d.ts +1 -1
  74. package/dist/Schema/strings.d.ts +5 -5
  75. package/dist/Schema/strings.d.ts.map +1 -1
  76. package/dist/Schema/strings.js +1 -5
  77. package/dist/Schema.d.ts +214 -8
  78. package/dist/Schema.d.ts.map +1 -1
  79. package/dist/Schema.js +190 -11
  80. package/dist/Set.d.ts +5 -2
  81. package/dist/Set.d.ts.map +1 -1
  82. package/dist/Set.js +3 -2
  83. package/dist/TypeTest.d.ts +1 -1
  84. package/dist/Types.d.ts +1 -1
  85. package/dist/Widen.type.d.ts +1 -1
  86. package/dist/_ext/Array.d.ts +2 -2
  87. package/dist/_ext/Array.d.ts.map +1 -1
  88. package/dist/_ext/Array.js +4 -2
  89. package/dist/_ext/date.d.ts +1 -1
  90. package/dist/_ext/misc.d.ts +5 -2
  91. package/dist/_ext/misc.d.ts.map +1 -1
  92. package/dist/_ext/misc.js +4 -2
  93. package/dist/_ext/ord.ext.d.ts +3 -2
  94. package/dist/_ext/ord.ext.d.ts.map +1 -1
  95. package/dist/_ext/ord.ext.js +2 -2
  96. package/dist/builtin.d.ts +1 -1
  97. package/dist/builtin.d.ts.map +1 -1
  98. package/dist/client/InvalidationKeys.d.ts +29 -0
  99. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  100. package/dist/client/InvalidationKeys.js +33 -0
  101. package/dist/client/apiClientFactory.d.ts +20 -32
  102. package/dist/client/apiClientFactory.d.ts.map +1 -1
  103. package/dist/client/apiClientFactory.js +104 -34
  104. package/dist/client/clientFor.d.ts +51 -17
  105. package/dist/client/clientFor.d.ts.map +1 -1
  106. package/dist/client/clientFor.js +9 -1
  107. package/dist/client/errors.d.ts +49 -25
  108. package/dist/client/errors.d.ts.map +1 -1
  109. package/dist/client/errors.js +43 -17
  110. package/dist/client/makeClient.d.ts +481 -33
  111. package/dist/client/makeClient.d.ts.map +1 -1
  112. package/dist/client/makeClient.js +66 -24
  113. package/dist/client.d.ts +6 -5
  114. package/dist/client.d.ts.map +1 -1
  115. package/dist/client.js +2 -1
  116. package/dist/faker.d.ts +1 -1
  117. package/dist/faker.d.ts.map +1 -1
  118. package/dist/http/Request.d.ts +2 -2
  119. package/dist/http/Request.d.ts.map +1 -1
  120. package/dist/http/Request.js +2 -2
  121. package/dist/http/internal/lib.d.ts +1 -1
  122. package/dist/http.d.ts +1 -1
  123. package/dist/ids.d.ts +40 -12
  124. package/dist/ids.d.ts.map +1 -1
  125. package/dist/ids.js +25 -3
  126. package/dist/index.d.ts +5 -8
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js +6 -8
  129. package/dist/logger.d.ts +1 -1
  130. package/dist/middleware.d.ts +14 -8
  131. package/dist/middleware.d.ts.map +1 -1
  132. package/dist/middleware.js +14 -8
  133. package/dist/rpc/Invalidation.d.ts +402 -0
  134. package/dist/rpc/Invalidation.d.ts.map +1 -0
  135. package/dist/rpc/Invalidation.js +150 -0
  136. package/dist/rpc/MiddlewareMaker.d.ts +11 -7
  137. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  138. package/dist/rpc/MiddlewareMaker.js +59 -38
  139. package/dist/rpc/RpcContextMap.d.ts +4 -4
  140. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  141. package/dist/rpc/RpcContextMap.js +4 -4
  142. package/dist/rpc/RpcMiddleware.d.ts +14 -10
  143. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  144. package/dist/rpc/RpcMiddleware.js +1 -1
  145. package/dist/rpc.d.ts +2 -2
  146. package/dist/rpc.d.ts.map +1 -1
  147. package/dist/rpc.js +2 -2
  148. package/dist/transform.d.ts +2 -2
  149. package/dist/transform.d.ts.map +1 -1
  150. package/dist/transform.js +4 -5
  151. package/dist/utils/effectify.d.ts +2 -2
  152. package/dist/utils/effectify.d.ts.map +1 -1
  153. package/dist/utils/effectify.js +2 -2
  154. package/dist/utils/extend.d.ts +1 -1
  155. package/dist/utils/extend.d.ts.map +1 -1
  156. package/dist/utils/gen.d.ts +5 -5
  157. package/dist/utils/gen.d.ts.map +1 -1
  158. package/dist/utils/logLevel.d.ts +3 -3
  159. package/dist/utils/logLevel.d.ts.map +1 -1
  160. package/dist/utils/logger.d.ts +5 -4
  161. package/dist/utils/logger.d.ts.map +1 -1
  162. package/dist/utils/logger.js +4 -4
  163. package/dist/utils.d.ts +40 -45
  164. package/dist/utils.d.ts.map +1 -1
  165. package/dist/utils.js +19 -27
  166. package/dist/validation/validators.d.ts +1 -1
  167. package/dist/validation/validators.d.ts.map +1 -1
  168. package/dist/validation.d.ts +1 -1
  169. package/dist/validation.d.ts.map +1 -1
  170. package/package.json +46 -24
  171. package/src/Array.ts +3 -3
  172. package/src/Config/SecretURL.ts +5 -2
  173. package/src/Config/internal/configSecretURL.ts +1 -1
  174. package/src/Config.ts +14 -0
  175. package/src/ConfigProvider.ts +48 -0
  176. package/src/{ServiceMap.ts → Context.ts} +56 -63
  177. package/src/Effect.ts +13 -14
  178. package/src/Layer.ts +10 -6
  179. package/src/NonEmptySet.ts +3 -1
  180. package/src/Option.ts +2 -0
  181. package/src/Pure.ts +21 -19
  182. package/src/Schema/Class.ts +274 -64
  183. package/src/Schema/SchemaParser.ts +12 -0
  184. package/src/Schema/SpecialJsonSchema.ts +139 -0
  185. package/src/Schema/SpecialOpenApi.ts +130 -0
  186. package/src/Schema/brand.ts +22 -2
  187. package/src/Schema/email.ts +7 -2
  188. package/src/Schema/ext.ts +443 -88
  189. package/src/Schema/moreStrings.ts +93 -37
  190. package/src/Schema/numbers.ts +64 -16
  191. package/src/Schema/phoneNumber.ts +5 -1
  192. package/src/Schema/strings.ts +4 -8
  193. package/src/Schema.ts +374 -10
  194. package/src/Set.ts +5 -1
  195. package/src/_ext/Array.ts +3 -1
  196. package/src/_ext/misc.ts +4 -1
  197. package/src/_ext/ord.ext.ts +2 -1
  198. package/src/client/InvalidationKeys.ts +50 -0
  199. package/src/client/apiClientFactory.ts +230 -131
  200. package/src/client/clientFor.ts +95 -29
  201. package/src/client/errors.ts +52 -26
  202. package/src/client/makeClient.ts +572 -71
  203. package/src/client.ts +5 -4
  204. package/src/http/Request.ts +1 -1
  205. package/src/ids.ts +25 -3
  206. package/src/index.ts +5 -10
  207. package/src/middleware.ts +13 -9
  208. package/src/rpc/Invalidation.ts +226 -0
  209. package/src/rpc/MiddlewareMaker.ts +82 -74
  210. package/src/rpc/README.md +2 -2
  211. package/src/rpc/RpcContextMap.ts +6 -5
  212. package/src/rpc/RpcMiddleware.ts +14 -11
  213. package/src/rpc.ts +1 -1
  214. package/src/transform.ts +3 -3
  215. package/src/utils/effectify.ts +1 -1
  216. package/src/utils/gen.ts +8 -8
  217. package/src/utils/logLevel.ts +1 -1
  218. package/src/utils/logger.ts +4 -3
  219. package/src/utils.ts +62 -139
  220. package/test/dist/rpc.test.d.ts.map +1 -1
  221. package/test/dist/secretURL.test.d.ts.map +1 -0
  222. package/test/dist/special.test.d.ts.map +1 -0
  223. package/test/dist/stream-error.types.d.ts +2 -0
  224. package/test/dist/stream-error.types.d.ts.map +1 -0
  225. package/test/dist/stream-error.types.js +27 -0
  226. package/test/moreStrings.test.ts +1 -1
  227. package/test/rpc.test.ts +46 -6
  228. package/test/schema.test.ts +459 -30
  229. package/test/secretURL.test.ts +160 -0
  230. package/test/special.test.ts +1026 -0
  231. package/test/utils.test.ts +7 -7
  232. package/tsconfig.base.json +6 -5
  233. package/tsconfig.json +2 -1
  234. package/tsconfig.json.bak +2 -2
  235. package/tsconfig.src.json +29 -29
  236. package/tsconfig.test.json +2 -2
  237. package/dist/Operations.d.ts +0 -123
  238. package/dist/Operations.d.ts.map +0 -1
  239. package/dist/Operations.js +0 -29
  240. package/dist/ServiceMap.d.ts +0 -44
  241. package/dist/ServiceMap.d.ts.map +0 -1
  242. package/dist/ServiceMap.js +0 -91
  243. package/eslint.config.mjs +0 -26
  244. package/src/Operations.ts +0 -55
package/src/rpc/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The extensions use V4 format of RPC middleware:
4
4
 
5
5
  - supports `requires` besides `provides`
6
- - `requires` and `provides` should be set as second generic argument: `Tag<Self, Config>`.
6
+ - `requires` and `provides` should be set as second generic argument: `Tag<Self, Config>`.
7
7
  - `wrap: true` is the default, there is no classic `provides: Tag`
8
8
 
9
9
  ## Features
@@ -34,7 +34,7 @@ NOTE: perhaps not as useful anymore if support for dynamic middleware gets integ
34
34
 
35
35
  ## Examples
36
36
 
37
- See [tests](../../../infra/test/rpc-multi-middleware.test.ts)
37
+ See [tests](../../../infra/test/rpc-multi-middleware.test.ts)
38
38
 
39
39
  ## Future
40
40
 
@@ -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 * as S from "effect/Schema"
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,17 +1,21 @@
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"
5
4
  import { type NonEmptyReadonlyArray } from "effect/Array"
5
+ import type * as Effect from "effect/Effect"
6
+ import type * as S from "effect/Schema"
7
+ import type * as Scope from "effect/Scope"
8
+ import type * as Stream from "effect/Stream"
6
9
  import { type Rpc, RpcMiddleware } from "effect/unstable/rpc"
7
10
  import { type TypeId } from "effect/unstable/rpc/RpcMiddleware"
11
+ import type * as Context from "../Context.js"
8
12
  import { type GetEffectContext, type RpcContextMap } from "./RpcContextMap.js"
9
13
 
10
14
  export type RpcMiddlewareV4<Provides, E, Requires> = RpcMiddleware.RpcMiddleware<Provides, E, Requires>
11
15
 
12
16
  export type RpcOptionsOriginal = {
13
17
  readonly optional?: boolean
14
- readonly error?: Schema.Top
18
+ readonly error?: S.Top
15
19
  readonly requiredForClient?: boolean
16
20
  }
17
21
 
@@ -39,7 +43,7 @@ export interface TagClassAny extends RpcMiddleware.AnyService {
39
43
  readonly optional: boolean
40
44
  readonly provides: any
41
45
  readonly requires: any
42
- readonly error: Schema.Top
46
+ readonly error: S.Top
43
47
  readonly dynamic?: RpcDynamic<any, any> | undefined
44
48
  readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
45
49
  }
@@ -49,18 +53,17 @@ export declare namespace TagClass {
49
53
  * @since 1.0.0
50
54
  * @category models
51
55
  */
52
- export type FailureSchema<Options> = Options extends { readonly error: Schema.Top; readonly optional?: false }
56
+ export type FailureSchema<Options> = Options extends { readonly error: S.Top; readonly optional?: false }
53
57
  ? Options["error"]
54
58
  // actually not, the Failure depends on Dynamic Middleware Configuration!
55
59
  // : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["error"]
56
- : typeof Schema.Never
60
+ : typeof S.Never
57
61
 
58
62
  /**
59
63
  * @since 1.0.0
60
64
  * @category models
61
65
  */
62
- export type Failure<Options> = Options extends { readonly error: Schema.Codec<infer _A>; readonly optional?: false }
63
- ? _A
66
+ export type Failure<Options> = Options extends { readonly error: S.Codec<infer _A>; readonly optional?: false } ? _A
64
67
  // actually not, the Failure depends on Dynamic Middleware Configuration!
65
68
  : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
66
69
  : never
@@ -69,7 +72,7 @@ export declare namespace TagClass {
69
72
  * @since 1.0.0
70
73
  * @category models
71
74
  */
72
- export type FailureContext<Options> = Schema.Codec.DecodingServices<FailureSchema<Options>>
75
+ export type FailureContext<Options> = S.Codec.DecodingServices<FailureSchema<Options>>
73
76
 
74
77
  /**
75
78
  * @since 1.0.0
@@ -102,8 +105,8 @@ export declare namespace TagClass {
102
105
  requires?: any
103
106
  provides?: any
104
107
  }
105
- > extends ServiceMap.Service<Self, Service> {
106
- new(_: never): ServiceMap.ServiceClass.Shape<Name, Service>
108
+ > extends Context.Service<Self, Service> {
109
+ new(_: never): Context.ServiceClass.Shape<Name, Service>
107
110
  readonly [TypeId]: TypeId
108
111
  readonly optional: Optional<Options>
109
112
  readonly error: FailureSchema<Options>
@@ -226,7 +229,7 @@ export type ExtractProvides<R extends Rpc.Any, Tag extends string> = R extends
226
229
  Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
227
230
  readonly provides: infer _P
228
231
  } ? [_P] extends [never] ? never
229
- : _P /*_P extends ServiceMap.Service<infer _I, infer _S> ? _I
232
+ : _P /*_P extends Context.Service<infer _I, infer _S> ? _I
230
233
  : never */
231
234
  : never
232
235
  : never
package/src/rpc.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * as RpcX from "./rpc.js"
1
+ export * as Invalidation from "./rpc/Invalidation.js"
2
2
  export * as MiddlewareMaker from "./rpc/MiddlewareMaker.js"
3
3
  export * as RpcContextMap from "./rpc/RpcContextMap.js"
4
4
  export * as RpcMiddleware from "./rpc/RpcMiddleware.js"
package/src/transform.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Option } from "effect"
3
2
  import type { NonEmptyReadonlyArray } from "effect/Array"
3
+ import * as Option from "effect/Option"
4
4
  import type { Misc, Union } from "ts-toolbelt"
5
5
  import type * as SET from "./Set.js"
6
6
 
@@ -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
  }
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
3
 
4
- import { Effect } from "effect"
4
+ import * as Effect from "effect/Effect"
5
5
 
6
6
  interface Callback<E, A> {
7
7
  (err: E, a?: A): void
package/src/utils/gen.ts CHANGED
@@ -1,24 +1,24 @@
1
- import { type Effect, type Yieldable } from "effect/Effect"
1
+ import { type Effect } from "effect/Effect"
2
2
 
3
3
  export namespace EffectGenUtils {
4
4
  export type Success<EG> = EG extends Effect<infer A, infer _E, infer _R> ? A
5
5
  // there could be a case where the generator function does not yield anything, so we need to handle that
6
6
  : EG extends (..._: infer _3) => Generator<never, 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
7
+ // generators yield Effect values
8
+ : EG extends (..._: infer _3) => Generator<Effect<any, 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
- // 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
14
+ // generators yield Effect values
15
+ : EG extends (..._: infer _3) => Generator<Effect<any, 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
- // 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
+ // generators yield Effect values
22
+ : EG extends (..._: infer _3) => Generator<Effect<any, infer _E, infer R>, infer _A, infer _2> ? R
23
23
  : never
24
24
  }
@@ -1,4 +1,4 @@
1
- import { type LogLevel } from "effect"
1
+ import type * as LogLevel from "effect/LogLevel"
2
2
 
3
3
  export const LogLevelToSentry = (level: LogLevel.LogLevel) => {
4
4
  switch (level) {
@@ -1,12 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
 
4
- import { Effect, type LogLevel } from "effect"
5
- import * as ServiceMap from "../ServiceMap.js"
4
+ import * as Effect from "effect/Effect"
5
+ import type * as LogLevel from "effect/LogLevel"
6
+ import * as Context from "../Context.js"
6
7
 
7
8
  type Levels = "info" | "debug" | "warn" | "error"
8
9
 
9
- export class LogLevels extends ServiceMap.Reference("LogLevels", {
10
+ export class LogLevels extends Context.Reference("LogLevels", {
10
11
  defaultValue: () => new Map<string, Levels>()
11
12
  }) {}
12
13
 
package/src/utils.ts CHANGED
@@ -1,20 +1,24 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-function-type */
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
  /* eslint-disable @typescript-eslint/no-redundant-type-constituents */
4
- import { Cause, Effect, Exit, Fiber, Option, Record } from "effect"
4
+ import * as Cause from "effect/Cause"
5
+ import * as Effect from "effect/Effect"
6
+ import * as Exit from "effect/Exit"
7
+ import * as Fiber from "effect/Fiber"
5
8
  import { dual } from "effect/Function"
6
- import { isFunction, isObject } from "effect/Predicate"
9
+ import * as Option from "effect/Option"
10
+ import { isFunction } from "effect/Predicate"
11
+ import * as Record from "effect/Record"
7
12
  import * as Result from "effect/Result"
8
- import type { GetFieldType, NumericDictionary, PropertyPath } from "lodash"
9
13
  import { identity, pipe } from "./Function.js"
10
14
  import type { DeepMutable, Equals, Mutable } from "./Types.js"
11
15
 
12
16
  // codegen:start {preset: barrel, include: ./utils/*.ts, nodir: false }
13
- export * from "./utils/effectify.js"
14
- export * from "./utils/extend.js"
15
- export * from "./utils/gen.js"
16
- export * from "./utils/logger.js"
17
- export * from "./utils/logLevel.js"
17
+ export * from "./utils/effectify.ts"
18
+ export * from "./utils/extend.ts"
19
+ export * from "./utils/gen.ts"
20
+ export * from "./utils/logger.ts"
21
+ export * from "./utils/logLevel.ts"
18
22
  // codegen:end
19
23
 
20
24
  export * from "effect/Utils"
@@ -24,121 +28,6 @@ export interface Clone {
24
28
  [cloneTrait](this: this, that: any): this
25
29
  }
26
30
 
27
- function get<TObject extends object, TKey extends keyof TObject>(object: TObject, path: TKey | [TKey]): TObject[TKey]
28
- function get<TObject extends object, TKey extends keyof TObject>(
29
- object: TObject | null | undefined,
30
- path: TKey | [TKey]
31
- ): TObject[TKey] | undefined
32
- function get<TObject extends object, TKey extends keyof TObject, TDefault>(
33
- object: TObject | null | undefined,
34
- path: TKey | [TKey],
35
- defaultValue: TDefault
36
- ): Exclude<TObject[TKey], undefined> | TDefault
37
- function get<TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1]>(
38
- object: TObject,
39
- path: [TKey1, TKey2]
40
- ): TObject[TKey1][TKey2]
41
- function get<TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1]>(
42
- object: TObject | null | undefined,
43
- path: [TKey1, TKey2]
44
- ): TObject[TKey1][TKey2] | undefined
45
- function get<TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TDefault>(
46
- object: TObject | null | undefined,
47
- path: [TKey1, TKey2],
48
- defaultValue: TDefault
49
- ): Exclude<TObject[TKey1][TKey2], undefined> | TDefault
50
- function get<
51
- TObject extends object,
52
- TKey1 extends keyof TObject,
53
- TKey2 extends keyof TObject[TKey1],
54
- TKey3 extends keyof TObject[TKey1][TKey2]
55
- >(object: TObject, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3]
56
- function get<
57
- TObject extends object,
58
- TKey1 extends keyof TObject,
59
- TKey2 extends keyof TObject[TKey1],
60
- TKey3 extends keyof TObject[TKey1][TKey2]
61
- >(object: TObject | null | undefined, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3] | undefined
62
- function get<
63
- TObject extends object,
64
- TKey1 extends keyof TObject,
65
- TKey2 extends keyof TObject[TKey1],
66
- TKey3 extends keyof TObject[TKey1][TKey2],
67
- TDefault
68
- >(
69
- object: TObject | null | undefined,
70
- path: [TKey1, TKey2, TKey3],
71
- defaultValue: TDefault
72
- ): Exclude<TObject[TKey1][TKey2][TKey3], undefined> | TDefault
73
- function get<
74
- TObject extends object,
75
- TKey1 extends keyof TObject,
76
- TKey2 extends keyof TObject[TKey1],
77
- TKey3 extends keyof TObject[TKey1][TKey2],
78
- TKey4 extends keyof TObject[TKey1][TKey2][TKey3]
79
- >(object: TObject, path: [TKey1, TKey2, TKey3, TKey4]): TObject[TKey1][TKey2][TKey3][TKey4]
80
- function get<
81
- TObject extends object,
82
- TKey1 extends keyof TObject,
83
- TKey2 extends keyof TObject[TKey1],
84
- TKey3 extends keyof TObject[TKey1][TKey2],
85
- TKey4 extends keyof TObject[TKey1][TKey2][TKey3]
86
- >(
87
- object: TObject | null | undefined,
88
- path: [TKey1, TKey2, TKey3, TKey4]
89
- ): TObject[TKey1][TKey2][TKey3][TKey4] | undefined
90
- function get<
91
- TObject extends object,
92
- TKey1 extends keyof TObject,
93
- TKey2 extends keyof TObject[TKey1],
94
- TKey3 extends keyof TObject[TKey1][TKey2],
95
- TKey4 extends keyof TObject[TKey1][TKey2][TKey3],
96
- TDefault
97
- >(
98
- object: TObject | null | undefined,
99
- path: [TKey1, TKey2, TKey3, TKey4],
100
- defaultValue: TDefault
101
- ): Exclude<TObject[TKey1][TKey2][TKey3][TKey4], undefined> | TDefault
102
- function get<T>(object: NumericDictionary<T>, path: number): T
103
- function get<T>(object: NumericDictionary<T> | null | undefined, path: number): T | undefined
104
- function get<T, TDefault>(
105
- object: NumericDictionary<T> | null | undefined,
106
- path: number,
107
- defaultValue: TDefault
108
- ): T | TDefault
109
- function get<TDefault>(object: null | undefined, path: PropertyPath, defaultValue: TDefault): TDefault
110
- function get(object: null | undefined, path: PropertyPath): undefined
111
- function get<TObject, TPath extends string>(
112
- data: TObject,
113
- path: TPath
114
- ): string extends TPath ? any : GetFieldType<TObject, TPath>
115
- function get<TObject, TPath extends string, TDefault = GetFieldType<TObject, TPath>>(
116
- data: TObject,
117
- path: TPath,
118
- defaultValue: TDefault
119
- ): Exclude<GetFieldType<TObject, TPath>, null | undefined> | TDefault
120
- function get(object: any, path: PropertyPath, defaultValue?: any): any
121
- function get(obj: any, path: any, defaultValue = undefined) {
122
- // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore?tab=readme-ov-file#_get
123
- const travel = (regexp: any) =>
124
- String
125
- .prototype
126
- .split
127
- .call(path, regexp)
128
- .filter(Boolean)
129
- .reduce((res, key) => (res !== null && res !== undefined ? res[key] : res), obj)
130
- const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/)
131
- return result === undefined || result === obj ? defaultValue : result
132
- }
133
-
134
- // codegen:start {preset: barrel, include: ./utils/*.ts }
135
- export * from "./utils/effectify.js"
136
- export * from "./utils/extend.js"
137
- export * from "./utils/gen.js"
138
- export * from "./utils/logger.js"
139
- export * from "./utils/logLevel.js"
140
- // codegen:end
141
-
142
31
  export const unsafeRight = <E, A>(ei: Result.Result<A, E>) => {
143
32
  if (Result.isFailure(ei)) {
144
33
  console.error(ei.failure)
@@ -269,7 +158,7 @@ export type EnforceNonEmptyRecord<R> = keyof R extends never ? never : R
269
158
  export function intersect<AS extends unknown[] & { 0: unknown }>(
270
159
  ...as: AS
271
160
  ): UnionToIntersection<{ [k in keyof AS]: AS[k] }[number]> {
272
- return as.reduce((a: any, b: any) => ({ ...a, ...b })) as any
161
+ return as.reduce((a: any, b: any) => Object.assign(a, b), {}) as any
273
162
  }
274
163
 
275
164
  export type IsEqualTo<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
@@ -280,8 +169,7 @@ export type IsEqualTo<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
280
169
  export const unifyIndex = Symbol()
281
170
  export type unifyIndex = typeof unifyIndex
282
171
 
283
- // @ts-expect-error abc
284
- export interface UnifiableIndexed<X> {}
172
+ export interface UnifiableIndexed<_X> {}
285
173
  export type UnifiableIndexedURI = keyof UnifiableIndexed<any>
286
174
 
287
175
  export interface Unifiable<X> {
@@ -313,9 +201,7 @@ function decorateNew(
313
201
  if (out.descriptor) {
314
202
  out.descriptor = Object.assign({}, out.descriptor)
315
203
  }
316
- const actualDesc: PropertyDescriptor = <any> (
317
- out.descriptor || /* istanbul ignore next */ out
318
- )
204
+ const actualDesc: PropertyDescriptor = out.descriptor || /* istanbul ignore next */ out
319
205
 
320
206
  const originalMethod = validateAndExtractMethodFromDescriptor(actualDesc)
321
207
  const isStatic = inp.placement === "static"
@@ -684,7 +570,7 @@ export type OptPromise<T extends () => any> = (
684
570
  ) => Promise<ReturnType<T>> | ReturnType<T>
685
571
 
686
572
  export function access<T extends string, T2>(t: Record<T, T2>) {
687
- return (key: T) => t[key] as T2
573
+ return (key: T) => t[key]
688
574
  }
689
575
 
690
576
  export function todayAtUTCNoon() {
@@ -736,25 +622,64 @@ export const copy = dual<
736
622
  }
737
623
  >(2, <A>(self: A, f: Partial<A> | ((a: A) => Partial<A>)) => clone(self, { ...self, ...(isFunction(f) ? f(self) : f) }))
738
624
 
739
- type CopyOriginU<U, Ctor extends new(...args: any[]) => any> =
625
+ export type CopyOriginU<U, Ctor extends new(...args: any[]) => any> =
740
626
  & {
741
627
  [K in keyof U & keyof InstanceType<Ctor>]?: U[K]
742
628
  }
743
629
  & {}
744
630
 
745
- type CopyOriginRet<A, U> =
631
+ export type CopyOriginRet<A, U> =
746
632
  & {
747
633
  [K in keyof A | keyof U]: K extends keyof U ? U[K] : A[K & keyof A]
748
634
  }
749
635
  & {}
750
636
 
751
- type CopyOriginSelf<A, U> = Equals<{}, U> extends true
637
+ export type CopyOriginSelf<A, U> = Equals<{}, U> extends true
752
638
  ? Equals<keyof {}, keyof U> extends true ? `updates argument is empty or contains only extra properties`
753
639
  : A
754
640
  : A
755
641
 
642
+ export interface StructuralCopyOrigin<Self extends object> {
643
+ <A extends Self, U extends Partial<Self>>(
644
+ f: (a: A) =>
645
+ & {
646
+ [K in keyof U & keyof Self]?: U[K]
647
+ }
648
+ & {}
649
+ ): (self: CopyOriginSelf<A, U>) => CopyOriginRet<A, U>
650
+ <A extends Self, U extends Partial<Self>>(
651
+ updates:
652
+ & {
653
+ [K in keyof U & keyof Self]?: U[K]
654
+ }
655
+ & {}
656
+ ): (self: CopyOriginSelf<A, U>) => CopyOriginRet<A, U>
657
+ <A extends Self, U extends Partial<Self>>(
658
+ self: CopyOriginSelf<A, U>,
659
+ f: (a: A) =>
660
+ & {
661
+ [K in keyof U & keyof Self]?: U[K]
662
+ }
663
+ & {}
664
+ ): CopyOriginRet<A, U>
665
+ <A extends Self, U extends Partial<Self>>(
666
+ self: CopyOriginSelf<A, U>,
667
+ updates:
668
+ & {
669
+ [K in keyof U & keyof Self]?: U[K]
670
+ }
671
+ & {}
672
+ ): CopyOriginRet<A, U>
673
+ }
674
+
756
675
  // just one input param: the convention is that the ctor takes an object
757
- // containing the properties of the class (I can't put object there as type because of contravariance)
676
+ // containing the properties of the value (I can't put object there as type because of contravariance)
677
+ /**
678
+ * By design this does not return `Self` directly.
679
+ *
680
+ * The return type is computed from `Self` and the update payload so callers can
681
+ * expose an explicit structural return type that remains assignable to `Self`.
682
+ */
758
683
  export const copyOrigin = <Ctor extends new(_: any) => any>(ctor: Ctor) =>
759
684
  dual<
760
685
  {
@@ -883,8 +808,6 @@ export function setMoveElDropUndefined<T>(el: T, newIndex: number) {
883
808
  pipe([...arrInput], arMoveElDropUndefined(el, newIndex), Option.map((ar) => new Set(ar)))
884
809
  }
885
810
 
886
- export { get }
887
-
888
811
  type RemoveNonArray<T> = T extends readonly any[] ? T : never
889
812
  export function isNativeTuple<A>(a: A): a is RemoveNonArray<A> {
890
813
  return Array.isArray(a)
@@ -956,7 +879,7 @@ const genConstructor = (function*() {}).constructor
956
879
  /**
957
880
  * @example
958
881
  * ```ts
959
- * import { Utils } from "effect"
882
+ * import * as Utils from "effect/Utils"
960
883
  *
961
884
  * function* generatorFn() {
962
885
  * yield 1
@@ -970,5 +893,5 @@ const genConstructor = (function*() {}).constructor
970
893
  * @category predicates
971
894
  * @since 3.11.0
972
895
  */
973
- export const isGeneratorFunction = (u: unknown): u is (...args: Array<any>) => Generator<any, any, any> =>
974
- isObject(u) && u.constructor === genConstructor
896
+ export const isGeneratorFunction = (u: unknown): u is (...args: Array<any>) => Generator<any> =>
897
+ isFunction(u) && u.constructor === genConstructor
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.test.d.ts","sourceRoot":"","sources":["../rpc.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AAE7C,qBAAa,iBAAkB,SAAQ,sBAIrC;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIL,qBAAa,KAAM,SAAQ,UAQzB;CAAG"}
1
+ {"version":3,"file":"rpc.test.d.ts","sourceRoot":"","sources":["../rpc.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAErF,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AAE7C,qBAAa,iBAAkB,SAAQ,sBAIrC;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAI0B,KAAK;;;;AAKpC,qBAAa,KAAM,SAAQ,UAQzB;CAAG"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secretURL.test.d.ts","sourceRoot":"","sources":["../secretURL.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"special.test.d.ts","sourceRoot":"","sources":["../special.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWFtLWVycm9yLnR5cGVzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zdHJlYW0tZXJyb3IudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-error.types.d.ts","sourceRoot":"","sources":["../stream-error.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { S } from "effect-app";
2
+ import { makeRpcClient } from "effect-app/client";
3
+ class GeneralError extends S.TaggedError("GeneralError")("GeneralError", {
4
+ message: S.String
5
+ }) {
6
+ }
7
+ class CustomError extends S.TaggedError("CustomError")("CustomError", {
8
+ reason: S.String
9
+ }) {
10
+ }
11
+ const { TaggedRequestFor } = makeRpcClient({ config: {} }, GeneralError);
12
+ const Req = TaggedRequestFor("Test");
13
+ class StreamWithError extends Req.Stream()("StreamWithError", {}, {
14
+ success: S.Number,
15
+ error: CustomError
16
+ }) {
17
+ }
18
+ const _check = true;
19
+ const _check2 = true;
20
+ class StreamNoError extends Req.Stream()("StreamNoError", {}, {
21
+ success: S.Number
22
+ }) {
23
+ }
24
+ const _check3 = true;
25
+ const _check4 = true;
26
+ console.log("ok");
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWFtLWVycm9yLnR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3RyZWFtLWVycm9yLnR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDOUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRWpELE1BQU0sWUFBYSxTQUFRLENBQUMsQ0FBQyxXQUFXLENBQWUsY0FBYyxDQUFDLENBQUMsY0FBYyxFQUFFO0lBQ3JGLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTTtDQUNsQixDQUFDO0NBQUc7QUFFTCxNQUFNLFdBQVksU0FBUSxDQUFDLENBQUMsV0FBVyxDQUFjLGFBQWEsQ0FBQyxDQUFDLGFBQWEsRUFBRTtJQUNqRixNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU07Q0FDakIsQ0FBQztDQUFHO0FBRUwsTUFBTSxFQUFFLGdCQUFnQixFQUFFLEdBQUcsYUFBYSxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQVMsRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFBO0FBQy9FLE1BQU0sR0FBRyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFBO0FBRXBDLE1BQU0sZUFBZ0IsU0FBUSxHQUFHLENBQUMsTUFBTSxFQUFtQixDQUFDLGlCQUFpQixFQUFFLEVBQUUsRUFBRTtJQUNqRixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDakIsS0FBSyxFQUFFLFdBQVc7Q0FDbkIsQ0FBQztDQUFHO0FBR0wsTUFBTSxNQUFNLEdBQXdELElBQUksQ0FBQTtBQUN4RSxNQUFNLE9BQU8sR0FBd0QsSUFBSSxDQUFBO0FBRXpFLE1BQU0sYUFBYyxTQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQWlCLENBQUMsZUFBZSxFQUFFLEVBQUUsRUFBRTtJQUMzRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU07Q0FDbEIsQ0FBQztDQUFHO0FBRUwsTUFBTSxPQUFPLEdBQTJDLElBQUksQ0FBQTtBQUM1RCxNQUFNLE9BQU8sR0FBMkMsSUFBSSxDQUFBO0FBRTVELE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUEifQ==
@@ -1,4 +1,4 @@
1
- import { S } from "effect-app"
1
+ import * as S from "effect-app/Schema"
2
2
  import * as fc from "fast-check"
3
3
  import { urlAlphabet } from "nanoid"
4
4
  import { test } from "vitest"
package/test/rpc.test.ts CHANGED
@@ -1,4 +1,8 @@
1
+ import type * as Effect from "effect/Effect"
2
+ import type * as Option from "effect/Option"
3
+ import { expect, test } from "vitest"
1
4
  import { makeRpcClient, NotLoggedInError, UnauthorizedError } from "../src/client.js"
5
+ import { ForceVoid } from "../src/client/makeClient.js"
2
6
  import { S } from "../src/index.js"
3
7
  import { RpcContextMap } from "../src/rpc.js"
4
8
 
@@ -8,16 +12,52 @@ export class RequestContextMap extends RpcContextMap.makeMap({
8
12
  test: RpcContextMap.make()(S.Never)
9
13
  }) {}
10
14
 
11
- const { TaggedRequest } = makeRpcClient(RequestContextMap)
15
+ const stubMiddleware = {
16
+ requestContextMap: RequestContextMap.config,
17
+ requestContext: undefined as never
18
+ }
19
+ const { TaggedRequestFor } = makeRpcClient(stubMiddleware)
20
+ const TaggedRequest = TaggedRequestFor("Test").Query
12
21
 
13
22
  export class Stats extends TaggedRequest<Stats>()("Stats", {}, {
14
23
  allowedRoles: ["manager"],
15
24
  success: {
16
- usersActive24Hours: S.Number,
17
- usersActiveLastWeek: S.Number,
18
- newUsersLast24Hours: S.Number,
19
- newUsersLastWeek: S.Number
25
+ usersActive24Hours: S.Finite,
26
+ usersActiveLastWeek: S.Finite,
27
+ newUsersLast24Hours: S.Finite,
28
+ newUsersLastWeek: S.Finite
20
29
  }
21
30
  }) {}
22
31
 
23
- declare const _stats: typeof Stats.success.Type
32
+ declare const _stats: typeof Stats.Type
33
+ declare const _statsSuccess: typeof Stats.success.Type
34
+ declare const _statsError: typeof Stats.error.Type
35
+ declare const _statsRequestType: typeof Stats.type
36
+
37
+ test("ForceVoid decodes and encodes as void", () => {
38
+ const statsFromMake = Stats.make({})
39
+ const statsFromMakeOption = Stats.makeOption({})
40
+ const statsFromMakeEffect = Stats.makeEffect({})
41
+
42
+ expect(S.decodeUnknownSync(ForceVoid)(undefined)).toBe(undefined)
43
+ expect(S.is(ForceVoid)(undefined)).toBe(true)
44
+ expect(S.decodeUnknownSync(ForceVoid)("test")).toBe(undefined)
45
+ expect(S.is(ForceVoid)("test")).toBe(true)
46
+ expect(S.encodeUnknownSync(ForceVoid)("test")).toBe(undefined)
47
+ expect(S.encodeUnknownSync(S.toCodecJson(ForceVoid))("test")).toBe(null)
48
+ expectTypeOf<typeof _stats>().toEqualTypeOf<Stats>()
49
+ expectTypeOf<typeof _statsSuccess>().toEqualTypeOf<{
50
+ readonly usersActive24Hours: number
51
+ readonly usersActiveLastWeek: number
52
+ readonly newUsersLast24Hours: number
53
+ readonly newUsersLastWeek: number
54
+ }>()
55
+ // Resource error carries only `config.error` (and optional `generalErrors`); rcm-derived
56
+ // middleware errors no longer leak into `resource.error` — they reach the wire via the
57
+ // middleware tag attached to the rpc group (`rpc.middlewares[*].error` failure-union).
58
+ expectTypeOf<typeof _statsError>().toEqualTypeOf<never>()
59
+ expectTypeOf<typeof _statsRequestType>().toEqualTypeOf<"query">()
60
+ expectTypeOf(statsFromMake).toEqualTypeOf<Stats>()
61
+ expectTypeOf(statsFromMakeOption).toEqualTypeOf<Option.Option<Stats>>()
62
+ expectTypeOf(statsFromMakeEffect).toEqualTypeOf<Effect.Effect<Stats, S.SchemaError>>()
63
+ })