effect-app 4.0.0-beta.17 → 4.0.0-beta.170

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 (207) hide show
  1. package/CHANGELOG.md +683 -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 +369 -47
  31. package/dist/Operations.d.ts.map +1 -1
  32. package/dist/Operations.js +10 -10
  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 +190 -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/SchemaParser.d.ts +5 -0
  45. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  46. package/dist/Schema/SchemaParser.js +6 -0
  47. package/dist/Schema/SpecialJsonSchema.d.ts +33 -0
  48. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  49. package/dist/Schema/SpecialJsonSchema.js +122 -0
  50. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  51. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  52. package/dist/Schema/SpecialOpenApi.js +123 -0
  53. package/dist/Schema/brand.d.ts +7 -2
  54. package/dist/Schema/brand.d.ts.map +1 -1
  55. package/dist/Schema/brand.js +1 -1
  56. package/dist/Schema/email.d.ts +1 -1
  57. package/dist/Schema/email.d.ts.map +1 -1
  58. package/dist/Schema/email.js +7 -4
  59. package/dist/Schema/ext.d.ts +121 -48
  60. package/dist/Schema/ext.d.ts.map +1 -1
  61. package/dist/Schema/ext.js +129 -53
  62. package/dist/Schema/moreStrings.d.ts +111 -11
  63. package/dist/Schema/moreStrings.d.ts.map +1 -1
  64. package/dist/Schema/moreStrings.js +14 -15
  65. package/dist/Schema/numbers.d.ts +127 -15
  66. package/dist/Schema/numbers.d.ts.map +1 -1
  67. package/dist/Schema/numbers.js +10 -12
  68. package/dist/Schema/phoneNumber.d.ts +1 -1
  69. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  70. package/dist/Schema/phoneNumber.js +6 -3
  71. package/dist/Schema/schema.d.ts +1 -1
  72. package/dist/Schema/strings.d.ts +37 -5
  73. package/dist/Schema/strings.d.ts.map +1 -1
  74. package/dist/Schema/strings.js +1 -5
  75. package/dist/Schema.d.ts +102 -56
  76. package/dist/Schema.d.ts.map +1 -1
  77. package/dist/Schema.js +128 -64
  78. package/dist/Set.d.ts +1 -1
  79. package/dist/Set.d.ts.map +1 -1
  80. package/dist/TypeTest.d.ts +1 -1
  81. package/dist/Types.d.ts +1 -1
  82. package/dist/Widen.type.d.ts +1 -1
  83. package/dist/_ext/Array.d.ts +1 -1
  84. package/dist/_ext/Array.d.ts.map +1 -1
  85. package/dist/_ext/date.d.ts +1 -1
  86. package/dist/_ext/misc.d.ts +1 -1
  87. package/dist/_ext/ord.ext.d.ts +1 -1
  88. package/dist/_ext/ord.ext.d.ts.map +1 -1
  89. package/dist/builtin.d.ts +1 -1
  90. package/dist/builtin.d.ts.map +1 -1
  91. package/dist/client/apiClientFactory.d.ts +14 -30
  92. package/dist/client/apiClientFactory.d.ts.map +1 -1
  93. package/dist/client/apiClientFactory.js +18 -19
  94. package/dist/client/clientFor.d.ts +30 -11
  95. package/dist/client/clientFor.d.ts.map +1 -1
  96. package/dist/client/clientFor.js +9 -1
  97. package/dist/client/errors.d.ts +44 -19
  98. package/dist/client/errors.d.ts.map +1 -1
  99. package/dist/client/errors.js +35 -10
  100. package/dist/client/makeClient.d.ts +243 -29
  101. package/dist/client/makeClient.d.ts.map +1 -1
  102. package/dist/client/makeClient.js +53 -23
  103. package/dist/client.d.ts +1 -1
  104. package/dist/faker.d.ts +1 -1
  105. package/dist/faker.d.ts.map +1 -1
  106. package/dist/http/Request.d.ts +2 -2
  107. package/dist/http/Request.d.ts.map +1 -1
  108. package/dist/http/Request.js +5 -5
  109. package/dist/http/internal/lib.d.ts +1 -1
  110. package/dist/http.d.ts +1 -1
  111. package/dist/ids.d.ts +3 -3
  112. package/dist/ids.d.ts.map +1 -1
  113. package/dist/ids.js +3 -2
  114. package/dist/index.d.ts +5 -8
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +6 -8
  117. package/dist/logger.d.ts +1 -1
  118. package/dist/middleware.d.ts +8 -8
  119. package/dist/middleware.d.ts.map +1 -1
  120. package/dist/middleware.js +8 -8
  121. package/dist/rpc/MiddlewareMaker.d.ts +5 -4
  122. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  123. package/dist/rpc/MiddlewareMaker.js +26 -27
  124. package/dist/rpc/RpcContextMap.d.ts +3 -3
  125. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  126. package/dist/rpc/RpcContextMap.js +4 -4
  127. package/dist/rpc/RpcMiddleware.d.ts +5 -4
  128. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  129. package/dist/rpc/RpcMiddleware.js +1 -1
  130. package/dist/rpc.d.ts +1 -2
  131. package/dist/rpc.d.ts.map +1 -1
  132. package/dist/rpc.js +1 -2
  133. package/dist/transform.d.ts +1 -1
  134. package/dist/transform.d.ts.map +1 -1
  135. package/dist/transform.js +3 -3
  136. package/dist/utils/effectify.d.ts +1 -1
  137. package/dist/utils/extend.d.ts +1 -1
  138. package/dist/utils/extend.d.ts.map +1 -1
  139. package/dist/utils/gen.d.ts +2 -2
  140. package/dist/utils/gen.d.ts.map +1 -1
  141. package/dist/utils/logLevel.d.ts +2 -2
  142. package/dist/utils/logLevel.d.ts.map +1 -1
  143. package/dist/utils/logger.d.ts +3 -3
  144. package/dist/utils/logger.d.ts.map +1 -1
  145. package/dist/utils/logger.js +3 -3
  146. package/dist/utils.d.ts +30 -10
  147. package/dist/utils.d.ts.map +1 -1
  148. package/dist/utils.js +10 -4
  149. package/dist/validation/validators.d.ts +1 -1
  150. package/dist/validation/validators.d.ts.map +1 -1
  151. package/dist/validation.d.ts +1 -1
  152. package/dist/validation.d.ts.map +1 -1
  153. package/eslint.config.mjs +2 -2
  154. package/package.json +39 -19
  155. package/src/Config/SecretURL.ts +2 -1
  156. package/src/Config.ts +14 -0
  157. package/src/ConfigProvider.ts +48 -0
  158. package/src/{ServiceMap.ts → Context.ts} +52 -59
  159. package/src/Effect.ts +12 -14
  160. package/src/Layer.ts +5 -4
  161. package/src/Operations.ts +14 -14
  162. package/src/Pure.ts +17 -18
  163. package/src/Schema/Class.ts +279 -62
  164. package/src/Schema/SchemaParser.ts +12 -0
  165. package/src/Schema/SpecialJsonSchema.ts +137 -0
  166. package/src/Schema/SpecialOpenApi.ts +130 -0
  167. package/src/Schema/brand.ts +9 -1
  168. package/src/Schema/email.ts +7 -2
  169. package/src/Schema/ext.ts +217 -87
  170. package/src/Schema/moreStrings.ts +22 -20
  171. package/src/Schema/numbers.ts +14 -16
  172. package/src/Schema/phoneNumber.ts +5 -1
  173. package/src/Schema/strings.ts +4 -8
  174. package/src/Schema.ts +265 -105
  175. package/src/client/apiClientFactory.ts +107 -113
  176. package/src/client/clientFor.ts +45 -12
  177. package/src/client/errors.ts +42 -17
  178. package/src/client/makeClient.ts +319 -63
  179. package/src/http/Request.ts +7 -4
  180. package/src/ids.ts +2 -1
  181. package/src/index.ts +5 -10
  182. package/src/middleware.ts +7 -9
  183. package/src/rpc/MiddlewareMaker.ts +36 -47
  184. package/src/rpc/README.md +2 -2
  185. package/src/rpc/RpcContextMap.ts +6 -5
  186. package/src/rpc/RpcMiddleware.ts +5 -4
  187. package/src/rpc.ts +0 -1
  188. package/src/transform.ts +2 -2
  189. package/src/utils/gen.ts +1 -1
  190. package/src/utils/logger.ts +2 -2
  191. package/src/utils.ts +47 -11
  192. package/test/dist/rpc.test.d.ts.map +1 -1
  193. package/test/dist/secretURL.test.d.ts.map +1 -0
  194. package/test/dist/special.test.d.ts.map +1 -0
  195. package/test/rpc.test.ts +38 -6
  196. package/test/schema.test.ts +591 -17
  197. package/test/secretURL.test.ts +157 -0
  198. package/test/special.test.ts +1023 -0
  199. package/test/utils.test.ts +6 -6
  200. package/tsconfig.base.json +3 -4
  201. package/tsconfig.json +0 -1
  202. package/tsconfig.json.bak +2 -2
  203. package/tsconfig.src.json +29 -29
  204. package/tsconfig.test.json +2 -2
  205. package/dist/ServiceMap.d.ts +0 -44
  206. package/dist/ServiceMap.d.ts.map +0 -1
  207. package/dist/ServiceMap.js +0 -91
