effect 3.13.12 → 3.14.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 (154) hide show
  1. package/LayerMap/package.json +6 -0
  2. package/dist/cjs/Array.js +29 -2
  3. package/dist/cjs/Array.js.map +1 -1
  4. package/dist/cjs/DateTime.js +16 -1
  5. package/dist/cjs/DateTime.js.map +1 -1
  6. package/dist/cjs/Effect.js +45 -3
  7. package/dist/cjs/Effect.js.map +1 -1
  8. package/dist/cjs/Either.js +35 -1
  9. package/dist/cjs/Either.js.map +1 -1
  10. package/dist/cjs/FiberSet.js +14 -2
  11. package/dist/cjs/FiberSet.js.map +1 -1
  12. package/dist/cjs/HashMap.js +11 -1
  13. package/dist/cjs/HashMap.js.map +1 -1
  14. package/dist/cjs/Layer.js +6 -1
  15. package/dist/cjs/Layer.js.map +1 -1
  16. package/dist/cjs/LayerMap.js +183 -0
  17. package/dist/cjs/LayerMap.js.map +1 -0
  18. package/dist/cjs/MutableHashMap.js +36 -4
  19. package/dist/cjs/MutableHashMap.js.map +1 -1
  20. package/dist/cjs/MutableRef.js.map +1 -1
  21. package/dist/cjs/Runtime.js.map +1 -1
  22. package/dist/cjs/TestClock.js +3 -2
  23. package/dist/cjs/TestClock.js.map +1 -1
  24. package/dist/cjs/Tracer.js.map +1 -1
  25. package/dist/cjs/index.js +4 -2
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/internal/channel/channelExecutor.js +6 -1
  28. package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
  29. package/dist/cjs/internal/core-effect.js +13 -2
  30. package/dist/cjs/internal/core-effect.js.map +1 -1
  31. package/dist/cjs/internal/core.js +2 -1
  32. package/dist/cjs/internal/core.js.map +1 -1
  33. package/dist/cjs/internal/dateTime.js +3 -1
  34. package/dist/cjs/internal/dateTime.js.map +1 -1
  35. package/dist/cjs/internal/effect/circular.js +5 -0
  36. package/dist/cjs/internal/effect/circular.js.map +1 -1
  37. package/dist/cjs/internal/hashMap.js +3 -1
  38. package/dist/cjs/internal/hashMap.js.map +1 -1
  39. package/dist/cjs/internal/layer.js +7 -3
  40. package/dist/cjs/internal/layer.js.map +1 -1
  41. package/dist/cjs/internal/rcMap.js +11 -1
  42. package/dist/cjs/internal/rcMap.js.map +1 -1
  43. package/dist/cjs/internal/runtime.js +21 -21
  44. package/dist/cjs/internal/runtime.js.map +1 -1
  45. package/dist/cjs/internal/tracer.js +6 -2
  46. package/dist/cjs/internal/tracer.js.map +1 -1
  47. package/dist/cjs/internal/version.js +1 -1
  48. package/dist/cjs/internal/version.js.map +1 -1
  49. package/dist/dts/Array.d.ts +58 -0
  50. package/dist/dts/Array.d.ts.map +1 -1
  51. package/dist/dts/Data.d.ts +4 -4
  52. package/dist/dts/Data.d.ts.map +1 -1
  53. package/dist/dts/DateTime.d.ts +15 -0
  54. package/dist/dts/DateTime.d.ts.map +1 -1
  55. package/dist/dts/Effect.d.ts +66 -0
  56. package/dist/dts/Effect.d.ts.map +1 -1
  57. package/dist/dts/Either.d.ts +30 -0
  58. package/dist/dts/Either.d.ts.map +1 -1
  59. package/dist/dts/FiberSet.d.ts.map +1 -1
  60. package/dist/dts/HashMap.d.ts +31 -0
  61. package/dist/dts/HashMap.d.ts.map +1 -1
  62. package/dist/dts/Layer.d.ts +12 -0
  63. package/dist/dts/Layer.d.ts.map +1 -1
  64. package/dist/dts/LayerMap.d.ts +242 -0
  65. package/dist/dts/LayerMap.d.ts.map +1 -0
  66. package/dist/dts/MutableHashMap.d.ts +22 -0
  67. package/dist/dts/MutableHashMap.d.ts.map +1 -1
  68. package/dist/dts/MutableRef.d.ts +1 -0
  69. package/dist/dts/MutableRef.d.ts.map +1 -1
  70. package/dist/dts/Runtime.d.ts +144 -10
  71. package/dist/dts/Runtime.d.ts.map +1 -1
  72. package/dist/dts/TestClock.d.ts +3 -2
  73. package/dist/dts/TestClock.d.ts.map +1 -1
  74. package/dist/dts/Tracer.d.ts +1 -0
  75. package/dist/dts/Tracer.d.ts.map +1 -1
  76. package/dist/dts/index.d.ts +4 -0
  77. package/dist/dts/index.d.ts.map +1 -1
  78. package/dist/dts/internal/channel/channelExecutor.d.ts.map +1 -1
  79. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  80. package/dist/dts/internal/layer.d.ts.map +1 -1
  81. package/dist/esm/Array.js +28 -1
  82. package/dist/esm/Array.js.map +1 -1
  83. package/dist/esm/DateTime.js +15 -0
  84. package/dist/esm/DateTime.js.map +1 -1
  85. package/dist/esm/Effect.js +42 -0
  86. package/dist/esm/Effect.js.map +1 -1
  87. package/dist/esm/Either.js +33 -0
  88. package/dist/esm/Either.js.map +1 -1
  89. package/dist/esm/FiberSet.js +13 -1
  90. package/dist/esm/FiberSet.js.map +1 -1
  91. package/dist/esm/HashMap.js +10 -0
  92. package/dist/esm/HashMap.js.map +1 -1
  93. package/dist/esm/Layer.js +5 -0
  94. package/dist/esm/Layer.js.map +1 -1
  95. package/dist/esm/LayerMap.js +172 -0
  96. package/dist/esm/LayerMap.js.map +1 -0
  97. package/dist/esm/MutableHashMap.js +33 -3
  98. package/dist/esm/MutableHashMap.js.map +1 -1
  99. package/dist/esm/MutableRef.js.map +1 -1
  100. package/dist/esm/Runtime.js.map +1 -1
  101. package/dist/esm/TestClock.js +3 -2
  102. package/dist/esm/TestClock.js.map +1 -1
  103. package/dist/esm/Tracer.js.map +1 -1
  104. package/dist/esm/index.js +4 -0
  105. package/dist/esm/index.js.map +1 -1
  106. package/dist/esm/internal/channel/channelExecutor.js +6 -1
  107. package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
  108. package/dist/esm/internal/core-effect.js +10 -0
  109. package/dist/esm/internal/core-effect.js.map +1 -1
  110. package/dist/esm/internal/core.js +2 -1
  111. package/dist/esm/internal/core.js.map +1 -1
  112. package/dist/esm/internal/dateTime.js +2 -0
  113. package/dist/esm/internal/dateTime.js.map +1 -1
  114. package/dist/esm/internal/effect/circular.js +5 -0
  115. package/dist/esm/internal/effect/circular.js.map +1 -1
  116. package/dist/esm/internal/hashMap.js +2 -0
  117. package/dist/esm/internal/hashMap.js.map +1 -1
  118. package/dist/esm/internal/layer.js +6 -2
  119. package/dist/esm/internal/layer.js.map +1 -1
  120. package/dist/esm/internal/rcMap.js +11 -1
  121. package/dist/esm/internal/rcMap.js.map +1 -1
  122. package/dist/esm/internal/runtime.js +21 -15
  123. package/dist/esm/internal/runtime.js.map +1 -1
  124. package/dist/esm/internal/tracer.js +6 -2
  125. package/dist/esm/internal/tracer.js.map +1 -1
  126. package/dist/esm/internal/version.js +1 -1
  127. package/dist/esm/internal/version.js.map +1 -1
  128. package/package.json +9 -1
  129. package/src/Array.ts +69 -1
  130. package/src/Data.ts +4 -4
  131. package/src/DateTime.ts +16 -0
  132. package/src/Effect.ts +143 -0
  133. package/src/Either.ts +36 -0
  134. package/src/FiberSet.ts +14 -1
  135. package/src/HashMap.ts +32 -0
  136. package/src/Layer.ts +14 -0
  137. package/src/LayerMap.ts +396 -0
  138. package/src/MutableHashMap.ts +45 -3
  139. package/src/MutableRef.ts +0 -2
  140. package/src/Runtime.ts +158 -20
  141. package/src/TestClock.ts +10 -3
  142. package/src/Tracer.ts +1 -0
  143. package/src/index.ts +5 -0
  144. package/src/internal/channel/channelExecutor.ts +11 -4
  145. package/src/internal/core-effect.ts +15 -0
  146. package/src/internal/core.ts +2 -1
  147. package/src/internal/dateTime.ts +3 -0
  148. package/src/internal/effect/circular.ts +5 -0
  149. package/src/internal/hashMap.ts +9 -0
  150. package/src/internal/layer.ts +14 -2
  151. package/src/internal/rcMap.ts +13 -3
  152. package/src/internal/runtime.ts +104 -38
  153. package/src/internal/tracer.ts +8 -1
  154. package/src/internal/version.ts +1 -1
