@effect-app/infra 4.0.0-beta.8 → 4.0.0-beta.81

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 (152) hide show
  1. package/CHANGELOG.md +527 -0
  2. package/dist/CUPS.d.ts +3 -3
  3. package/dist/CUPS.d.ts.map +1 -1
  4. package/dist/CUPS.js +3 -3
  5. package/dist/Emailer/Sendgrid.js +1 -1
  6. package/dist/Emailer/service.d.ts +3 -3
  7. package/dist/Emailer/service.d.ts.map +1 -1
  8. package/dist/Emailer/service.js +3 -3
  9. package/dist/MainFiberSet.d.ts +2 -2
  10. package/dist/MainFiberSet.d.ts.map +1 -1
  11. package/dist/MainFiberSet.js +3 -3
  12. package/dist/Model/Repository/internal/internal.d.ts +3 -3
  13. package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
  14. package/dist/Model/Repository/internal/internal.js +11 -7
  15. package/dist/Model/Repository/makeRepo.d.ts +2 -2
  16. package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
  17. package/dist/Model/Repository/makeRepo.js +1 -1
  18. package/dist/Model/Repository/validation.d.ts +5 -4
  19. package/dist/Model/Repository/validation.d.ts.map +1 -1
  20. package/dist/Model/query/dsl.d.ts +9 -9
  21. package/dist/Operations.d.ts +2 -2
  22. package/dist/Operations.d.ts.map +1 -1
  23. package/dist/Operations.js +3 -3
  24. package/dist/OperationsRepo.d.ts +2 -2
  25. package/dist/OperationsRepo.d.ts.map +1 -1
  26. package/dist/OperationsRepo.js +3 -3
  27. package/dist/QueueMaker/SQLQueue.d.ts +3 -5
  28. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  29. package/dist/QueueMaker/SQLQueue.js +9 -7
  30. package/dist/QueueMaker/errors.d.ts +1 -1
  31. package/dist/QueueMaker/errors.d.ts.map +1 -1
  32. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  33. package/dist/QueueMaker/memQueue.js +10 -9
  34. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  35. package/dist/QueueMaker/sbqueue.js +11 -9
  36. package/dist/RequestContext.d.ts +19 -14
  37. package/dist/RequestContext.d.ts.map +1 -1
  38. package/dist/RequestContext.js +5 -5
  39. package/dist/RequestFiberSet.d.ts +2 -2
  40. package/dist/RequestFiberSet.d.ts.map +1 -1
  41. package/dist/RequestFiberSet.js +5 -5
  42. package/dist/Store/ContextMapContainer.d.ts +14 -3
  43. package/dist/Store/ContextMapContainer.d.ts.map +1 -1
  44. package/dist/Store/ContextMapContainer.js +64 -3
  45. package/dist/Store/Cosmos.js +1 -1
  46. package/dist/Store/Disk.d.ts.map +1 -1
  47. package/dist/Store/Disk.js +3 -4
  48. package/dist/Store/Memory.d.ts +2 -2
  49. package/dist/Store/Memory.d.ts.map +1 -1
  50. package/dist/Store/Memory.js +4 -4
  51. package/dist/Store/service.d.ts +6 -3
  52. package/dist/Store/service.d.ts.map +1 -1
  53. package/dist/Store/service.js +14 -6
  54. package/dist/adapters/SQL/Model.d.ts +2 -5
  55. package/dist/adapters/SQL/Model.d.ts.map +1 -1
  56. package/dist/adapters/SQL/Model.js +21 -13
  57. package/dist/adapters/ServiceBus.d.ts +6 -6
  58. package/dist/adapters/ServiceBus.d.ts.map +1 -1
  59. package/dist/adapters/ServiceBus.js +9 -9
  60. package/dist/adapters/cosmos-client.d.ts +2 -2
  61. package/dist/adapters/cosmos-client.d.ts.map +1 -1
  62. package/dist/adapters/cosmos-client.js +3 -3
  63. package/dist/adapters/logger.d.ts.map +1 -1
  64. package/dist/adapters/memQueue.d.ts +2 -2
  65. package/dist/adapters/memQueue.d.ts.map +1 -1
  66. package/dist/adapters/memQueue.js +3 -3
  67. package/dist/adapters/mongo-client.d.ts +2 -2
  68. package/dist/adapters/mongo-client.d.ts.map +1 -1
  69. package/dist/adapters/mongo-client.js +3 -3
  70. package/dist/adapters/redis-client.d.ts +3 -3
  71. package/dist/adapters/redis-client.d.ts.map +1 -1
  72. package/dist/adapters/redis-client.js +3 -3
  73. package/dist/api/ContextProvider.d.ts +6 -6
  74. package/dist/api/ContextProvider.d.ts.map +1 -1
  75. package/dist/api/ContextProvider.js +6 -6
  76. package/dist/api/internal/RequestContextMiddleware.d.ts +1 -1
  77. package/dist/api/internal/auth.d.ts +1 -1
  78. package/dist/api/internal/events.d.ts +2 -2
  79. package/dist/api/internal/events.d.ts.map +1 -1
  80. package/dist/api/internal/events.js +7 -5
  81. package/dist/api/layerUtils.d.ts +5 -5
  82. package/dist/api/layerUtils.d.ts.map +1 -1
  83. package/dist/api/layerUtils.js +5 -5
  84. package/dist/api/routing/middleware/RouterMiddleware.d.ts +3 -3
  85. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  86. package/dist/api/routing/schema/jwt.d.ts +1 -1
  87. package/dist/api/routing/schema/jwt.d.ts.map +1 -1
  88. package/dist/api/routing/schema/jwt.js +1 -1
  89. package/dist/api/routing.d.ts +1 -5
  90. package/dist/api/routing.d.ts.map +1 -1
  91. package/dist/api/routing.js +3 -2
  92. package/dist/api/setupRequest.js +4 -4
  93. package/dist/errorReporter.d.ts +1 -1
  94. package/dist/errorReporter.d.ts.map +1 -1
  95. package/dist/errorReporter.js +1 -1
  96. package/dist/fileUtil.js +1 -1
  97. package/dist/logger.d.ts.map +1 -1
  98. package/dist/rateLimit.js +1 -1
  99. package/examples/query.ts +29 -25
  100. package/package.json +16 -16
  101. package/src/CUPS.ts +2 -2
  102. package/src/Emailer/Sendgrid.ts +1 -1
  103. package/src/Emailer/service.ts +2 -2
  104. package/src/MainFiberSet.ts +2 -2
  105. package/src/Model/Repository/internal/internal.ts +11 -8
  106. package/src/Model/Repository/makeRepo.ts +2 -2
  107. package/src/Operations.ts +2 -2
  108. package/src/OperationsRepo.ts +2 -2
  109. package/src/QueueMaker/SQLQueue.ts +10 -10
  110. package/src/QueueMaker/memQueue.ts +41 -42
  111. package/src/QueueMaker/sbqueue.ts +65 -62
  112. package/src/RequestContext.ts +4 -4
  113. package/src/RequestFiberSet.ts +4 -4
  114. package/src/Store/ContextMapContainer.ts +98 -2
  115. package/src/Store/Cosmos.ts +10 -10
  116. package/src/Store/Disk.ts +2 -3
  117. package/src/Store/Memory.ts +4 -6
  118. package/src/Store/service.ts +14 -5
  119. package/src/adapters/SQL/Model.ts +76 -71
  120. package/src/adapters/ServiceBus.ts +8 -8
  121. package/src/adapters/cosmos-client.ts +2 -2
  122. package/src/adapters/memQueue.ts +2 -2
  123. package/src/adapters/mongo-client.ts +2 -2
  124. package/src/adapters/redis-client.ts +2 -2
  125. package/src/api/ContextProvider.ts +11 -11
  126. package/src/api/internal/events.ts +7 -6
  127. package/src/api/layerUtils.ts +8 -8
  128. package/src/api/routing/middleware/RouterMiddleware.ts +4 -4
  129. package/src/api/routing/schema/jwt.ts +2 -3
  130. package/src/api/routing.ts +7 -6
  131. package/src/api/setupRequest.ts +3 -3
  132. package/src/errorReporter.ts +1 -1
  133. package/src/fileUtil.ts +1 -1
  134. package/src/rateLimit.ts +2 -2
  135. package/test/contextProvider.test.ts +5 -5
  136. package/test/controller.test.ts +12 -9
  137. package/test/dist/contextProvider.test.d.ts.map +1 -1
  138. package/test/dist/controller.test.d.ts.map +1 -1
  139. package/test/dist/fixtures.d.ts +18 -8
  140. package/test/dist/fixtures.d.ts.map +1 -1
  141. package/test/dist/fixtures.js +11 -9
  142. package/test/dist/query.test.d.ts.map +1 -1
  143. package/test/dist/rawQuery.test.d.ts.map +1 -1
  144. package/test/dist/requires.test.d.ts.map +1 -1
  145. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  146. package/test/fixtures.ts +10 -8
  147. package/test/query.test.ts +160 -14
  148. package/test/rawQuery.test.ts +19 -17
  149. package/test/requires.test.ts +6 -5
  150. package/test/rpc-multi-middleware.test.ts +73 -4
  151. package/test/validateSample.test.ts +1 -1
  152. package/tsconfig.json +0 -1
