@effect-app/infra 2.92.3 → 2.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/MainFiberSet.d.ts +1 -1
  3. package/dist/Operations.d.ts +1 -1
  4. package/dist/QueueMaker/sbqueue.d.ts +5 -6
  5. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  6. package/dist/QueueMaker/sbqueue.js +18 -22
  7. package/dist/RequestFiberSet.d.ts +1 -1
  8. package/dist/Store/service.d.ts +1 -1
  9. package/dist/adapters/ServiceBus.d.ts +57 -17
  10. package/dist/adapters/ServiceBus.d.ts.map +1 -1
  11. package/dist/adapters/ServiceBus.js +75 -61
  12. package/dist/adapters/memQueue.d.ts +1 -1
  13. package/dist/api/routing/middleware/middleware-api.d.ts +2 -1
  14. package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
  15. package/dist/api/routing/middleware/middleware-api.js +1 -1
  16. package/dist/api/routing/middleware.d.ts +0 -1
  17. package/dist/api/routing/middleware.d.ts.map +1 -1
  18. package/dist/api/routing/middleware.js +1 -2
  19. package/dist/api/routing.d.ts +8 -9
  20. package/dist/api/routing.d.ts.map +1 -1
  21. package/dist/api/routing.js +18 -10
  22. package/package.json +2 -6
  23. package/src/QueueMaker/sbqueue.ts +33 -46
  24. package/src/adapters/ServiceBus.ts +141 -93
  25. package/src/api/routing/middleware/middleware-api.ts +2 -1
  26. package/src/api/routing/middleware.ts +0 -1
  27. package/src/api/routing.ts +46 -233
  28. package/test/controller.test.ts +12 -8
  29. package/test/dist/controller/test2.test.d.ts.map +1 -0
  30. package/test/dist/controller.legacy2.test.d.ts.map +1 -0
  31. package/test/dist/controller.legacy3.test.d.ts.map +1 -0
  32. package/test/dist/controller.test copy.js +129 -0
  33. package/test/dist/controller.test.d.ts.map +1 -1
  34. package/test/dist/controller5.test.d.ts.map +1 -0
  35. package/test/dist/controller6.test.d.ts.map +1 -0
  36. package/test/dist/controller7.test.d.ts.map +1 -0
  37. package/test/dist/dynamicContext.test.d.ts.map +1 -0
  38. package/test/dist/filterApi.test.d.ts.map +1 -0
  39. package/test/dist/fixtures.d.ts +3 -3
  40. package/test/dist/middleware-api.test.d.ts.map +1 -0
  41. package/test/dist/requires.d.ts +21 -0
  42. package/test/dist/requires.d.ts.map +1 -0
  43. package/test/dist/requires.js +27 -0
  44. package/vitest.config.ts.timestamp-1711724061890-6ecedb0a07fdd.mjs +0 -0
  45. package/vitest.config.ts.timestamp-1711743489537-da8d9e5f66c9f.mjs +0 -0
  46. package/vitest.config.ts.timestamp-1711744615239-dcf257a844e01.mjs +37 -0
  47. package/dist/api/routing/middleware/dynamic-middleware.d.ts +0 -2
  48. package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +0 -1
  49. package/dist/api/routing/middleware/dynamic-middleware.js +0 -2
  50. /package/{src/api/routing/middleware/dynamic-middleware.ts → vitest.config.ts.timestamp-1711656440838-19c636fe320df.mjs} +0 -0
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
2
- import { type OperationOptionsBase, type ProcessErrorArgs, ServiceBusClient, type ServiceBusMessage, type ServiceBusMessageBatch, type ServiceBusReceivedMessage, type ServiceBusReceiver, type ServiceBusSender } from "@azure/service-bus"
2
+ import { type OperationOptionsBase, type ProcessErrorArgs, ServiceBusClient, type ServiceBusMessage, type ServiceBusMessageBatch, type ServiceBusReceivedMessage, type ServiceBusReceiver } from "@azure/service-bus"
3
3
  import { Cause, Context, Effect, Exit, FiberSet, Layer, type Scope } from "effect-app"
4
4
  import { InfraLogger } from "../logger.js"
5
5
 
