effect 3.13.11 → 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 (176) 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/JSONSchema.js +6 -1
  15. package/dist/cjs/JSONSchema.js.map +1 -1
  16. package/dist/cjs/Layer.js +6 -1
  17. package/dist/cjs/Layer.js.map +1 -1
  18. package/dist/cjs/LayerMap.js +183 -0
  19. package/dist/cjs/LayerMap.js.map +1 -0
  20. package/dist/cjs/MutableHashMap.js +36 -4
  21. package/dist/cjs/MutableHashMap.js.map +1 -1
  22. package/dist/cjs/MutableRef.js.map +1 -1
  23. package/dist/cjs/Runtime.js.map +1 -1
  24. package/dist/cjs/Schema.js +2 -2
  25. package/dist/cjs/Schema.js.map +1 -1
  26. package/dist/cjs/SchemaAST.js +37 -33
  27. package/dist/cjs/SchemaAST.js.map +1 -1
  28. package/dist/cjs/TestClock.js +3 -2
  29. package/dist/cjs/TestClock.js.map +1 -1
  30. package/dist/cjs/Tracer.js.map +1 -1
  31. package/dist/cjs/index.js +4 -2
  32. package/dist/cjs/index.js.map +1 -1
  33. package/dist/cjs/internal/channel/channelExecutor.js +6 -1
  34. package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
  35. package/dist/cjs/internal/core-effect.js +13 -2
  36. package/dist/cjs/internal/core-effect.js.map +1 -1
  37. package/dist/cjs/internal/core.js +2 -1
  38. package/dist/cjs/internal/core.js.map +1 -1
  39. package/dist/cjs/internal/dateTime.js +3 -1
  40. package/dist/cjs/internal/dateTime.js.map +1 -1
  41. package/dist/cjs/internal/effect/circular.js +5 -0
  42. package/dist/cjs/internal/effect/circular.js.map +1 -1
  43. package/dist/cjs/internal/hashMap.js +3 -1
  44. package/dist/cjs/internal/hashMap.js.map +1 -1
  45. package/dist/cjs/internal/layer.js +7 -3
  46. package/dist/cjs/internal/layer.js.map +1 -1
  47. package/dist/cjs/internal/rcMap.js +11 -1
  48. package/dist/cjs/internal/rcMap.js.map +1 -1
  49. package/dist/cjs/internal/runtime.js +21 -21
  50. package/dist/cjs/internal/runtime.js.map +1 -1
  51. package/dist/cjs/internal/schema/errors.js +1 -4
  52. package/dist/cjs/internal/schema/errors.js.map +1 -1
  53. package/dist/cjs/internal/tracer.js +6 -2
  54. package/dist/cjs/internal/tracer.js.map +1 -1
  55. package/dist/cjs/internal/version.js +1 -1
  56. package/dist/cjs/internal/version.js.map +1 -1
  57. package/dist/dts/Array.d.ts +58 -0
  58. package/dist/dts/Array.d.ts.map +1 -1
  59. package/dist/dts/Data.d.ts +4 -4
  60. package/dist/dts/Data.d.ts.map +1 -1
  61. package/dist/dts/DateTime.d.ts +15 -0
  62. package/dist/dts/DateTime.d.ts.map +1 -1
  63. package/dist/dts/Effect.d.ts +66 -0
  64. package/dist/dts/Effect.d.ts.map +1 -1
  65. package/dist/dts/Either.d.ts +30 -0
  66. package/dist/dts/Either.d.ts.map +1 -1
  67. package/dist/dts/FiberSet.d.ts.map +1 -1
  68. package/dist/dts/HashMap.d.ts +31 -0
  69. package/dist/dts/HashMap.d.ts.map +1 -1
  70. package/dist/dts/Layer.d.ts +12 -0
  71. package/dist/dts/Layer.d.ts.map +1 -1
  72. package/dist/dts/LayerMap.d.ts +242 -0
  73. package/dist/dts/LayerMap.d.ts.map +1 -0
  74. package/dist/dts/MutableHashMap.d.ts +22 -0
  75. package/dist/dts/MutableHashMap.d.ts.map +1 -1
  76. package/dist/dts/MutableRef.d.ts +1 -0
  77. package/dist/dts/MutableRef.d.ts.map +1 -1
  78. package/dist/dts/Runtime.d.ts +144 -10
  79. package/dist/dts/Runtime.d.ts.map +1 -1
  80. package/dist/dts/SchemaAST.d.ts +1 -1
  81. package/dist/dts/SchemaAST.d.ts.map +1 -1
  82. package/dist/dts/TestClock.d.ts +3 -2
  83. package/dist/dts/TestClock.d.ts.map +1 -1
  84. package/dist/dts/Tracer.d.ts +1 -0
  85. package/dist/dts/Tracer.d.ts.map +1 -1
  86. package/dist/dts/index.d.ts +4 -0
  87. package/dist/dts/index.d.ts.map +1 -1
  88. package/dist/dts/internal/channel/channelExecutor.d.ts.map +1 -1
  89. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  90. package/dist/dts/internal/layer.d.ts.map +1 -1
  91. package/dist/esm/Array.js +28 -1
  92. package/dist/esm/Array.js.map +1 -1
  93. package/dist/esm/DateTime.js +15 -0
  94. package/dist/esm/DateTime.js.map +1 -1
  95. package/dist/esm/Effect.js +42 -0
  96. package/dist/esm/Effect.js.map +1 -1
  97. package/dist/esm/Either.js +33 -0
  98. package/dist/esm/Either.js.map +1 -1
  99. package/dist/esm/FiberSet.js +13 -1
  100. package/dist/esm/FiberSet.js.map +1 -1
  101. package/dist/esm/HashMap.js +10 -0
  102. package/dist/esm/HashMap.js.map +1 -1
  103. package/dist/esm/JSONSchema.js +6 -1
  104. package/dist/esm/JSONSchema.js.map +1 -1
  105. package/dist/esm/Layer.js +5 -0
  106. package/dist/esm/Layer.js.map +1 -1
  107. package/dist/esm/LayerMap.js +172 -0
  108. package/dist/esm/LayerMap.js.map +1 -0
  109. package/dist/esm/MutableHashMap.js +33 -3
  110. package/dist/esm/MutableHashMap.js.map +1 -1
  111. package/dist/esm/MutableRef.js.map +1 -1
  112. package/dist/esm/Runtime.js.map +1 -1
  113. package/dist/esm/Schema.js +2 -2
  114. package/dist/esm/Schema.js.map +1 -1
  115. package/dist/esm/SchemaAST.js +31 -27
  116. package/dist/esm/SchemaAST.js.map +1 -1
  117. package/dist/esm/TestClock.js +3 -2
  118. package/dist/esm/TestClock.js.map +1 -1
  119. package/dist/esm/Tracer.js.map +1 -1
  120. package/dist/esm/index.js +4 -0
  121. package/dist/esm/index.js.map +1 -1
  122. package/dist/esm/internal/channel/channelExecutor.js +6 -1
  123. package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
  124. package/dist/esm/internal/core-effect.js +10 -0
  125. package/dist/esm/internal/core-effect.js.map +1 -1
  126. package/dist/esm/internal/core.js +2 -1
  127. package/dist/esm/internal/core.js.map +1 -1
  128. package/dist/esm/internal/dateTime.js +2 -0
  129. package/dist/esm/internal/dateTime.js.map +1 -1
  130. package/dist/esm/internal/effect/circular.js +5 -0
  131. package/dist/esm/internal/effect/circular.js.map +1 -1
  132. package/dist/esm/internal/hashMap.js +2 -0
  133. package/dist/esm/internal/hashMap.js.map +1 -1
  134. package/dist/esm/internal/layer.js +6 -2
  135. package/dist/esm/internal/layer.js.map +1 -1
  136. package/dist/esm/internal/rcMap.js +11 -1
  137. package/dist/esm/internal/rcMap.js.map +1 -1
  138. package/dist/esm/internal/runtime.js +21 -15
  139. package/dist/esm/internal/runtime.js.map +1 -1
  140. package/dist/esm/internal/schema/errors.js +0 -2
  141. package/dist/esm/internal/schema/errors.js.map +1 -1
  142. package/dist/esm/internal/tracer.js +6 -2
  143. package/dist/esm/internal/tracer.js.map +1 -1
  144. package/dist/esm/internal/version.js +1 -1
  145. package/dist/esm/internal/version.js.map +1 -1
  146. package/package.json +9 -1
  147. package/src/Array.ts +69 -1
  148. package/src/Data.ts +4 -4
  149. package/src/DateTime.ts +16 -0
  150. package/src/Effect.ts +143 -0
  151. package/src/Either.ts +36 -0
  152. package/src/FiberSet.ts +14 -1
  153. package/src/HashMap.ts +32 -0
  154. package/src/JSONSchema.ts +6 -2
  155. package/src/Layer.ts +14 -0
  156. package/src/LayerMap.ts +396 -0
  157. package/src/MutableHashMap.ts +45 -3
  158. package/src/MutableRef.ts +0 -2
  159. package/src/Runtime.ts +158 -20
  160. package/src/Schema.ts +2 -2
  161. package/src/SchemaAST.ts +45 -30
  162. package/src/TestClock.ts +10 -3
  163. package/src/Tracer.ts +1 -0
  164. package/src/index.ts +5 -0
  165. package/src/internal/channel/channelExecutor.ts +11 -4
  166. package/src/internal/core-effect.ts +15 -0
  167. package/src/internal/core.ts +2 -1
  168. package/src/internal/dateTime.ts +3 -0
  169. package/src/internal/effect/circular.ts +5 -0
  170. package/src/internal/hashMap.ts +9 -0
  171. package/src/internal/layer.ts +14 -2
  172. package/src/internal/rcMap.ts +13 -3
  173. package/src/internal/runtime.ts +104 -38
  174. package/src/internal/schema/errors.ts +0 -6
  175. package/src/internal/tracer.ts +8 -1
  176. package/src/internal/version.ts +1 -1
package/src/Layer.ts CHANGED
@@ -133,6 +133,20 @@ export interface MemoMap {
133
133
  ) => Effect.Effect<Context.Context<ROut>, E, RIn>
134
134
  }
135
135
 
136
+ /**
137
+ * @since 3.13.0
138
+ * @category models
139
+ */
140
+ export interface CurrentMemoMap {
141
+ readonly _: unique symbol
142
+ }
143
+
144
+ /**
145
+ * @since 3.13.0
146
+ * @category models
147
+ */
148
+ export const CurrentMemoMap: Context.Reference<CurrentMemoMap, MemoMap> = internal.CurrentMemoMap
149
+
136
150
  /**
137
151
  * Returns `true` if the specified value is a `Layer`, `false` otherwise.
138
152
  *
@@ -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