@@ -1,4 +1,8 @@
1
- import { Data, Effect, Layer, ServiceMap } from "effect-app"
1
+ import { Context, Data, Effect, type Exit, Layer, RequestResolver } from "effect-app"
2
+ import type { NonEmptyArray } from "effect/Array"
3
+ import { dual } from "effect/Function"
4
+ import * as MutableHashMap from "effect/MutableHashMap"
5
+ import type * as Request from "effect/Request"
2
6
  import { ContextMap } from "./service.js"
3
7
 
4
8
  // TODO: we have to create a new contextmap on every request.
@@ -7,7 +11,7 @@ import { ContextMap } from "./service.js"
7
11
  // we can call another start after startup. but it would be even better if we could Die on accessing rootmap
8
12
  // we could also make the ContextMap optional, and when missing, issue a warning instead?
9
13
 
10
- export class ContextMapContainer extends ServiceMap.Reference("ContextMapContainer", {
14
+ export class ContextMapContainer extends Context.Reference("ContextMapContainer", {
11
15
  defaultValue: (): ContextMap | "root" => "root"
12
16
  }) {
13
17
  static readonly layer = Layer.effect(this, ContextMap.make.pipe(Effect.map(ContextMap.of)))
@@ -18,3 +22,95 @@ export class ContextMapNotStartedError extends Data.TaggedError("ContextMapNotSt
18
22
  export const getContextMap = ContextMapContainer.asEffect().pipe(
19
23
  Effect.filterOrFail((_) => _ !== "root", () => new ContextMapNotStartedError())
20
24
  )
25
+
26
+ export const withRequestResolverCache: {
27
+ <A extends Request.Request<any, any>>(options: {
28
+ readonly capacity: number
29
+ readonly strategy?: "lru" | "fifo" | undefined
30
+ }): (self: RequestResolver.RequestResolver<A>) => RequestResolver.RequestResolver<A>
31
+ <A extends Request.Request<any, any>>(
32
+ self: RequestResolver.RequestResolver<A>,
33
+ options: {
34
+ readonly capacity: number
35
+ readonly strategy?: "lru" | "fifo" | undefined
36
+ }
37
+ ): RequestResolver.RequestResolver<A>
38
+ } = dual(2, <A extends Request.Request<any, any>>(
39
+ self: RequestResolver.RequestResolver<A>,
40
+ options: {
41
+ readonly capacity: number
42
+ readonly strategy?: "lru" | "fifo" | undefined
43
+ }
44
+ ): RequestResolver.RequestResolver<A> => {
45
+ const cacheKey = Symbol()
46
+ const strategy = options.strategy ?? "lru"
47
+ type CacheEntry = {
48
+ readonly entry: Request.Entry<A>
49
+ exit: Exit.Exit<Request.Success<A>, Request.Error<A>> | undefined
50
+ }
51
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
52
+ return RequestResolver.makeWith({
53
+ ...(self as any),
54
+ runAll(
55
+ entries: NonEmptyArray<Request.Entry<A>>,
56
+ key: unknown
57
+ ) {
58
+ return Effect.flatMap(
59
+ getContextMap.pipe(Effect.orDie),
60
+ (contextMap) => {
61
+ const cache = contextMap.getOrCreateStore<MutableHashMap.MutableHashMap<A, CacheEntry>>(
62
+ cacheKey,
63
+ () => MutableHashMap.empty()
64
+ )
65
+
66
+ const uncached: Array<Request.Entry<A>> = []
67
+ for (const entry of entries) {
68
+ const ocached = MutableHashMap.get(cache, entry.request)
69
+ if (ocached._tag === "None") {
70
+ const cached: CacheEntry = { entry, exit: undefined }
71
+ MutableHashMap.set(cache, entry.request, cached)
72
+ const prevComplete = entry.completeUnsafe.bind(entry)
73
+ entry.completeUnsafe = (exit) => {
74
+ cached.exit = exit
75
+ prevComplete(exit)
76
+ }
77
+ uncached.push(entry)
78
+ } else {
79
+ const cached = ocached.value
80
+ if (cached.exit) {
81
+ if (strategy === "lru") {
82
+ MutableHashMap.remove(cache, cached.entry.request)
83
+ MutableHashMap.set(cache, cached.entry.request, cached)
84
+ }
85
+ entry.completeUnsafe(cached.exit as any)
86
+ } else {
87
+ cached.entry.uninterruptible = true
88
+ const prevComplete = cached.entry.completeUnsafe.bind(cached.entry)
89
+ cached.entry.completeUnsafe = (exit) => {
90
+ prevComplete(exit)
91
+ entry.completeUnsafe(exit)
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ if (uncached.length === 0) return Effect.void
98
+
99
+ return Effect.onExit(
100
+ (self as any).runAll(uncached, key),
101
+ () => {
102
+ let toRemove = MutableHashMap.size(cache) - options.capacity
103
+ if (toRemove <= 0) return Effect.void
104
+ for (const k of MutableHashMap.keys(cache)) {
105
+ MutableHashMap.remove(cache, k)
106
+ toRemove--
107
+ if (toRemove <= 0) break
108
+ }
109
+ return Effect.void
110
+ }
111
+ )
112
+ }
113
+ )
114
+ }
115
+ })
116
+ })
@@ -328,15 +328,13 @@ function makeCosmosStore({ prefix }: StorageConfig) {
328
328
  .query<M>(q, { partitionKey: mainPartitionKey })
329
329
  .fetchAll()
330
330
  .then(({ resources }) =>
331
- resources.map((_) =>
332
- ({
333
- ...pipe(
334
- defaultValues,
335
- Struct.pick(f.select!.filter((_) => typeof _ === "string"))
336
- ),
337
- ...mapReverseId(_ as any)
338
- }) as any
339
- )
331
+ resources.map((_) => ({
332
+ ...pipe(
333
+ defaultValues,
334
+ Struct.pick(f.select!.filter((_) => typeof _ === "string") as never[])
335
+ ),
336
+ ...mapReverseId(_ as any)
337
+ }))
340
338
  )
341
339
  : container
342
340
  .items
@@ -404,7 +402,9 @@ function makeCosmosStore({ prefix }: StorageConfig) {
404
402
  Effect
405
403
  .flatMap((x) => {
406
404
  if (x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409) {
407
- return Effect.fail(new OptimisticConcurrencyException({ type: name, id: e[idKey], code: x.statusCode }))
405
+ return Effect.fail(
406
+ new OptimisticConcurrencyException({ type: name, id: e[idKey], code: x.statusCode })
407
+ )
408
408
  }
409
409
  if (x.statusCode > 299 || x.statusCode < 200) {
410
410
  return Effect.die(
package/src/Store/Disk.ts CHANGED
@@ -66,11 +66,10 @@ function makeDiskStoreInt<IdKey extends keyof Encoded, Encoded extends FieldValu
66
66
  }
67
67
 
68
68
  // lock file for cross-process coordination during initialization
69
- const lockFile = file + ".lock"
70
69
 
71
70
  // wrap initialization in file lock to prevent race conditions in multi-worker setups
72
71
  const store = yield* fu.withFileLock(
73
- lockFile,
72
+ file,
74
73
  Effect.gen(function*() {
75
74
  const shouldSeed = !(fs.existsSync(file))
76
75
 
@@ -143,7 +142,7 @@ export function makeDiskStore({ prefix }: StorageConfig, dir: string) {
143
142
  const storesSem = Semaphore.makeUnsafe(1)
144
143
  const primary = yield* makeDiskStoreInt(prefix, idKey, "primary", dir, name, seed, config?.defaultValues)
145
144
  const stores = new Map<string, Store<IdKey, Encoded>>([["primary", primary]])
146
- const ctx = yield* Effect.services<R>()
145
+ const ctx = yield* Effect.context<R>()
147
146
  const getStore = !config?.allowNamespace
148
147
  ? Effect.succeed(primary)
149
148
  : storeId.asEffect().pipe(Effect.flatMap((namespace) => {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
 
3
- import { Array, Effect, flow, type NonEmptyReadonlyArray, Option, Order, pipe, Ref, Result, Semaphore, ServiceMap, Struct } from "effect-app"
3
+ import { Array, Context, Effect, flow, type NonEmptyReadonlyArray, Option, Order, pipe, Ref, Result, Semaphore, Struct } from "effect-app"
4
4
  import { NonEmptyString255 } from "effect-app/Schema"
5
5
  import { get } from "effect-app/utils"
6
6
  import { InfraLogger } from "../logger.js"
@@ -24,7 +24,7 @@ export function memFilter<T extends FieldValues, U extends keyof T = never>(f: F
24
24
  )
25
25
  const n = Struct.pick(i, keys)
26
26
  subKeys.forEach((subKey) => {
27
- n[subKey.key] = i[subKey.key]!.map(Struct.pick(subKey.subKeys))
27
+ n[subKey.key] = i[subKey.key]!.map(Struct.pick(subKey.subKeys as never[]))
28
28
  })
29
29
  return n as M
30
30
  }) as any
@@ -72,9 +72,7 @@ export function memFilter<T extends FieldValues, U extends keyof T = never>(f: F
72
72
  }
73
73
 
74
74
  const defaultNs: NonEmptyString255 = NonEmptyString255("primary")
75
- export class storeId
76
- extends ServiceMap.Reference("StoreId", { defaultValue: (): NonEmptyString255 => defaultNs })
77
- {}
75
+ export class storeId extends Context.Reference("StoreId", { defaultValue: (): NonEmptyString255 => defaultNs }) {}
78
76
 
79
77
  function logQuery(f: FilterArgs<any, any>, defaultValues?: any) {
80
78
  return InfraLogger
@@ -267,7 +265,7 @@ export const makeMemoryStore = () => ({
267
265
  seed,
268
266
  config?.defaultValues
269
267
  )
270
- const ctx = yield* Effect.services<R>()
268
+ const ctx = yield* Effect.context<R>()
271
269
  const stores = new Map([["primary", primary]])
272
270
  const getStore = !config?.allowNamespace
273
271
  ? Effect.succeed(primary)
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import type { UniqueKey } from "@azure/cosmos"
3
- import { Effect, type NonEmptyReadonlyArray, type Option, type Redacted, ServiceMap } from "effect-app"
3
+ import { Context, Effect, type NonEmptyReadonlyArray, type Option, type Redacted } from "effect-app"
4
4
  import type { OptimisticConcurrencyException } from "../errors.js"
5
5
  import type { FilterResult } from "../Model/filter/filterApi.js"
6
6
  import type { FieldValues } from "../Model/filter/types.js"
@@ -89,7 +89,7 @@ export interface Store<
89
89
  queryRaw: <Out>(query: RawQuery<Encoded, Out>) => Effect.Effect<readonly Out[]>
90
90
  }
91
91
 
92
- export class StoreMaker extends ServiceMap.Opaque<StoreMaker, {
92
+ export class StoreMaker extends Context.Opaque<StoreMaker, {
93
93
  make: <IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
94
94
  name: string,
95
95
  idKey: IdKey,
@@ -161,16 +161,25 @@ export const makeContextMap = () => {
161
161
  // }
162
162
  // }
163
163
 
164
+ const store = new Map<symbol, unknown>()
165
+
164
166
  return {
165
167
  get: getEtag,
166
- set: setEtag
167
- // parserEnv
168
+ set: setEtag,
169
+ getOrCreateStore: <T>(key: symbol, make: () => T): T => {
170
+ let value = store.get(key) as T | undefined
171
+ if (value === undefined) {
172
+ value = make()
173
+ store.set(key, value)
174
+ }
175
+ return value
176
+ }
168
177
  }
169
178
  }
170
179
 
171
180
  const makeMap = Effect.sync(() => makeContextMap())
172
181
 
173
- export class ContextMap extends ServiceMap.Opaque<ContextMap>()("effect-app/ContextMap", { make: makeMap }) {
182
+ export class ContextMap extends Context.Opaque<ContextMap>()("effect-app/ContextMap", { make: makeMap }) {
174
183
  }
175
184
 
176
185
  export type PersistenceModelType<Encoded extends object> = Encoded & {
@@ -7,10 +7,6 @@
7
7
  /**
8
8
  * @since 1.0.0
9
9
  */
10
- import * as VariantSchema from "effect/unstable/schema/VariantSchema"
11
- import { SqlClient } from "effect/unstable/sql/SqlClient"
12
- import * as SqlResolver from "effect/unstable/sql/SqlResolver"
13
- import * as SqlSchema from "effect/unstable/sql/SqlSchema"
14
10
  import crypto from "crypto" // TODO
15
11
  import type { Brand } from "effect/Brand"
16
12
  import * as DateTime from "effect/DateTime"
@@ -24,6 +20,10 @@ import * as Schema from "effect/Schema"
24
20
  import * as Getter from "effect/SchemaGetter"
25
21
  import * as Transformation from "effect/SchemaTransformation"
26
22
  import type { Scope } from "effect/Scope"
23
+ import * as VariantSchema from "effect/unstable/schema/VariantSchema"
24
+ import { SqlClient } from "effect/unstable/sql/SqlClient"
25
+ import * as SqlResolver from "effect/unstable/sql/SqlResolver"
26
+ import * as SqlSchema from "effect/unstable/sql/SqlSchema"
27
27
 
28
28
  const {
29
29
  Class,
@@ -190,14 +190,13 @@ export const Generated = <S extends Schema.Top>(
190
190
  * @since 1.0.0
191
191
  * @category generated
192
192
  */
193
- export interface GeneratedByApp<S extends Schema.Top>
194
- extends
195
- VariantSchema.Field<{
196
- readonly select: S
197
- readonly insert: S
198
- readonly update: S
199
- readonly json: S
200
- }>
193
+ export interface GeneratedByApp<S extends Schema.Top> extends
194
+ VariantSchema.Field<{
195
+ readonly select: S
196
+ readonly insert: S
197
+ readonly update: S
198
+ readonly json: S
199
+ }>
201
200
  {}
202
201
 
203
202
  /**
@@ -303,8 +302,7 @@ export const FieldOption: <Field extends VariantSchema.Field<any> | Schema.Top>(
303
302
  ) => Field extends Schema.Top ? FieldOption<Field>
304
303
  : Field extends VariantSchema.Field<infer S> ? VariantSchema.Field<
305
304
  {
306
- readonly [K in keyof S]: S[K] extends Schema.Top
307
- ? K extends VariantsDatabase ? Schema.OptionFromNullOr<S[K]>
305
+ readonly [K in keyof S]: S[K] extends Schema.Top ? K extends VariantsDatabase ? Schema.OptionFromNullOr<S[K]>
308
306
  : optionalOption<S[K]>
309
307
  : never
310
308
  }
@@ -545,16 +543,15 @@ export const DateTimeUpdateFromNumber: DateTimeUpdateFromNumber = Field({
545
543
  * @since 1.0.0
546
544
  * @category json
547
545
  */
548
- export interface JsonFromString<S extends Schema.Top>
549
- extends
550
- VariantSchema.Field<{
551
- readonly select: Schema.fromJsonString<S>
552
- readonly insert: Schema.fromJsonString<S>
553
- readonly update: Schema.fromJsonString<S>
554
- readonly json: S
555
- readonly jsonCreate: S
556
- readonly jsonUpdate: S
557
- }>
546
+ export interface JsonFromString<S extends Schema.Top> extends
547
+ VariantSchema.Field<{
548
+ readonly select: Schema.fromJsonString<S>
549
+ readonly insert: Schema.fromJsonString<S>
550
+ readonly update: Schema.fromJsonString<S>
551
+ readonly json: S
552
+ readonly jsonCreate: S
553
+ readonly jsonUpdate: S
554
+ }>
558
555
  {}
559
556
 
560
557
  /**
@@ -825,26 +822,28 @@ export const makeDataLoaders = <
825
822
  const idColumn = options.idColumn as string
826
823
  const setMaxBatchSize = options.maxBatchSize ? RequestResolver.batchN(options.maxBatchSize) : identity
827
824
 
828
- const insertResolver = SqlResolver.ordered({
829
- Request: Model.insert,
830
- Result: Model,
831
- execute: (request: any) =>
832
- sql.onDialectOrElse({
833
- mysql: () =>
834
- Effect.forEach(request, (request: any) =>
835
- sql`insert into ${sql(options.tableName)} ${sql.insert(request)};
825
+ const insertResolver = SqlResolver
826
+ .ordered({
827
+ Request: Model.insert,
828
+ Result: Model,
829
+ execute: (request: any) =>
830
+ sql.onDialectOrElse({
831
+ mysql: () =>
832
+ Effect.forEach(request, (request: any) =>
833
+ sql`insert into ${sql(options.tableName)} ${sql.insert(request)};
836
834
  select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID();`
837
- .unprepared
838
- .pipe(
839
- Effect.map(([, results]) => results![0] as any)
840
- ), { concurrency: 10 }),
841
- orElse: () => sql`insert into ${sql(options.tableName)} ${sql.insert(request).returning("*")}`
842
- })
843
- }).pipe(
844
- RequestResolver.setDelay(options.window),
845
- setMaxBatchSize,
846
- RequestResolver.withSpan(`${options.spanPrefix}.insertResolver`)
847
- )
835
+ .unprepared
836
+ .pipe(
837
+ Effect.map(([, results]) => results![0] as any)
838
+ ), { concurrency: 10 }),
839
+ orElse: () => sql`insert into ${sql(options.tableName)} ${sql.insert(request).returning("*")}`
840
+ })
841
+ })
842
+ .pipe(
843
+ RequestResolver.setDelay(options.window),
844
+ setMaxBatchSize,
845
+ RequestResolver.withSpan(`${options.spanPrefix}.insertResolver`)
846
+ )
848
847
  const insertExecute = SqlResolver.request(insertResolver)
849
848
  const insert = (
850
849
  insert: S["insert"]["Type"]
@@ -860,14 +859,16 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
860
859
  })
861
860
  ) as any
862
861
 
863
- const insertVoidResolver = SqlResolver.void({
864
- Request: Model.insert,
865
- execute: (request: any) => sql`insert into ${sql(options.tableName)} ${sql.insert(request)}`
866
- }).pipe(
867
- RequestResolver.setDelay(options.window),
868
- setMaxBatchSize,
869
- RequestResolver.withSpan(`${options.spanPrefix}.insertVoidResolver`)
870
- )
862
+ const insertVoidResolver = SqlResolver
863
+ .void({
864
+ Request: Model.insert,
865
+ execute: (request: any) => sql`insert into ${sql(options.tableName)} ${sql.insert(request)}`
866
+ })
867
+ .pipe(
868
+ RequestResolver.setDelay(options.window),
869
+ setMaxBatchSize,
870
+ RequestResolver.withSpan(`${options.spanPrefix}.insertVoidResolver`)
871
+ )
871
872
  const insertVoidExecute = SqlResolver.request(insertVoidResolver)
872
873
  const insertVoid = (
873
874
  insert: S["insert"]["Type"]
@@ -878,18 +879,20 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
878
879
  })
879
880
  ) as any
880
881
 
881
- const findByIdResolver = SqlResolver.findById({
882
- Id: idSchema,
883
- Result: Model,
884
- ResultId(request: any) {
885
- return request[idColumn]
886
- },
887
- execute: (ids: any) => sql`select * from ${sql(options.tableName)} where ${sql.in(idColumn, ids)}`
888
- }).pipe(
889
- RequestResolver.setDelay(options.window),
890
- setMaxBatchSize,
891
- RequestResolver.withSpan(`${options.spanPrefix}.findByIdResolver`)
892
- )
882
+ const findByIdResolver = SqlResolver
883
+ .findById({
884
+ Id: idSchema,
885
+ Result: Model,
886
+ ResultId(request: any) {
887
+ return request[idColumn]
888
+ },
889
+ execute: (ids: any) => sql`select * from ${sql(options.tableName)} where ${sql.in(idColumn, ids)}`
890
+ })
891
+ .pipe(
892
+ RequestResolver.setDelay(options.window),
893
+ setMaxBatchSize,
894
+ RequestResolver.withSpan(`${options.spanPrefix}.findByIdResolver`)
895
+ )
893
896
  const findByIdExecute = SqlResolver.request(findByIdResolver)
894
897
  const findById = (
895
898
  id: S["fields"][Id]["Type"]
@@ -904,14 +907,16 @@ select * from ${sql(options.tableName)} where ${sql(idColumn)} = LAST_INSERT_ID(
904
907
  })
905
908
  ) as any
906
909
 
907
- const deleteResolver = SqlResolver.void({
908
- Request: idSchema,
909
- execute: (ids: any) => sql`delete from ${sql(options.tableName)} where ${sql.in(idColumn, ids)}`
910
- }).pipe(
911
- RequestResolver.setDelay(options.window),
912
- setMaxBatchSize,
913
- RequestResolver.withSpan(`${options.spanPrefix}.deleteResolver`)
914
- )
910
+ const deleteResolver = SqlResolver
911
+ .void({
912
+ Request: idSchema,
913
+ execute: (ids: any) => sql`delete from ${sql(options.tableName)} where ${sql.in(idColumn, ids)}`
914
+ })
915
+ .pipe(
916
+ RequestResolver.setDelay(options.window),
917
+ setMaxBatchSize,
918
+ RequestResolver.withSpan(`${options.spanPrefix}.deleteResolver`)
919
+ )
915
920
  const deleteExecute = SqlResolver.request(deleteResolver)
916
921
  const delete_ = (
917
922
  id: S["fields"][Id]["Type"]
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
2
2
  import { type OperationOptionsBase, type ProcessErrorArgs, ServiceBusClient, type ServiceBusMessage, type ServiceBusMessageBatch, type ServiceBusReceivedMessage, type ServiceBusReceiver } from "@azure/service-bus"
3
- import { Cause, Effect, Exit, FiberSet, Layer, type Scope, ServiceMap } from "effect-app"
3
+ import { Cause, Context, Effect, Exit, FiberSet, Layer, type Scope } from "effect-app"
4
4
  import { InfraLogger } from "../logger.js"
5
5
 
6
6
  const withSpanAndLog = (name: string) => <A, E, R>(self: Effect.Effect<A, E, R>) =>
@@ -19,7 +19,7 @@ function makeClient(url: string) {
19
19
  }
20
20
 
21
21
  export class ServiceBusClientTag
22
- extends ServiceMap.Opaque<ServiceBusClientTag, ServiceBusClient>()("@services/Client", { make: makeClient })
22
+ extends Context.Opaque<ServiceBusClientTag, ServiceBusClient>()("@services/Client", { make: makeClient })
23
23
  {
24
24
  static readonly layer = (url: string) => this.toLayer(this.make(url))
25
25
  }
@@ -50,7 +50,7 @@ const makeSender = (name: string) =>
50
50
  return { name, sendMessages }
51
51
  })
52
52
 
53
- export class Sender extends ServiceMap.Opaque<Sender, {
53
+ export class Sender extends Context.Opaque<Sender, {
54
54
  name: string
55
55
  sendMessages: (
56
56
  messages: ServiceBusMessage | ServiceBusMessage[] | ServiceBusMessageBatch,
@@ -61,12 +61,12 @@ export class Sender extends ServiceMap.Opaque<Sender, {
61
61
  }
62
62
 
63
63
  export const SenderTag = <Id>() => <Key extends string>(queueName: Key) => {
64
- const tag = ServiceMap.Service<Id, Sender>(`ServiceBus.Sender.${queueName}`)
64
+ const tag = Context.Service<Id, Sender>(`ServiceBus.Sender.${queueName}`)
65
65
 
66
66
  return Object.assign(tag, {
67
67
  layer: Layer.effect(
68
68
  tag,
69
- Sender.make(queueName).pipe(Effect.map((_) => Sender.of(_)))
69
+ Sender.make(queueName).pipe(Effect.map(Sender.of))
70
70
  )
71
71
  })
72
72
  }
@@ -163,7 +163,7 @@ const makeReceiver = (name: string) =>
163
163
  }
164
164
  })
165
165
 
166
- export class Receiver extends ServiceMap.Opaque<Receiver, {
166
+ export class Receiver extends Context.Opaque<Receiver, {
167
167
  name: string
168
168
  make: (waitTillEmpty: Effect.Effect<void>) => Effect.Effect<ServiceBusReceiver, never, Scope.Scope>
169
169
  makeSession: (
@@ -180,12 +180,12 @@ export class Receiver extends ServiceMap.Opaque<Receiver, {
180
180
  }
181
181
 
182
182
  export const ReceiverTag = <Id>() => <Key extends string>(queueName: Key) => {
183
- const tag = ServiceMap.Service<Id, Receiver>(`ServiceBus.Receiver.${queueName}`)
183
+ const tag = Context.Service<Id, Receiver>(`ServiceBus.Receiver.${queueName}`)
184
184
 
185
185
  return Object.assign(tag, {
186
186
  layer: Layer.effect(
187
187
  tag,
188
- makeReceiver(queueName).pipe(Effect.map((_) => Receiver.of(_)))
188
+ makeReceiver(queueName).pipe(Effect.map(Receiver.of))
189
189
  )
190
190
  })
191
191
  }
@@ -1,12 +1,12 @@
1
1
  import { CosmosClient as ComosClient_ } from "@azure/cosmos"
2
- import { Effect, Layer, ServiceMap } from "effect-app"
2
+ import { Context, Effect, Layer } from "effect-app"
3
3
 
4
4
  const withClient = (url: string) => Effect.sync(() => new ComosClient_(url))
5
5
 
6
6
  export const makeCosmosClient = (url: string, dbName: string) =>
7
7
  Effect.map(withClient(url), (x) => ({ db: x.database(dbName) }))
8
8
 
9
- export class CosmosClient extends ServiceMap.Service<CosmosClient, {
9
+ export class CosmosClient extends Context.Service<CosmosClient, {
10
10
  readonly db: ReturnType<InstanceType<typeof ComosClient_>["database"]>
11
11
  }>()("@services/CosmosClient") {}
12
12
 
@@ -1,4 +1,4 @@
1
- import { Effect, type Queue, ServiceMap } from "effect-app"
1
+ import { Context, Effect, type Queue } from "effect-app"
2
2
  import * as Q from "effect/Queue"
3
3
 
4
4
  const make = Effect
@@ -16,6 +16,6 @@ const make = Effect
16
16
  }
17
17
  })
18
18
 
19
- export class MemQueue extends ServiceMap.Opaque<MemQueue>()("effect-app/MemQueue", { make }) {
19
+ export class MemQueue extends Context.Opaque<MemQueue>()("effect-app/MemQueue", { make }) {
20
20
  static readonly Live = this.toLayer(this.make)
21
21
  }
@@ -1,4 +1,4 @@
1
- import { Effect, Layer, ServiceMap } from "effect-app"
1
+ import { Context, Effect, Layer } from "effect-app"
2
2
  import { MongoClient as MongoClient_ } from "mongodb"
3
3
 
4
4
  // TODO: we should probably share a single client...
@@ -15,7 +15,7 @@ const withClient = (url: string) =>
15
15
 
16
16
  const makeMongoClient = (url: string, dbName?: string) => Effect.map(withClient(url), (x) => ({ db: x.db(dbName) }))
17
17
 
18
- export class MongoClient extends ServiceMap.Service<MongoClient, {
18
+ export class MongoClient extends Context.Service<MongoClient, {
19
19
  readonly db: ReturnType<InstanceType<typeof MongoClient_>["db"]>
20
20
  }>()("@services/MongoClient") {}
21
21
 
@@ -1,4 +1,4 @@
1
- import { Data, Effect, Layer, Option, ServiceMap } from "effect-app"
1
+ import { Context, Data, Effect, Layer, Option } from "effect-app"
2
2
  import type { RedisClient as Client } from "redis"
3
3
  import Redlock from "redlock"
4
4
 
@@ -90,7 +90,7 @@ export const makeRedisClient = (makeClient: () => Client) =>
90
90
  .pipe(Effect.uninterruptible, Effect.orDie)
91
91
  )
92
92
 
93
- export class RedisClient extends ServiceMap.Service<RedisClient, {
93
+ export class RedisClient extends Context.Service<RedisClient, {
94
94
  readonly client: Client
95
95
  readonly lock: Redlock
96
96
  readonly get: (key: string) => Effect.Effect<Option.Option<string>, ConnectionException>