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.
- package/LayerMap/package.json +6 -0
- package/dist/cjs/Array.js +29 -2
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/DateTime.js +16 -1
- package/dist/cjs/DateTime.js.map +1 -1
- package/dist/cjs/Effect.js +45 -3
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Either.js +35 -1
- package/dist/cjs/Either.js.map +1 -1
- package/dist/cjs/FiberSet.js +14 -2
- package/dist/cjs/FiberSet.js.map +1 -1
- package/dist/cjs/HashMap.js +11 -1
- package/dist/cjs/HashMap.js.map +1 -1
- package/dist/cjs/JSONSchema.js +6 -1
- package/dist/cjs/JSONSchema.js.map +1 -1
- package/dist/cjs/Layer.js +6 -1
- package/dist/cjs/Layer.js.map +1 -1
- package/dist/cjs/LayerMap.js +183 -0
- package/dist/cjs/LayerMap.js.map +1 -0
- package/dist/cjs/MutableHashMap.js +36 -4
- package/dist/cjs/MutableHashMap.js.map +1 -1
- package/dist/cjs/MutableRef.js.map +1 -1
- package/dist/cjs/Runtime.js.map +1 -1
- package/dist/cjs/Schema.js +2 -2
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/SchemaAST.js +37 -33
- package/dist/cjs/SchemaAST.js.map +1 -1
- package/dist/cjs/TestClock.js +3 -2
- package/dist/cjs/TestClock.js.map +1 -1
- package/dist/cjs/Tracer.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/channel/channelExecutor.js +6 -1
- package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
- package/dist/cjs/internal/core-effect.js +13 -2
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/core.js +2 -1
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/dateTime.js +3 -1
- package/dist/cjs/internal/dateTime.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +5 -0
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/hashMap.js +3 -1
- package/dist/cjs/internal/hashMap.js.map +1 -1
- package/dist/cjs/internal/layer.js +7 -3
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/rcMap.js +11 -1
- package/dist/cjs/internal/rcMap.js.map +1 -1
- package/dist/cjs/internal/runtime.js +21 -21
- package/dist/cjs/internal/runtime.js.map +1 -1
- package/dist/cjs/internal/schema/errors.js +1 -4
- package/dist/cjs/internal/schema/errors.js.map +1 -1
- package/dist/cjs/internal/tracer.js +6 -2
- package/dist/cjs/internal/tracer.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/Array.d.ts +58 -0
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/Data.d.ts +4 -4
- package/dist/dts/Data.d.ts.map +1 -1
- package/dist/dts/DateTime.d.ts +15 -0
- package/dist/dts/DateTime.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +66 -0
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Either.d.ts +30 -0
- package/dist/dts/Either.d.ts.map +1 -1
- package/dist/dts/FiberSet.d.ts.map +1 -1
- package/dist/dts/HashMap.d.ts +31 -0
- package/dist/dts/HashMap.d.ts.map +1 -1
- package/dist/dts/Layer.d.ts +12 -0
- package/dist/dts/Layer.d.ts.map +1 -1
- package/dist/dts/LayerMap.d.ts +242 -0
- package/dist/dts/LayerMap.d.ts.map +1 -0
- package/dist/dts/MutableHashMap.d.ts +22 -0
- package/dist/dts/MutableHashMap.d.ts.map +1 -1
- package/dist/dts/MutableRef.d.ts +1 -0
- package/dist/dts/MutableRef.d.ts.map +1 -1
- package/dist/dts/Runtime.d.ts +144 -10
- package/dist/dts/Runtime.d.ts.map +1 -1
- package/dist/dts/SchemaAST.d.ts +1 -1
- package/dist/dts/SchemaAST.d.ts.map +1 -1
- package/dist/dts/TestClock.d.ts +3 -2
- package/dist/dts/TestClock.d.ts.map +1 -1
- package/dist/dts/Tracer.d.ts +1 -0
- package/dist/dts/Tracer.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/channel/channelExecutor.d.ts.map +1 -1
- package/dist/dts/internal/core-effect.d.ts.map +1 -1
- package/dist/dts/internal/layer.d.ts.map +1 -1
- package/dist/esm/Array.js +28 -1
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/DateTime.js +15 -0
- package/dist/esm/DateTime.js.map +1 -1
- package/dist/esm/Effect.js +42 -0
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Either.js +33 -0
- package/dist/esm/Either.js.map +1 -1
- package/dist/esm/FiberSet.js +13 -1
- package/dist/esm/FiberSet.js.map +1 -1
- package/dist/esm/HashMap.js +10 -0
- package/dist/esm/HashMap.js.map +1 -1
- package/dist/esm/JSONSchema.js +6 -1
- package/dist/esm/JSONSchema.js.map +1 -1
- package/dist/esm/Layer.js +5 -0
- package/dist/esm/Layer.js.map +1 -1
- package/dist/esm/LayerMap.js +172 -0
- package/dist/esm/LayerMap.js.map +1 -0
- package/dist/esm/MutableHashMap.js +33 -3
- package/dist/esm/MutableHashMap.js.map +1 -1
- package/dist/esm/MutableRef.js.map +1 -1
- package/dist/esm/Runtime.js.map +1 -1
- package/dist/esm/Schema.js +2 -2
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/SchemaAST.js +31 -27
- package/dist/esm/SchemaAST.js.map +1 -1
- package/dist/esm/TestClock.js +3 -2
- package/dist/esm/TestClock.js.map +1 -1
- package/dist/esm/Tracer.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/channel/channelExecutor.js +6 -1
- package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
- package/dist/esm/internal/core-effect.js +10 -0
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/core.js +2 -1
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/dateTime.js +2 -0
- package/dist/esm/internal/dateTime.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +5 -0
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/hashMap.js +2 -0
- package/dist/esm/internal/hashMap.js.map +1 -1
- package/dist/esm/internal/layer.js +6 -2
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/rcMap.js +11 -1
- package/dist/esm/internal/rcMap.js.map +1 -1
- package/dist/esm/internal/runtime.js +21 -15
- package/dist/esm/internal/runtime.js.map +1 -1
- package/dist/esm/internal/schema/errors.js +0 -2
- package/dist/esm/internal/schema/errors.js.map +1 -1
- package/dist/esm/internal/tracer.js +6 -2
- package/dist/esm/internal/tracer.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +9 -1
- package/src/Array.ts +69 -1
- package/src/Data.ts +4 -4
- package/src/DateTime.ts +16 -0
- package/src/Effect.ts +143 -0
- package/src/Either.ts +36 -0
- package/src/FiberSet.ts +14 -1
- package/src/HashMap.ts +32 -0
- package/src/JSONSchema.ts +6 -2
- package/src/Layer.ts +14 -0
- package/src/LayerMap.ts +396 -0
- package/src/MutableHashMap.ts +45 -3
- package/src/MutableRef.ts +0 -2
- package/src/Runtime.ts +158 -20
- package/src/Schema.ts +2 -2
- package/src/SchemaAST.ts +45 -30
- package/src/TestClock.ts +10 -3
- package/src/Tracer.ts +1 -0
- package/src/index.ts +5 -0
- package/src/internal/channel/channelExecutor.ts +11 -4
- package/src/internal/core-effect.ts +15 -0
- package/src/internal/core.ts +2 -1
- package/src/internal/dateTime.ts +3 -0
- package/src/internal/effect/circular.ts +5 -0
- package/src/internal/hashMap.ts +9 -0
- package/src/internal/layer.ts +14 -2
- package/src/internal/rcMap.ts +13 -3
- package/src/internal/runtime.ts +104 -38
- package/src/internal/schema/errors.ts +0 -6
- package/src/internal/tracer.ts +8 -1
- 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
|
*
|
package/src/LayerMap.ts
ADDED
|
@@ -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
|
+
}
|
package/src/MutableHashMap.ts
CHANGED
|
@@ -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
|
|
184
|
-
for (const
|
|
185
|
-
|
|
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
|
+
})
|