@@ -18,12 +18,13 @@ function makeClient(url: string) {
18
18
  )
19
19
  }
20
20
 
21
- const Client = Context.GenericTag<ServiceBusClient>("@services/Client")
22
- export const LiveServiceBusClient = (url: string) => Layer.scoped(Client)(makeClient(url))
21
+ export class ServiceBusClientTag extends Context.Tag("@services/Client")<ServiceBusClientTag, ServiceBusClient>() {
22
+ static readonly layer = (url: string) => Layer.scoped(this, makeClient(url))
23
+ }
23
24
 
24
- function makeSender(queueName: string) {
25
+ function makeSender_(queueName: string) {
25
26
  return Effect.gen(function*() {
26
- const serviceBusClient = yield* Client
27
+ const serviceBusClient = yield* ServiceBusClientTag
27
28
 
28
29
  return yield* Effect.acquireRelease(
29
30
  Effect.sync(() => serviceBusClient.createSender(queueName)).pipe(
@@ -33,112 +34,159 @@ function makeSender(queueName: string) {
33
34
  )
34
35
  })
35
36
  }
36
- export const Sender = Context.GenericTag<ServiceBusSender>("@services/Sender")
37
37
 
38
- export function LiveSender(queueName: string) {
39
- return Layer
40
- .scoped(Sender, makeSender(queueName))
38
+ const makeSender = (name: string) =>
39
+ Effect.gen(function*() {
40
+ const sender = yield* makeSender_(name)
41
+ const sendMessages = Effect.fnUntraced(function*(
42
+ messages: ServiceBusMessage | ServiceBusMessage[] | ServiceBusMessageBatch,
43
+ options?: Omit<OperationOptionsBase, "abortSignal">
44
+ ) {
45
+ return yield* Effect.promise((abortSignal) => sender.sendMessages(messages, { ...options, abortSignal }))
46
+ })
47
+
48
+ return { name, sendMessages }
49
+ })
50
+
51
+ export class Sender extends Context.TagId("Sender")<Sender, {
52
+ name: string
53
+ sendMessages: (
54
+ messages: ServiceBusMessage | ServiceBusMessage[] | ServiceBusMessageBatch,
55
+ options?: Omit<OperationOptionsBase, "abortSignal"> | undefined
56
+ ) => Effect.Effect<void, never, never>
57
+ }>() {
58
+ static readonly layer = (name: string) => this.toLayerScoped(makeSender(name))
41
59
  }
42
60
 
43
- function makeReceiver(queueName: string, waitTillEmpty: Effect<void>, sessionId?: string) {
44
- return Effect.gen(function*() {
45
- const serviceBusClient = yield* Client
61
+ export const SenderTag = <Id>() => <Key extends string>(queueName: Key) => {
62
+ const tag = Context.Tag(`ServiceBus.Sender.${queueName}`)<
63
+ Id,
64
+ Sender
65
+ >()
46
66
 
47
- return yield* Effect.acquireRelease(
48
- (sessionId
49
- ? Effect.promise(() => serviceBusClient.acceptSession(queueName, sessionId))
50
- : Effect.sync(() => serviceBusClient.createReceiver(queueName)))
51
- .pipe(withSpanAndLog(`ServiceBus.receiver.create ${queueName}.${sessionId}`)),
52
- (r) =>
53
- waitTillEmpty.pipe(
54
- withSpanAndLog(`ServiceBus.receiver.waitTillEmpty ${queueName}.${sessionId}`),
55
- Effect.andThen(
56
- Effect.promise(() => r.close()).pipe(withSpanAndLog(`ServiceBus.receiver.close ${queueName}.${sessionId}`))
57
- ),
58
- withSpanAndLog(`ServiceBus.receiver.release ${queueName}.${sessionId}`)
59
- )
67
+ return Object.assign(tag, {
68
+ layer: Layer.scoped(
69
+ tag,
70
+ makeSender(queueName).pipe(Effect.map((_) => Sender.of(_)))
60
71
  )
61
72
  })
62
73
  }
63
74
 
64
- export class ServiceBusReceiverFactory extends Context.TagId(
65
- "ServiceBusReceiverFactory"
66
- )<ServiceBusReceiverFactory, {
75
+ const makeReceiver = (name: string) =>
76
+ Effect.gen(function*() {
77
+ const serviceBusClient = yield* ServiceBusClientTag
78
+
79
+ const makeReceiver = Effect.fnUntraced(
80
+ function*(queueName: string, waitTillEmpty: Effect<void>, sessionId?: string) {
81
+ return yield* Effect.acquireRelease(
82
+ (sessionId
83
+ ? Effect.promise(() => serviceBusClient.acceptSession(queueName, sessionId))
84
+ : Effect.sync(() => serviceBusClient.createReceiver(queueName)))
85
+ .pipe(withSpanAndLog(`ServiceBus.receiver.create ${queueName}.${sessionId}`)),
86
+ (r) =>
87
+ waitTillEmpty.pipe(
88
+ withSpanAndLog(`ServiceBus.receiver.waitTillEmpty ${queueName}.${sessionId}`),
89
+ Effect.andThen(
90
+ Effect.promise(() => r.close()).pipe(
91
+ withSpanAndLog(`ServiceBus.receiver.close ${queueName}.${sessionId}`)
92
+ )
93
+ ),
94
+ withSpanAndLog(`ServiceBus.receiver.release ${queueName}.${sessionId}`)
95
+ )
96
+ )
97
+ }
98
+ )
99
+
100
+ const make = (waitTillEmpty: Effect<void>) => makeReceiver(name, waitTillEmpty)
101
+
102
+ const makeSession = (sessionId: string, waitTillEmpty: Effect<void>) => makeReceiver(name, waitTillEmpty, sessionId)
103
+
104
+ return {
105
+ name,
106
+ make,
107
+ makeSession,
108
+ subscribe: Effect.fnUntraced(function*<RMsg, RErr>(hndlr: MessageHandlers<RMsg, RErr>, sessionId?: string) {
109
+ const fs = yield* FiberSet.make()
110
+ const fr = yield* FiberSet.runtime(fs)<RMsg | RErr>()
111
+ const wait = Effect
112
+ .gen(function*() {
113
+ if ((yield* FiberSet.size(fs)) > 0) {
114
+ yield* InfraLogger.logDebug("Waiting ServiceBusFiberSet to be empty: " + (yield* FiberSet.size(fs)))
115
+ }
116
+ while ((yield* FiberSet.size(fs)) > 0) yield* Effect.sleep("250 millis")
117
+ })
118
+ const r = yield* sessionId
119
+ ? makeSession(
120
+ sessionId,
121
+ wait
122
+ )
123
+ : make(wait)
124
+
125
+ const runEffect = <E>(effect: Effect<void, E, RMsg | RErr>) =>
126
+ new Promise<void>((resolve, reject) =>
127
+ fr(effect)
128
+ .addObserver((exit) => {
129
+ if (Exit.isSuccess(exit)) {
130
+ resolve(exit.value)
131
+ } else {
132
+ // disable @typescript-eslint/prefer-promise-reject-errors
133
+ reject(Cause.pretty(exit.cause, { renderErrorCause: true }))
134
+ }
135
+ })
136
+ )
137
+ yield* Effect.acquireRelease(
138
+ Effect
139
+ .sync(() =>
140
+ r
141
+ .subscribe({
142
+ processError: (err) =>
143
+ runEffect(
144
+ hndlr
145
+ .processError(err)
146
+ .pipe(
147
+ Effect.catchAllCause((cause) => Effect.logError(`ServiceBus Error ${sessionId}`, cause))
148
+ )
149
+ ),
150
+ processMessage: (msg) => runEffect(hndlr.processMessage(msg))
151
+ // DO NOT CATCH ERRORS here as they should return to the queue!
152
+ })
153
+ )
154
+ .pipe(withSpanAndLog(`ServiceBus.subscription.create ${sessionId}`)),
155
+ (subscription) =>
156
+ Effect.promise(() => subscription.close()).pipe(
157
+ withSpanAndLog(`ServiceBus.subscription.close ${sessionId}`)
158
+ )
159
+ )
160
+ })
161
+ }
162
+ })
163
+
164
+ export class Receiver extends Context.TagId("Receiver")<Receiver, {
165
+ name: string
67
166
  make: (waitTillEmpty: Effect<void>) => Effect<ServiceBusReceiver, never, Scope>
68
167
  makeSession: (sessionId: string, waitTillEmpty: Effect<void>) => Effect<ServiceBusReceiver, never, Scope>
168
+ subscribe<RMsg, RErr>(
169
+ hndlr: MessageHandlers<RMsg, RErr>,
170
+ sessionId?: string
171
+ ): Effect.Effect<void, never, Scope.Scope | RMsg | RErr>
69
172
  }>() {
70
- static readonly Live = (queueName: string) =>
71
- this.toLayer(Client.pipe(Effect.andThen((cl) => ({
72
- make: (waitTillEmpty: Effect<void>) =>
73
- makeReceiver(queueName, waitTillEmpty).pipe(Effect.provideService(Client, cl)),
74
- makeSession: (sessionId: string, waitTillEmpty: Effect<void>) =>
75
- makeReceiver(queueName, waitTillEmpty, sessionId).pipe(Effect.provideService(Client, cl))
76
- }))))
173
+ static readonly layer = (name: string) => this.toLayer(makeReceiver(name))
77
174
  }
78
175
 
79
- export function sendMessages(
80
- messages: ServiceBusMessage | ServiceBusMessage[] | ServiceBusMessageBatch,
81
- options?: OperationOptionsBase
82
- ) {
83
- return Effect.gen(function*() {
84
- const s = yield* Sender
85
- return yield* Effect.promise(() => s.sendMessages(messages, options))
86
- })
87
- }
176
+ export const ReceiverTag = <Id>() => <Key extends string>(queueName: Key) => {
177
+ const tag = Context.Tag(`ServiceBus.Receiver.${queueName}`)<Id, Receiver>()
88
178
 
89
- export function subscribe<RMsg, RErr>(hndlr: MessageHandlers<RMsg, RErr>, sessionId?: string) {
90
- return Effect.gen(function*() {
91
- const rf = yield* ServiceBusReceiverFactory
92
- const fs = yield* FiberSet.make()
93
- const fr = yield* FiberSet.runtime(fs)<RMsg | RErr>()
94
- const wait = Effect
95
- .gen(function*() {
96
- if ((yield* FiberSet.size(fs)) > 0) {
97
- yield* InfraLogger.logDebug("Waiting ServiceBusFiberSet to be empty: " + (yield* FiberSet.size(fs)))
98
- }
99
- while ((yield* FiberSet.size(fs)) > 0) yield* Effect.sleep("250 millis")
100
- })
101
- const r = yield* sessionId
102
- ? rf.makeSession(
103
- sessionId,
104
- wait
105
- )
106
- : rf.make(wait)
107
-
108
- const runEffect = <E>(effect: Effect<void, E, RMsg | RErr>) =>
109
- new Promise<void>((resolve, reject) =>
110
- fr(effect)
111
- .addObserver((exit) => {
112
- if (Exit.isSuccess(exit)) {
113
- resolve(exit.value)
114
- } else {
115
- // disable @typescript-eslint/prefer-promise-reject-errors
116
- reject(Cause.pretty(exit.cause, { renderErrorCause: true }))
117
- }
118
- })
119
- )
120
- yield* Effect.acquireRelease(
121
- Effect
122
- .sync(() =>
123
- r
124
- .subscribe({
125
- processError: (err) =>
126
- runEffect(
127
- hndlr
128
- .processError(err)
129
- .pipe(Effect.catchAllCause((cause) => Effect.logError(`ServiceBus Error ${sessionId}`, cause)))
130
- ),
131
- processMessage: (msg) => runEffect(hndlr.processMessage(msg))
132
- // DO NOT CATCH ERRORS here as they should return to the queue!
133
- })
134
- )
135
- .pipe(withSpanAndLog(`ServiceBus.subscription.create ${sessionId}`)),
136
- (subscription) =>
137
- Effect.promise(() => subscription.close()).pipe(withSpanAndLog(`ServiceBus.subscription.close ${sessionId}`))
179
+ return Object.assign(tag, {
180
+ layer: Layer.effect(
181
+ tag,
182
+ makeReceiver(queueName).pipe(Effect.map((_) => Receiver.of(_)))
138
183
  )
139
184
  })
140
185
  }
141
186
 
187
+ export const SenderReceiver = (queue: string, queueDrain?: string) =>
188
+ Layer.mergeAll(Sender.layer(queue), Receiver.layer(queueDrain ?? queue))
189
+
142
190
  export interface MessageHandlers<RMsg, RErr> {
143
191
  /**
144
192
  * Handler that processes messages from service bus.
@@ -2,6 +2,7 @@
2
2
  import { type AnyWithProps } from "@effect/rpc/Rpc"
3
3
  import { Context, type Effect, type NonEmptyArray, type NonEmptyReadonlyArray, S } from "effect-app"
4
4
  import { type GetContextConfig, type RPCContextMap } from "effect-app/client"
5
+ import { type TypeTestId } from "../../routing.js"
5
6
  import { type MiddlewareMaker, middlewareMaker } from "./generic-middleware.js"
6
7
  import { type AnyDynamic, type RpcDynamic, Tag, type TagClassAny } from "./RpcMiddleware.js"
7
8
 
@@ -103,7 +104,7 @@ export interface BuildingMiddleware<
103
104
  : never
104
105
 
105
106
  // helps debugging what are the missing requirements (type only)
106
- missing: {
107
+ readonly [TypeTestId]: {
107
108
  missingDynamicMiddlewares: Exclude<keyof RequestContextMap, Provided>
108
109
  missingContext: MiddlewareR
109
110
  }
@@ -1,5 +1,4 @@
1
1
  // codegen:start {preset: barrel, include: ./middleware/*.ts, nodir: false }
2
- export * from "./middleware/dynamic-middleware.js"
3
2
  export * from "./middleware/generic-middleware.js"
4
3
  export * from "./middleware/middleware-api.js"
5
4
  export * from "./middleware/middleware.js"
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
3
  /* eslint-disable @typescript-eslint/no-empty-object-type */
4
4
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
- import { Rpc, RpcGroup, RpcServer } from "@effect/rpc"
5
+ import { Rpc, RpcGroup, type RpcSerialization, RpcServer } from "@effect/rpc"
6
6
  import { type Array, Effect, Layer, type NonEmptyReadonlyArray, Predicate, S, Schema, type Scope } from "effect-app"
7
7
  import type { GetEffectContext, GetEffectError, RPCContextMap } from "effect-app/client/req"
8
8
  import { type HttpHeaders, HttpRouter } from "effect-app/http"
@@ -15,6 +15,14 @@ import { DevMode, type RouterMiddleware } from "./routing/middleware.js"
15
15
 
16
16
  export * from "./routing/middleware.js"
17
17
 
18
+ // Nice way to underline types that are only there for type testing, not for production use
19
+ // sadly with unique symbols we get weird issues in app projects.
20
+ // api/src/X/PackList.Controllers.ts:21:1 - error TS4082: Default export of the module has or is using private name 'TypeTestId'
21
+ // export const TypeTestId: unique symbol = Symbol.for("@effect/infra/type-test")
22
+ // export type TypeTestId = typeof TypeTestId
23
+ export const TypeTestId = "@effect-app/infra/type-test" as const
24
+ export type TypeTestId = typeof TypeTestId
25
+
18
26
  // it's the result of extending S.Req setting success, config
19
27
  // it's a schema plus some metadata
20
28
  export type AnyRequestModule = S.Schema.Any & {
@@ -91,11 +99,6 @@ type FilterRequestModules<T> = {
91
99
  [K in keyof T as T[K] extends AnyRequestModule ? K : never]: T[K]
92
100
  }
93
101
 
94
- export const RouterSymbol = Symbol()
95
- export interface RouterShape<Resource> {
96
- [RouterSymbol]: Resource
97
- }
98
-
99
102
  type RPCRouteR<
100
103
  T extends [any, (req: any, headers: HttpHeaders.Headers) => Effect<any, any, any>]
101
104
  > = T extends [
@@ -352,7 +355,12 @@ export const makeRouter = <
352
355
  match: any
353
356
  ) => Effect<THandlers, MakeE, MakeR> | Generator<YieldWrap<Effect<any, MakeE, MakeR>>, THandlers, any>
354
357
  ) => {
355
- type Router = RouterShape<Resource>
358
+ const dependenciesL = Layer.mergeAll(...dependencies as any) as Layer.Layer<
359
+ LayerUtils.GetLayersSuccess<MakeDependencies>,
360
+ LayerUtils.GetLayersError<MakeDependencies>,
361
+ LayerUtils.GetLayersContext<MakeDependencies>
362
+ >
363
+
356
364
  const layer = Effect
357
365
  .gen(function*() {
358
366
  const finalMake = ((make as any)[Symbol.toStringTag] === "GeneratorFunction"
@@ -410,28 +418,29 @@ export const makeRouter = <
410
418
  const rpcs = RpcGroup
411
419
  .make(
412
420
  ...typedValuesOf(mapped).map(([resource]) => {
413
- return Rpc.fromTaggedRequest(resource).annotate(middleware.requestContext, resource.config ?? {})
421
+ return Rpc
422
+ .fromTaggedRequest(resource)
423
+ .annotate(middleware.requestContext, resource.config ?? {})
414
424
  })
415
425
  )
416
426
  .prefix(`${meta.moduleName}.`)
417
427
  .middleware(middleware as any)
418
- const rpcLayer = rpcs.toLayer(Effect.gen(function*() {
419
- return typedValuesOf(mapped).reduce((acc, [resource, handler]) => {
420
- acc[`${meta.moduleName}.${resource._tag}`] = handler
421
- return acc
422
- }, {} as Record<string, any>) as any // TODO
423
- })) as unknown as Layer<
424
- { [K in keyof RequestModules]: Rpc.Handler<K> },
425
- | Layer.Error<typeof middleware.Default>
426
- | LayerUtils.GetLayersError<MakeDependencies>,
427
- | RPCRouteR<typeof mapped[keyof typeof mapped]>
428
- | Layer.Context<typeof middleware.Default>
429
- | LayerUtils.GetLayersContext<MakeDependencies>
430
- >
428
+
429
+ const rpc = rpcs
430
+ .toLayer(Effect.gen(function*() {
431
+ return typedValuesOf(mapped).reduce((acc, [resource, handler]) => {
432
+ acc[`${meta.moduleName}.${resource._tag}`] = handler
433
+ return acc
434
+ }, {} as Record<string, any>) as any // TODO
435
+ })) as unknown as Layer<
436
+ { [K in keyof RequestModules]: Rpc.Handler<K> },
437
+ MakeE,
438
+ RPCRouteR<typeof mapped[keyof typeof mapped]>
439
+ >
431
440
 
432
441
  return RpcServer
433
442
  .layer(rpcs, { spanPrefix: "RpcServer." + meta.moduleName })
434
- .pipe(Layer.provide(rpcLayer))
443
+ .pipe(Layer.provide(rpc))
435
444
  .pipe(
436
445
  Layer.provideMerge(
437
446
  RpcServer.layerProtocolHttp(
@@ -442,24 +451,13 @@ export const makeRouter = <
442
451
  })
443
452
  .pipe(Layer.unwrapEffect)
444
453
 
445
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
446
- const routes = (
447
- layer.pipe(
448
- Layer.provide([
449
- ...dependencies ?? [],
450
- middleware.Default
451
- ] as any) as any,
452
- Layer.provide(Layer.succeed(DevMode, devMode))
453
- )
454
- ) as (Layer.Layer<
455
- Router,
456
- | LayerUtils.GetLayersError<MakeDependencies>
457
- | MakeE
458
- | Layer.Error<typeof middleware.Default>,
459
- | LayerUtils.GetLayersContext<MakeDependencies>
460
- | Layer.Context<typeof middleware.Default>
461
- | Exclude<MakeR, LayerUtils.GetLayersSuccess<MakeDependencies>>
462
- >)
454
+ const routes = layer.pipe(
455
+ Layer.provide([
456
+ dependenciesL,
457
+ middleware.Default
458
+ ]),
459
+ Layer.provide(Layer.succeed(DevMode, devMode))
460
+ )
463
461
 
464
462
  // Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
465
463
 
@@ -494,7 +492,7 @@ export const makeRouter = <
494
492
  moduleName: ModuleName
495
493
 
496
494
  routes: Layer.Layer<
497
- RouterShape<Resource>,
495
+ never,
498
496
  | MakeErrors<Make>
499
497
  | Service.MakeDepsE<Make>
500
498
  | Layer.Error<typeof middleware.Default>,
@@ -504,169 +502,12 @@ export const makeRouter = <
504
502
  MakeContext<Make>,
505
503
  MakeDepsOut<Make>
506
504
  >
505
+ | RpcSerialization.RpcSerialization
507
506
  >
508
507
 
509
508
  // just for type testing purposes
510
- make: Make
509
+ [TypeTestId]: Make
511
510
  }
512
- // <
513
- // const Make extends {
514
- // dependencies?: Array<Layer.Layer.Any>
515
- // effect: (match: typeof router3) => Effect<
516
- // { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> },
517
- // any,
518
- // any
519
- // >
520
- // /** @deprecated */
521
- // readonly ಠ_ಠ: never
522
- // }
523
- // >(
524
- // make: Make
525
- // ): {
526
- // moduleName: ModuleName
527
-
528
- // routes: Layer.Layer<
529
- // RouterShape<Resource>,
530
- // | MakeErrors<Make>
531
- // | Service.MakeDepsE<Make>
532
- // | Layer.Error<typeof middleware.Default>,
533
- // | Service.MakeDepsIn<Make>
534
- // | Layer.Context<typeof middleware.Default>
535
- // | Exclude<
536
- // MakeContext<Make>,
537
- // MakeDepsOut<Make>
538
- // >
539
- // >
540
-
541
- // // just for type testing purposes
542
- // make: Make
543
- // }
544
- // <
545
- // const Make extends {
546
- // dependencies?: Array<Layer.Layer.Any>
547
- // effect: (match: typeof router3) => Effect<
548
- // { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> },
549
- // any,
550
- // any
551
- // >
552
- // /** @deprecated */
553
- // readonly ಠ_ಠ: never
554
- // }
555
- // >(
556
- // make: Make
557
- // ): {
558
- // moduleName: ModuleName
559
-
560
- // routes: Layer.Layer<
561
- // RouterShape<Resource>,
562
- // | MakeErrors<Make>
563
- // | Service.MakeDepsE<Make>
564
- // | Layer.Error<typeof middleware.Default>,
565
- // | Service.MakeDepsIn<Make>
566
- // | Layer.Context<typeof middleware.Default>
567
- // | Exclude<
568
- // MakeContext<Make>,
569
- // MakeDepsOut<Make>
570
- // >
571
- // >
572
-
573
- // // just for type testing purposes
574
- // make: Make
575
- // }
576
- // <
577
- // const Make extends {
578
- // dependencies?: Array<Layer.Layer.Any>
579
- // effect: (match: typeof router3) => Effect<
580
- // { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> },
581
- // any,
582
- // any
583
- // >
584
- // /** @deprecated */
585
- // readonly ಠ_ಠ: never
586
- // }
587
- // >(
588
- // make: Make
589
- // ): {
590
- // moduleName: ModuleName
591
-
592
- // routes: Layer.Layer<
593
- // RouterShape<Resource>,
594
- // | MakeErrors<Make>
595
- // | Service.MakeDepsE<Make>
596
- // | Layer.Error<typeof middleware.Default>,
597
- // | Service.MakeDepsIn<Make>
598
- // | Layer.Context<typeof middleware.Default>
599
- // | Exclude<
600
- // MakeContext<Make>,
601
- // MakeDepsOut<Make>
602
- // >
603
- // >
604
-
605
- // // just for type testing purposes
606
- // make: Make
607
- // }
608
- // <
609
- // const Make extends {
610
- // dependencies?: Array<Layer.Layer.Any>
611
- // effect: (match: typeof router3) => Effect<
612
- // { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> },
613
- // any,
614
- // any
615
- // >
616
- // /** @deprecated */
617
- // readonly ಠ_ಠ: never
618
- // }
619
- // >(
620
- // make: Make
621
- // ): {
622
- // moduleName: ModuleName
623
-
624
- // routes: Layer.Layer<
625
- // RouterShape<Resource>,
626
- // | MakeErrors<Make>
627
- // | Service.MakeDepsE<Make>
628
- // | Layer.Error<typeof middleware.Default>,
629
- // | Service.MakeDepsIn<Make>
630
- // | Layer.Context<typeof middleware.Default>
631
- // | Exclude<
632
- // MakeContext<Make>,
633
- // MakeDepsOut<Make>
634
- // >
635
- // >
636
-
637
- // // just for type testing purposes
638
- // make: Make
639
- // }
640
- // <
641
- // const Make extends {
642
- // dependencies?: Array<Layer.Layer.Any>
643
- // effect: (match: typeof router3) => Effect<
644
- // { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> },
645
- // any,
646
- // any
647
- // >
648
- // }
649
- // >(
650
- // make: Make
651
- // ): {
652
- // moduleName: ModuleName
653
-
654
- // routes: Layer.Layer<
655
- // RouterShape<Resource>,
656
- // | MakeErrors<Make>
657
- // | Service.MakeDepsE<Make>
658
- // | Layer.Error<typeof middleware.Default>,
659
- // | Service.MakeDepsIn<Make>
660
- // | Layer.Context<typeof middleware.Default>
661
- // | Exclude<
662
- // MakeContext<Make>,
663
- // MakeDepsOut<Make>
664
- // >
665
- // >
666
-
667
- // // just for type testing purposes
668
- // make: Make
669
- // }
670
511
  <
671
512
  const Make extends {
672
513
  dependencies?: Array<Layer.Layer.Any>
@@ -688,7 +529,7 @@ export const makeRouter = <
688
529
  moduleName: ModuleName
689
530
 
690
531
  routes: Layer.Layer<
691
- RouterShape<Resource>,
532
+ never,
692
533
  | MakeErrors<Make>
693
534
  | Service.MakeDepsE<Make>
694
535
  | Layer.Error<typeof middleware.Default>,
@@ -698,39 +539,12 @@ export const makeRouter = <
698
539
  MakeContext<Make>,
699
540
  MakeDepsOut<Make>
700
541
  >
542
+ | RpcSerialization.RpcSerialization
701
543
  >
702
544
 
703
545
  // just for type testing purposes
704
- make: Make
546
+ readonly [TypeTestId]: Make
705
547
  }
706
- // <
707
- // const Make extends {
708
- // dependencies: [
709
- // ...Make["dependencies"],
710
- // ...Exclude<Effect.Context<ReturnType<Make["effect"]>>, MakeDepsOut<Make>> extends never ? []
711
- // : [Layer.Layer<Exclude<Effect.Context<ReturnType<Make["effect"]>>, MakeDepsOut<Make>>, never, never>]
712
- // ]
713
- // effect: (match: typeof router3) => Effect<
714
- // { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> },
715
- // any,
716
- // any
717
- // >
718
- // }
719
- // >(
720
- // make: Make
721
- // ): {
722
- // moduleName: ModuleName
723
- // Router: HttpRouter.HttpRouter.TagClass<
724
- // RouterShape<Resource>,
725
- // `${ModuleName}Router`,
726
- // never,
727
- // never
728
- // >
729
- // routes: any
730
-
731
- // // just for type testing purposes
732
- // make: Make
733
- // }
734
548
  } =
735
549
  ((make: { dependencies: any; effect: any }) =>
736
550
  Object.assign(makeRoutes(make.dependencies, make.effect), { make })) as any
@@ -741,8 +555,7 @@ export const makeRouter = <
741
555
  function matchAll<
742
556
  T extends {
743
557
  [key: string]: {
744
- // Router: { router: Effect<HttpRouter.HttpRouter<any, any>, any, any> }
745
- routes: Layer.Layer<any, any, any>
558
+ routes: Layer.Layer<never, any, any>
746
559
  moduleName: string
747
560
  }
748
561
  }
@@ -755,7 +568,7 @@ export const makeRouter = <
755
568
  never,
756
569
  Layer.Layer.Error<typeof handlers[keyof typeof handlers]["routes"]>,
757
570
  Layer.Layer.Context<typeof handlers[keyof typeof handlers]["routes"]>
758
- > // TODO
571
+ >
759
572
  }
760
573
 
761
574
  return {