@@ -0,0 +1,396 @@
1
+ /**
2
+ * @since 3.14.0
3
+ * @experimental
4
+ */
5
+ import * as Context from "./Context.js"
6
+ import type * as Duration from "./Duration.js"
7
+ import * as Effect from "./Effect.js"
8
+ import { identity } from "./Function.js"
9
+ import * as Layer from "./Layer.js"
10
+ import * as RcMap from "./RcMap.js"
11
+ import * as Scope from "./Scope.js"
12
+ import type { Mutable } from "./Types.js"
13
+
14
+ /**
15
+ * @since 3.14.0
16
+ * @category Symbols
17
+ */
18
+ export const TypeId: unique symbol = Symbol.for("effect/LayerMap")
19
+
20
+ /**
21
+ * @since 3.14.0
22
+ * @category Symbols
23
+ */
24
+ export type TypeId = typeof TypeId
25
+
26
+ /**
27
+ * @since 3.14.0
28
+ * @category Models
29
+ * @experimental
30
+ */
31
+ export interface LayerMap<in K, in out I, out S, out E = never> {
32
+ readonly [TypeId]: TypeId
33
+
34
+ /**
35
+ * The internal RcMap that stores the resources.
36
+ */
37
+ readonly rcMap: RcMap.RcMap<K, readonly [Context.Context<I>, S], E>
38
+
39
+ /**
40
+ * Retrieves an instance of the resource associated with the key.
41
+ */
42
+ get(key: K): Effect.Effect<S, E, Scope.Scope>
43
+
44
+ /**
45
+ * Provides an instance of the resource associated with the key
46
+ * to the given effect.
47
+ */
48
+ provide(key: K): <A, EX, R>(effect: Effect.Effect<A, EX, R>) => Effect.Effect<A, EX | E, Exclude<R, I>>
49
+
50
+ /**
51
+ * Invalidates the resource associated with the key.
52
+ */
53
+ invalidate(key: K): Effect.Effect<void>
54
+ }
55
+
56
+ /**
57
+ * @since 3.14.0
58
+ * @category Constructors
59
+ * @experimental
60
+ *
61
+ * A `LayerMap` allows you to create a map of Layer's that can be used to
62
+ * dynamically access resources based on a key.
63
+ *
64
+ * ```ts
65
+ * import { Completions } from "@effect/ai"
66
+ * import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
67
+ * import { FetchHttpClient } from "@effect/platform"
68
+ * import { NodeRuntime } from "@effect/platform-node"
69
+ * import { Config, Effect, Layer, LayerMap } from "effect"
70
+ *
71
+ * // create the openai client layer
72
+ * const OpenAiLayer = OpenAiClient.layerConfig({
73
+ * apiKey: Config.redacted("OPENAI_API_KEY")
74
+ * }).pipe(Layer.provide(FetchHttpClient.layer))
75
+ *
76
+ * // create a service that wraps a LayerMap
77
+ * class AiClients extends LayerMap.Service<AiClients>()("AiClients", {
78
+ * // this LayerMap will provide the ai Completions service
79
+ * provides: Completions.Completions,
80
+ *
81
+ * // define the lookup function for the layer map
82
+ * //
83
+ * // The returned Layer will be used to provide the Completions service for the
84
+ * // given model.
85
+ * lookup: (model: OpenAiCompletions.Model) => OpenAiCompletions.layer({ model }),
86
+ *
87
+ * // If a layer is not used for a certain amount of time, it can be removed
88
+ * idleTimeToLive: "5 seconds",
89
+ *
90
+ * // Supply the dependencies for the layers in the LayerMap
91
+ * dependencies: [OpenAiLayer]
92
+ * }) {}
93
+ *
94
+ * // usage
95
+ * Effect.gen(function*() {
96
+ * // access and use the generic Completions service
97
+ * const ai = yield* Completions.Completions
98
+ * const response = yield* ai.create("Hello, world!")
99
+ * console.log(response.text)
100
+ * }).pipe(
101
+ * // use the AiClients service to provide a variant of the Completions service
102
+ * AiClients.provide("gpt-4o"),
103
+ * // provide the LayerMap service
104
+ * Effect.provide(AiClients.Default),
105
+ * NodeRuntime.runMain
106
+ * )
107
+ * ```
108
+ */
109
+ export const make: <
110
+ Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
111
+ K,
112
+ L extends Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>
113
+ >(
114
+ tagOrAccessor: Accessor,
115
+ lookup: (key: K) => L,
116
+ options?: {
117
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
118
+ } | undefined
119
+ ) => Effect.Effect<
120
+ LayerMap<
121
+ K,
122
+ Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>,
123
+ Effect.Effect.Success<Accessor>,
124
+ Effect.Effect.Error<Accessor> | (L extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never)
125
+ >,
126
+ never,
127
+ Scope.Scope | (L extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
128
+ > = Effect.fnUntraced(function*<I, S, K, EL, RL, E = never>(
129
+ tagOrAccessor: Effect.Effect<S, E, I>,
130
+ lookup: (key: K) => Layer.Layer<Exclude<I, Scope.Scope>, EL, RL>,
131
+ options?: {
132
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
133
+ } | undefined
134
+ ) {
135
+ const context = yield* Effect.context<never>()
136
+
137
+ // If we are inside another layer build, use the current memo map,
138
+ // otherwise create a new one.
139
+ const memoMap = context.unsafeMap.has(Layer.CurrentMemoMap.key)
140
+ ? Context.get(context, Layer.CurrentMemoMap)
141
+ : yield* Layer.makeMemoMap
142
+
143
+ const rcMap = yield* RcMap.make({
144
+ lookup: Effect.fnUntraced(function*(key: K) {
145
+ const scope = yield* Effect.scope
146
+ const context = yield* (Layer.buildWithMemoMap(lookup(key), memoMap, scope) as Effect.Effect<
147
+ Context.Context<Exclude<I, Scope.Scope>>
148
+ >)
149
+ const service = yield* (Effect.provide(tagOrAccessor, context) as Effect.Effect<S>)
150
+ return [context, service] as const
151
+ }),
152
+ idleTimeToLive: options?.idleTimeToLive
153
+ })
154
+
155
+ return identity<LayerMap<K, Exclude<I, Scope.Scope>, S, any>>({
156
+ [TypeId]: TypeId,
157
+ rcMap,
158
+ get: (key) => Effect.map(RcMap.get(rcMap, key), ([, service]) => service),
159
+ provide: (key) => (effect) =>
160
+ Effect.scopedWith((scope) =>
161
+ Effect.flatMap(
162
+ Scope.extend(RcMap.get(rcMap, key), scope),
163
+ ([context]) => Effect.provide(effect, context)
164
+ )
165
+ ),
166
+ invalidate: (key) => RcMap.invalidate(rcMap, key)
167
+ })
168
+ })
169
+
170
+ /**
171
+ * @since 3.14.0
172
+ * @category Constructors
173
+ * @experimental
174
+ */
175
+ export const fromRecord = <
176
+ Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
177
+ const Layers extends Record<string, Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>>
178
+ >(
179
+ tagOrAccessor: Accessor,
180
+ layers: Layers,
181
+ options?: {
182
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
183
+ } | undefined
184
+ ): Effect.Effect<
185
+ LayerMap<
186
+ keyof Layers,
187
+ Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>,
188
+ Effect.Effect.Success<Accessor>,
189
+ | Effect.Effect.Error<Accessor>
190
+ | (Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never)
191
+ >,
192
+ never,
193
+ Scope.Scope | (Layers[keyof Layers] extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
194
+ > => make(tagOrAccessor, (key: keyof Layers) => layers[key], options)
195
+
196
+ /**
197
+ * @since 3.14.0
198
+ * @category Service
199
+ */
200
+ export interface TagClass<
201
+ in out Self,
202
+ in out Id extends string,
203
+ in out K,
204
+ in out I,
205
+ in out S,
206
+ in out E,
207
+ in out R,
208
+ in out Deps extends Layer.Layer<any, any, any>
209
+ > extends Context.TagClass<Self, Id, LayerMap<K, I, S, E>> {
210
+ /**
211
+ * A default layer for the `LayerMap` service.
212
+ */
213
+ readonly Default: Layer.Layer<
214
+ Self,
215
+ (Deps extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never),
216
+ | Exclude<R, (Deps extends Layer.Layer<infer _A, infer _E, infer _R> ? _A : never)>
217
+ | (Deps extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never)
218
+ >
219
+
220
+ /**
221
+ * A default layer for the `LayerMap` service without the dependencies provided.
222
+ */
223
+ readonly DefaultWithoutDependencies: Layer.Layer<Self, never, R>
224
+
225
+ /**
226
+ * Retrieves an instance of the resource associated with the key.
227
+ */
228
+ readonly get: (key: K) => Effect.Effect<S, E, Scope.Scope | Self>
229
+
230
+ /**
231
+ * Provides an instance of the resource associated with the key to the given
232
+ * effect.
233
+ */
234
+ readonly provide: (
235
+ key: K
236
+ ) => <A, EX, R>(effect: Effect.Effect<A, EX, R>) => Effect.Effect<A, EX | E, Exclude<R, I> | Self>
237
+
238
+ /**
239
+ * Invalidates the resource associated with the key.
240
+ */
241
+ readonly invalidate: (key: K) => Effect.Effect<void, never, Self>
242
+ }
243
+
244
+ /**
245
+ * @since 3.14.0
246
+ * @category Service
247
+ * @experimental
248
+ *
249
+ * Create a `LayerMap` service that provides a dynamic set of resources based on
250
+ * a key.
251
+ *
252
+ * ```ts
253
+ * import { Completions } from "@effect/ai"
254
+ * import { OpenAiClient, OpenAiCompletions } from "@effect/ai-openai"
255
+ * import { FetchHttpClient } from "@effect/platform"
256
+ * import { NodeRuntime } from "@effect/platform-node"
257
+ * import { Config, Effect, Layer, LayerMap } from "effect"
258
+ *
259
+ * // create the openai client layer
260
+ * const OpenAiLayer = OpenAiClient.layerConfig({
261
+ * apiKey: Config.redacted("OPENAI_API_KEY")
262
+ * }).pipe(Layer.provide(FetchHttpClient.layer))
263
+ *
264
+ * // create a service that wraps a LayerMap
265
+ * class AiClients extends LayerMap.Service<AiClients>()("AiClients", {
266
+ * // this LayerMap will provide the ai Completions service
267
+ * provides: Completions.Completions,
268
+ *
269
+ * // define the lookup function for the layer map
270
+ * //
271
+ * // The returned Layer will be used to provide the Completions service for the
272
+ * // given model.
273
+ * lookup: (model: OpenAiCompletions.Model) => OpenAiCompletions.layer({ model }),
274
+ *
275
+ * // If a layer is not used for a certain amount of time, it can be removed
276
+ * idleTimeToLive: "5 seconds",
277
+ *
278
+ * // Supply the dependencies for the layers in the LayerMap
279
+ * dependencies: [OpenAiLayer]
280
+ * }) {}
281
+ *
282
+ * // usage
283
+ * Effect.gen(function*() {
284
+ * // access and use the generic Completions service
285
+ * const ai = yield* Completions.Completions
286
+ * const response = yield* ai.create("Hello, world!")
287
+ * console.log(response.text)
288
+ * }).pipe(
289
+ * // use the AiClients service to provide a variant of the Completions service
290
+ * AiClients.provide("gpt-4o"),
291
+ * // provide the LayerMap service
292
+ * Effect.provide(AiClients.Default),
293
+ * NodeRuntime.runMain
294
+ * )
295
+ * ```
296
+ */
297
+ export const Service = <Self>() =>
298
+ <
299
+ const Id extends string,
300
+ Accessor extends Context.Tag<any, any> | Effect.Effect<any, any, any>,
301
+ Lookup extends {
302
+ readonly lookup: (key: any) => Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>
303
+ } | {
304
+ readonly layers: Record<string, Layer.Layer<Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>, any, any>>
305
+ },
306
+ const Deps extends ReadonlyArray<Layer.Layer<any, any, any>> = []
307
+ >(
308
+ id: Id,
309
+ options: Lookup & {
310
+ readonly provides: Accessor
311
+ readonly dependencies?: Deps | undefined
312
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
313
+ }
314
+ ): TagClass<
315
+ Self,
316
+ Id,
317
+ Lookup extends { readonly lookup: (key: infer K) => any } ? K
318
+ : Lookup extends { readonly layers: infer Layers } ? keyof Layers
319
+ : never,
320
+ Exclude<Effect.Effect.Context<Accessor>, Scope.Scope>,
321
+ Effect.Effect.Success<Accessor>,
322
+ Effect.Effect.Error<Accessor> | Service.Error<Lookup>,
323
+ Service.Context<Lookup>,
324
+ Deps[number]
325
+ > => {
326
+ const Err = globalThis.Error as any
327
+ const limit = Err.stackTraceLimit
328
+ Err.stackTraceLimit = 2
329
+ const creationError = new Err()
330
+ Err.stackTraceLimit = limit
331
+
332
+ function TagClass() {}
333
+ const TagClass_ = TagClass as any as Mutable<TagClass<Self, Id, string, any, any, any, any, any>>
334
+ Object.setPrototypeOf(TagClass, Object.getPrototypeOf(Context.GenericTag<Self, any>(id)))
335
+ TagClass.key = id
336
+ Object.defineProperty(TagClass, "stack", {
337
+ get() {
338
+ return creationError.stack
339
+ }
340
+ })
341
+ TagClass_.get = (key: string) => Effect.flatMap(TagClass_, (layerMap) => layerMap.get(key))
342
+ TagClass_.provide = (key: string) => (effect) =>
343
+ Effect.flatMap(TagClass_, (layerMap) => layerMap.provide(key)(effect))
344
+ TagClass_.invalidate = (key: string) => Effect.flatMap(TagClass_, (layerMap) => layerMap.invalidate(key))
345
+
346
+ TagClass_.DefaultWithoutDependencies = Layer.scoped(
347
+ TagClass_,
348
+ "lookup" in options
349
+ ? make(options.provides, options.lookup, options)
350
+ : fromRecord(options.provides, options.layers as any, options)
351
+ )
352
+ TagClass_.Default = options.dependencies && options.dependencies.length > 0 ?
353
+ Layer.provide(TagClass_.DefaultWithoutDependencies, options.dependencies as any) :
354
+ TagClass_.DefaultWithoutDependencies
355
+
356
+ return TagClass as any
357
+ }
358
+
359
+ /**
360
+ * @since 3.14.0
361
+ * @category Service
362
+ * @experimental
363
+ */
364
+ export declare namespace Service {
365
+ /**
366
+ * @since 3.14.0
367
+ * @category Service
368
+ * @experimental
369
+ */
370
+ export type Key<Options> = Options extends { readonly lookup: (key: infer K) => any } ? K
371
+ : Options extends { readonly layers: infer Layers } ? keyof Layers
372
+ : never
373
+
374
+ /**
375
+ * @since 3.14.0
376
+ * @category Service
377
+ * @experimental
378
+ */
379
+ export type Layers<Options> = Options extends { readonly lookup: (key: infer _K) => infer Layers } ? Layers
380
+ : Options extends { readonly layers: infer Layers } ? Layers[keyof Layers]
381
+ : never
382
+
383
+ /**
384
+ * @since 3.14.0
385
+ * @category Service
386
+ * @experimental
387
+ */
388
+ export type Error<Options> = Layers<Options> extends Layer.Layer<infer _A, infer _E, infer _R> ? _E : never
389
+
390
+ /**
391
+ * @since 3.14.0
392
+ * @category Service
393
+ * @experimental
394
+ */
395
+ export type Context<Options> = Layers<Options> extends Layer.Layer<infer _A, infer _E, infer _R> ? _R : never
396
+ }
@@ -180,13 +180,29 @@ export const get: {
180
180
  * @category elements
181
181
  */
182
182
  export const keys = <K, V>(self: MutableHashMap<K, V>): Array<K> => {
183
- const keys: Array<K> = []
184
- for (const [key] of self) {
185
- keys.push(key)
183
+ const keys = Array.from(self.referential.keys())
184
+ for (const bucket of self.buckets.values()) {
185
+ for (let i = 0, len = bucket.length; i < len; i++) {
186
+ keys.push(bucket[i][0])
187
+ }
186
188
  }
187
189
  return keys
188
190
  }
189
191
 
192
+ /**
193
+ * @since 3.8.0
194
+ * @category elements
195
+ */
196
+ export const values = <K, V>(self: MutableHashMap<K, V>): Array<V> => {
197
+ const values = Array.from(self.referential.values())
198
+ for (const bucket of self.buckets.values()) {
199
+ for (let i = 0, len = bucket.length; i < len; i++) {
200
+ values.push(bucket[i][1])
201
+ }
202
+ }
203
+ return values
204
+ }
205
+
190
206
  const getFromBucket = <K, V>(
191
207
  self: MutableHashMap<K, V>,
192
208
  bucket: NonEmptyArray<readonly [K & Equal.Equal, V]>,
@@ -474,3 +490,29 @@ export const clear = <K, V>(self: MutableHashMap<K, V>) => {
474
490
  export const size = <K, V>(self: MutableHashMap<K, V>): number => {
475
491
  return self.referential.size + self.bucketsSize
476
492
  }
493
+
494
+ /**
495
+ * @since 2.0.0
496
+ */
497
+ export const isEmpty = <K, V>(self: MutableHashMap<K, V>): boolean => size(self) === 0
498
+
499
+ /**
500
+ * @since 2.0.0
501
+ */
502
+ export const forEach: {
503
+ /**
504
+ * @since 2.0.0
505
+ */
506
+ <K, V>(f: (value: V, key: K) => void): (self: MutableHashMap<K, V>) => void
507
+ /**
508
+ * @since 2.0.0
509
+ */
510
+ <K, V>(self: MutableHashMap<K, V>, f: (value: V, key: K) => void): void
511
+ } = dual(2, <K, V>(self: MutableHashMap<K, V>, f: (value: V, key: K) => void) => {
512
+ self.referential.forEach(f)
513
+ for (const bucket of self.buckets.values()) {
514
+ for (const [key, value] of bucket) {
515
+ f(value, key)
516
+ }
517
+ }
518
+ })
package/src/MutableRef.ts CHANGED
@@ -21,8 +21,6 @@ export type TypeId = typeof TypeId
21
21
  */
22
22
  export interface MutableRef<out T> extends Pipeable, Inspectable {
23
23
  readonly [TypeId]: TypeId
24
-
25
- /** @internal */
26
24
  current: T
27
25
  }
28
26
 
package/src/Runtime.ts CHANGED
@@ -81,9 +81,28 @@ export interface RunForkOptions {
81
81
  * @since 2.0.0
82
82
  * @category execution
83
83
  */
84
- export const runFork: <R>(
85
- runtime: Runtime<R>
86
- ) => <A, E>(self: Effect.Effect<A, E, R>, options?: RunForkOptions) => Fiber.RuntimeFiber<A, E> = internal.unsafeFork
84
+ export const runFork: {
85
+ /**
86
+ * Executes the effect using the provided Scheduler or using the global
87
+ * Scheduler if not provided
88
+ *
89
+ * @since 2.0.0
90
+ * @category execution
91
+ */
92
+ <R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>, options?: RunForkOptions | undefined) => Fiber.RuntimeFiber<A, E>
93
+ /**
94
+ * Executes the effect using the provided Scheduler or using the global
95
+ * Scheduler if not provided
96
+ *
97
+ * @since 2.0.0
98
+ * @category execution
99
+ */
100
+ <R, A, E>(
101
+ runtime: Runtime<R>,
102
+ effect: Effect.Effect<A, E, R>,
103
+ options?: RunForkOptions | undefined
104
+ ): Fiber.RuntimeFiber<A, E>
105
+ } = internal.unsafeFork
87
106
 
88
107
  /**
89
108
  * Executes the effect synchronously returning the exit.
@@ -94,8 +113,28 @@ export const runFork: <R>(
94
113
  * @since 2.0.0
95
114
  * @category execution
96
115
  */
97
- export const runSyncExit: <R>(runtime: Runtime<R>) => <A, E>(effect: Effect.Effect<A, E, R>) => Exit.Exit<A, E> =
98
- internal.unsafeRunSyncExit
116
+ export const runSyncExit: {
117
+ /**
118
+ * Executes the effect synchronously returning the exit.
119
+ *
120
+ * This method is effectful and should only be invoked at the edges of your
121
+ * program.
122
+ *
123
+ * @since 2.0.0
124
+ * @category execution
125
+ */
126
+ <A, E, R>(runtime: Runtime<R>, effect: Effect.Effect<A, E, R>): Exit.Exit<A, E>
127
+ /**
128
+ * Executes the effect synchronously returning the exit.
129
+ *
130
+ * This method is effectful and should only be invoked at the edges of your
131
+ * program.
132
+ *
133
+ * @since 2.0.0
134
+ * @category execution
135
+ */
136
+ <R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>) => Exit.Exit<A, E>
137
+ } = internal.unsafeRunSyncExit
99
138
 
100
139
  /**
101
140
  * Executes the effect synchronously throwing in case of errors or async boundaries.
@@ -106,7 +145,28 @@ export const runSyncExit: <R>(runtime: Runtime<R>) => <A, E>(effect: Effect.Effe
106
145
  * @since 2.0.0
107
146
  * @category execution
108
147
  */
109
- export const runSync: <R>(runtime: Runtime<R>) => <A, E>(effect: Effect.Effect<A, E, R>) => A = internal.unsafeRunSync
148
+ export const runSync: {
149
+ /**
150
+ * Executes the effect synchronously throwing in case of errors or async boundaries.
151
+ *
152
+ * This method is effectful and should only be invoked at the edges of your
153
+ * program.
154
+ *
155
+ * @since 2.0.0
156
+ * @category execution
157
+ */
158
+ <A, E, R>(runtime: Runtime<R>, effect: Effect.Effect<A, E, R>): A
159
+ /**
160
+ * Executes the effect synchronously throwing in case of errors or async boundaries.
161
+ *
162
+ * This method is effectful and should only be invoked at the edges of your
163
+ * program.
164
+ *
165
+ * @since 2.0.0
166
+ * @category execution
167
+ */
168
+ <R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>) => A
169
+ } = internal.unsafeRunSync
110
170
 
111
171
  /**
112
172
  * @since 2.0.0
@@ -126,10 +186,37 @@ export interface RunCallbackOptions<in A, in E = never> extends RunForkOptions {
126
186
  * @since 2.0.0
127
187
  * @category execution
128
188
  */
129
- export const runCallback: <R>(
130
- runtime: Runtime<R>
131
- ) => <A, E>(effect: Effect.Effect<A, E, R>, options?: RunCallbackOptions<A, E> | undefined) => Cancel<A, E> =
132
- internal.unsafeRunCallback
189
+ export const runCallback: {
190
+ /**
191
+ * Executes the effect asynchronously, eventually passing the exit value to
192
+ * the specified callback.
193
+ *
194
+ * This method is effectful and should only be invoked at the edges of your
195
+ * program.
196
+ *
197
+ * @since 2.0.0
198
+ * @category execution
199
+ */
200
+ <R>(runtime: Runtime<R>): <A, E>(
201
+ effect: Effect.Effect<A, E, R>,
202
+ options?: RunCallbackOptions<A, E> | undefined
203
+ ) => (fiberId?: FiberId.FiberId, options?: RunCallbackOptions<A, E> | undefined) => void
204
+ /**
205
+ * Executes the effect asynchronously, eventually passing the exit value to
206
+ * the specified callback.
207
+ *
208
+ * This method is effectful and should only be invoked at the edges of your
209
+ * program.
210
+ *
211
+ * @since 2.0.0
212
+ * @category execution
213
+ */
214
+ <R, A, E>(
215
+ runtime: Runtime<R>,
216
+ effect: Effect.Effect<A, E, R>,
217
+ options?: RunCallbackOptions<A, E> | undefined
218
+ ): (fiberId?: FiberId.FiberId, options?: RunCallbackOptions<A, E> | undefined) => void
219
+ } = internal.unsafeRunCallback
133
220
 
134
221
  /**
135
222
  * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
@@ -142,10 +229,36 @@ export const runCallback: <R>(
142
229
  * @since 2.0.0
143
230
  * @category execution
144
231
  */
145
- export const runPromise: <R>(
146
- runtime: Runtime<R>
147
- ) => <A, E>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal } | undefined) => Promise<A> =
148
- internal.unsafeRunPromise
232
+ export const runPromise: {
233
+ /**
234
+ * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
235
+ * with the value of the effect once the effect has been executed, or will be
236
+ * rejected with the first error or exception throw by the effect.
237
+ *
238
+ * This method is effectful and should only be used at the edges of your
239
+ * program.
240
+ *
241
+ * @since 2.0.0
242
+ * @category execution
243
+ */
244
+ <R>(runtime: Runtime<R>): <A, E>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal } | undefined) => Promise<A>
245
+ /**
246
+ * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
247
+ * with the value of the effect once the effect has been executed, or will be
248
+ * rejected with the first error or exception throw by the effect.
249
+ *
250
+ * This method is effectful and should only be used at the edges of your
251
+ * program.
252
+ *
253
+ * @since 2.0.0
254
+ * @category execution
255
+ */
256
+ <R, A, E>(
257
+ runtime: Runtime<R>,
258
+ effect: Effect.Effect<A, E, R>,
259
+ options?: { readonly signal?: AbortSignal } | undefined
260
+ ): Promise<A>
261
+ } = internal.unsafeRunPromise
149
262
 