@@ -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
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 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
 
package/src/utils.ts CHANGED
@@ -269,7 +269,7 @@ export type EnforceNonEmptyRecord<R> = keyof R extends never ? never : R
269
269
  export function intersect<AS extends unknown[] & { 0: unknown }>(
270
270
  ...as: AS
271
271
  ): UnionToIntersection<{ [k in keyof AS]: AS[k] }[number]> {
272
- return as.reduce((a: any, b: any) => ({ ...a, ...b })) as any
272
+ return as.reduce((a: any, b: any) => Object.assign(a, b), {}) as any
273
273
  }
274
274
 
275
275
  export type IsEqualTo<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
@@ -280,8 +280,7 @@ export type IsEqualTo<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
280
280
  export const unifyIndex = Symbol()
281
281
  export type unifyIndex = typeof unifyIndex
282
282
 
283
- // @ts-expect-error abc
284
- export interface UnifiableIndexed<X> {}
283
+ export interface UnifiableIndexed<_X> {}
285
284
  export type UnifiableIndexedURI = keyof UnifiableIndexed<any>
286
285
 
287
286
  export interface Unifiable<X> {
@@ -313,9 +312,7 @@ function decorateNew(
313
312
  if (out.descriptor) {
314
313
  out.descriptor = Object.assign({}, out.descriptor)
315
314
  }
316
- const actualDesc: PropertyDescriptor = <any> (
317
- out.descriptor || /* istanbul ignore next */ out
318
- )
315
+ const actualDesc: PropertyDescriptor = out.descriptor || /* istanbul ignore next */ out
319
316
 
320
317
  const originalMethod = validateAndExtractMethodFromDescriptor(actualDesc)
321
318
  const isStatic = inp.placement === "static"
@@ -684,7 +681,7 @@ export type OptPromise<T extends () => any> = (
684
681
  ) => Promise<ReturnType<T>> | ReturnType<T>
685
682
 
686
683
  export function access<T extends string, T2>(t: Record<T, T2>) {
687
- return (key: T) => t[key] as T2
684
+ return (key: T) => t[key]
688
685
  }
689
686
 
690
687
  export function todayAtUTCNoon() {
@@ -736,25 +733,64 @@ export const copy = dual<
736
733
  }
737
734
  >(2, <A>(self: A, f: Partial<A> | ((a: A) => Partial<A>)) => clone(self, { ...self, ...(isFunction(f) ? f(self) : f) }))
738
735
 
739
- type CopyOriginU<U, Ctor extends new(...args: any[]) => any> =
736
+ export type CopyOriginU<U, Ctor extends new(...args: any[]) => any> =
740
737
  & {
741
738
  [K in keyof U & keyof InstanceType<Ctor>]?: U[K]
742
739
  }
743
740
  & {}
744
741
 
745
- type CopyOriginRet<A, U> =
742
+ export type CopyOriginRet<A, U> =
746
743
  & {
747
744
  [K in keyof A | keyof U]: K extends keyof U ? U[K] : A[K & keyof A]
748
745
  }
749
746
  & {}
750
747
 
751
- type CopyOriginSelf<A, U> = Equals<{}, U> extends true
748
+ export type CopyOriginSelf<A, U> = Equals<{}, U> extends true
752
749
  ? Equals<keyof {}, keyof U> extends true ? `updates argument is empty or contains only extra properties`
753
750
  : A
754
751
  : A
755
752
 
753
+ export interface StructuralCopyOrigin<Self extends object> {
754
+ <A extends Self, U extends Partial<Self>>(
755
+ f: (a: A) =>
756
+ & {
757
+ [K in keyof U & keyof Self]?: U[K]
758
+ }
759
+ & {}
760
+ ): (self: CopyOriginSelf<A, U>) => CopyOriginRet<A, U>
761
+ <A extends Self, U extends Partial<Self>>(
762
+ updates:
763
+ & {
764
+ [K in keyof U & keyof Self]?: U[K]
765
+ }
766
+ & {}
767
+ ): (self: CopyOriginSelf<A, U>) => CopyOriginRet<A, U>
768
+ <A extends Self, U extends Partial<Self>>(
769
+ self: CopyOriginSelf<A, U>,
770
+ f: (a: A) =>
771
+ & {
772
+ [K in keyof U & keyof Self]?: U[K]
773
+ }
774
+ & {}
775
+ ): CopyOriginRet<A, U>
776
+ <A extends Self, U extends Partial<Self>>(
777
+ self: CopyOriginSelf<A, U>,
778
+ updates:
779
+ & {
780
+ [K in keyof U & keyof Self]?: U[K]
781
+ }
782
+ & {}
783
+ ): CopyOriginRet<A, U>
784
+ }
785
+
756
786
  // 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)
787
+ // containing the properties of the value (I can't put object there as type because of contravariance)
788
+ /**
789
+ * By design this does not return `Self` directly.
790
+ *
791
+ * The return type is computed from `Self` and the update payload so callers can
792
+ * expose an explicit structural return type that remains assignable to `Self`.
793
+ */
758
794
  export const copyOrigin = <Ctor extends new(_: any) => any>(ctor: Ctor) =>
759
795
  dual<
760
796
  {
@@ -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":"AAEA,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKL,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":""}
package/test/rpc.test.ts CHANGED
@@ -1,4 +1,7 @@
1
+ import { type Effect, type Option } from "effect"
2
+ import { expect, test } from "vitest"
1
3
  import { makeRpcClient, NotLoggedInError, UnauthorizedError } from "../src/client.js"
4
+ import { ForceVoid } from "../src/client/makeClient.js"
2
5
  import { S } from "../src/index.js"
3
6
  import { RpcContextMap } from "../src/rpc.js"
4
7
 
@@ -8,16 +11,45 @@ export class RequestContextMap extends RpcContextMap.makeMap({
8
11
  test: RpcContextMap.make()(S.Never)
9
12
  }) {}
10
13
 
11
- const { TaggedRequest } = makeRpcClient(RequestContextMap)
14
+ const { TaggedRequestFor } = makeRpcClient(RequestContextMap)
15
+ const TaggedRequest = TaggedRequestFor("Test").Query
12
16
 
13
17
  export class Stats extends TaggedRequest<Stats>()("Stats", {}, {
14
18
  allowedRoles: ["manager"],
15
19
  success: {
16
- usersActive24Hours: S.Number,
17
- usersActiveLastWeek: S.Number,
18
- newUsersLast24Hours: S.Number,
19
- newUsersLastWeek: S.Number
20
+ usersActive24Hours: S.Finite,
21
+ usersActiveLastWeek: S.Finite,
22
+ newUsersLast24Hours: S.Finite,
23
+ newUsersLastWeek: S.Finite
20
24
  }
21
25
  }) {}
22
26
 
23
- declare const _stats: typeof Stats.success.Type
27
+ declare const _stats: typeof Stats.Type
28
+ declare const _statsSuccess: typeof Stats.success.Type
29
+ declare const _statsError: typeof Stats.error.Type
30
+ declare const _statsRequestType: typeof Stats.type
31
+
32
+ test("ForceVoid decodes and encodes as void", () => {
33
+ const statsFromMake = Stats.make({})
34
+ const statsFromMakeOption = Stats.makeOption({})
35
+ const statsFromMakeEffect = Stats.makeEffect({})
36
+
37
+ expect(S.decodeUnknownSync(ForceVoid)(undefined)).toBe(undefined)
38
+ expect(S.is(ForceVoid)(undefined)).toBe(true)
39
+ expect(S.decodeUnknownSync(ForceVoid)("test")).toBe(undefined)
40
+ expect(S.is(ForceVoid)("test")).toBe(true)
41
+ expect(S.encodeUnknownSync(ForceVoid)("test")).toBe(undefined)
42
+ expect(S.encodeUnknownSync(S.toCodecJson(ForceVoid))("test")).toBe(null)
43
+ expectTypeOf<typeof _stats>().toEqualTypeOf<Stats>()
44
+ expectTypeOf<typeof _statsSuccess>().toEqualTypeOf<{
45
+ readonly usersActive24Hours: number
46
+ readonly usersActiveLastWeek: number
47
+ readonly newUsersLast24Hours: number
48
+ readonly newUsersLastWeek: number
49
+ }>()
50
+ expectTypeOf<typeof _statsError>().toEqualTypeOf<NotLoggedInError | UnauthorizedError>()
51
+ expectTypeOf<typeof _statsRequestType>().toEqualTypeOf<"query">()
52
+ expectTypeOf(statsFromMake).toEqualTypeOf<Stats>()
53
+ expectTypeOf(statsFromMakeOption).toEqualTypeOf<Option.Option<Stats>>()
54
+ expectTypeOf(statsFromMakeEffect).toEqualTypeOf<Effect.Effect<Stats, S.SchemaError>>()
55
+ })