150
263
  /**
151
264
  * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
@@ -157,12 +270,37 @@ export const runPromise: <R>(
157
270
  * @since 2.0.0
158
271
  * @category execution
159
272
  */
160
- export const runPromiseExit: <R>(
161
- runtime: Runtime<R>
162
- ) => <A, E>(
163
- effect: Effect.Effect<A, E, R>,
164
- options?: { readonly signal?: AbortSignal } | undefined
165
- ) => Promise<Exit.Exit<A, E>> = internal.unsafeRunPromiseExit
273
+ export const runPromiseExit: {
274
+ /**
275
+ * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
276
+ * with the `Exit` state of the effect once the effect has been executed.
277
+ *
278
+ * This method is effectful and should only be used at the edges of your
279
+ * program.
280
+ *
281
+ * @since 2.0.0
282
+ * @category execution
283
+ */
284
+ <R>(runtime: Runtime<R>): <A, E>(
285
+ effect: Effect.Effect<A, E, R>,
286
+ options?: { readonly signal?: AbortSignal } | undefined
287
+ ) => Promise<Exit.Exit<A, E>>
288
+ /**
289
+ * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
290
+ * with the `Exit` state of the effect once the effect has been executed.
291
+ *
292
+ * This method is effectful and should only be used at the edges of your
293
+ * program.
294
+ *
295
+ * @since 2.0.0
296
+ * @category execution
297
+ */
298
+ <R, A, E>(
299
+ runtime: Runtime<R>,
300
+ effect: Effect.Effect<A, E, R>,
301
+ options?: { readonly signal?: AbortSignal } | undefined
302
+ ): Promise<Exit.Exit<A, E>>
303
+ } = internal.unsafeRunPromiseExit
166
304
 
167
305
  /**
168
306
  * @since 2.0.0