effect 2.4.0 → 2.4.2
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/dist/cjs/Context.js.map +1 -1
- package/dist/cjs/Duration.js +9 -1
- package/dist/cjs/Duration.js.map +1 -1
- package/dist/cjs/Effect.js +83 -5
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Either.js.map +1 -1
- package/dist/cjs/FiberMap.js +31 -5
- package/dist/cjs/FiberMap.js.map +1 -1
- package/dist/cjs/FiberSet.js +31 -5
- package/dist/cjs/FiberSet.js.map +1 -1
- package/dist/cjs/Logger.js +50 -1
- package/dist/cjs/Logger.js.map +1 -1
- package/dist/cjs/Option.js.map +1 -1
- package/dist/cjs/Predicate.js +40 -3
- package/dist/cjs/Predicate.js.map +1 -1
- package/dist/cjs/Request.js +4 -4
- package/dist/cjs/SortedSet.js +7 -1
- package/dist/cjs/SortedSet.js.map +1 -1
- package/dist/cjs/Struct.js +7 -6
- package/dist/cjs/Struct.js.map +1 -1
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +26 -1
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/logger.js +64 -2
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Context.d.ts +10 -11
- package/dist/dts/Context.d.ts.map +1 -1
- package/dist/dts/Duration.d.ts +1 -1
- package/dist/dts/Duration.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +55 -15
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Either.d.ts +18 -3
- package/dist/dts/Either.d.ts.map +1 -1
- package/dist/dts/FiberMap.d.ts +22 -2
- package/dist/dts/FiberMap.d.ts.map +1 -1
- package/dist/dts/FiberSet.d.ts +20 -0
- package/dist/dts/FiberSet.d.ts.map +1 -1
- package/dist/dts/Logger.d.ts +61 -0
- package/dist/dts/Logger.d.ts.map +1 -1
- package/dist/dts/Option.d.ts +13 -3
- package/dist/dts/Option.d.ts.map +1 -1
- package/dist/dts/Predicate.d.ts +37 -2
- package/dist/dts/Predicate.d.ts.map +1 -1
- package/dist/dts/Request.d.ts +7 -7
- package/dist/dts/Request.d.ts.map +1 -1
- package/dist/dts/STM.d.ts +1 -1
- package/dist/dts/STM.d.ts.map +1 -1
- package/dist/dts/SortedSet.d.ts +6 -0
- package/dist/dts/SortedSet.d.ts.map +1 -1
- package/dist/dts/Struct.d.ts +18 -2
- package/dist/dts/Struct.d.ts.map +1 -1
- package/dist/dts/Types.d.ts +4 -0
- package/dist/dts/Types.d.ts.map +1 -1
- package/dist/dts/internal/logger.d.ts +1 -0
- package/dist/dts/internal/logger.d.ts.map +1 -1
- package/dist/esm/Context.js.map +1 -1
- package/dist/esm/Duration.js +9 -1
- package/dist/esm/Duration.js.map +1 -1
- package/dist/esm/Effect.js +78 -1
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Either.js.map +1 -1
- package/dist/esm/FiberMap.js +29 -4
- package/dist/esm/FiberMap.js.map +1 -1
- package/dist/esm/FiberSet.js +29 -4
- package/dist/esm/FiberSet.js.map +1 -1
- package/dist/esm/Logger.js +49 -0
- package/dist/esm/Logger.js.map +1 -1
- package/dist/esm/Option.js.map +1 -1
- package/dist/esm/Predicate.js +37 -2
- package/dist/esm/Predicate.js.map +1 -1
- package/dist/esm/Request.js +4 -4
- package/dist/esm/SortedSet.js +5 -0
- package/dist/esm/SortedSet.js.map +1 -1
- package/dist/esm/Struct.js +7 -4
- package/dist/esm/Struct.js.map +1 -1
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +25 -0
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/logger.js +61 -1
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +2 -2
- package/src/Context.ts +10 -11
- package/src/Duration.ts +17 -1
- package/src/Effect.ts +124 -22
- package/src/Either.ts +19 -3
- package/src/FiberMap.ts +44 -6
- package/src/FiberSet.ts +38 -4
- package/src/Logger.ts +77 -0
- package/src/Option.ts +14 -3
- package/src/Predicate.ts +39 -2
- package/src/Request.ts +7 -7
- package/src/STM.ts +1 -1
- package/src/SortedSet.ts +7 -0
- package/src/Struct.ts +40 -21
- package/src/Types.ts +5 -0
- package/src/internal/core-effect.ts +9 -9
- package/src/internal/core.ts +5 -5
- package/src/internal/fiberRuntime.ts +68 -0
- package/src/internal/logger.ts +76 -1
- package/src/internal/request.ts +2 -2
- package/src/internal/version.ts +1 -1
package/src/Logger.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @since 2.0.0
|
|
3
3
|
*/
|
|
4
4
|
import type * as Cause from "./Cause.js"
|
|
5
|
+
import type { DurationInput } from "./Duration.js"
|
|
5
6
|
import type { Effect } from "./Effect.js"
|
|
6
7
|
import type * as FiberId from "./FiberId.js"
|
|
7
8
|
import type * as FiberRefs from "./FiberRefs.js"
|
|
@@ -158,6 +159,39 @@ export const map: {
|
|
|
158
159
|
): Logger<Message, Output2>
|
|
159
160
|
} = internal.map
|
|
160
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @since 2.0.0
|
|
164
|
+
* @category mapping
|
|
165
|
+
* @example
|
|
166
|
+
* import { Console, Effect, Logger } from "effect";
|
|
167
|
+
*
|
|
168
|
+
* const LoggerLive = Logger.replaceScoped(
|
|
169
|
+
* Logger.defaultLogger,
|
|
170
|
+
* Logger.logfmtLogger.pipe(
|
|
171
|
+
* Logger.batched("500 millis", (messages) =>
|
|
172
|
+
* Console.log("BATCH", messages.join("\n"))
|
|
173
|
+
* )
|
|
174
|
+
* )
|
|
175
|
+
* );
|
|
176
|
+
*
|
|
177
|
+
* Effect.gen(function* (_) {
|
|
178
|
+
* yield* _(Effect.log("one"));
|
|
179
|
+
* yield* _(Effect.log("two"));
|
|
180
|
+
* yield* _(Effect.log("three"));
|
|
181
|
+
* }).pipe(Effect.provide(LoggerLive), Effect.runFork);
|
|
182
|
+
*/
|
|
183
|
+
export const batched: {
|
|
184
|
+
<Output, R>(
|
|
185
|
+
window: DurationInput,
|
|
186
|
+
f: (messages: Array<Types.NoInfer<Output>>) => Effect<void, never, R>
|
|
187
|
+
): <Message>(self: Logger<Message, Output>) => Effect<Logger<Message, void>, never, R | Scope>
|
|
188
|
+
<Message, Output, R>(
|
|
189
|
+
self: Logger<Message, Output>,
|
|
190
|
+
window: DurationInput,
|
|
191
|
+
f: (messages: Array<Types.NoInfer<Output>>) => Effect<void, never, R>
|
|
192
|
+
): Effect<Logger<Message, void>, never, Scope | R>
|
|
193
|
+
} = fiberRuntime.batchedLogger
|
|
194
|
+
|
|
161
195
|
/**
|
|
162
196
|
* A logger that does nothing in response to logging events.
|
|
163
197
|
*
|
|
@@ -298,6 +332,12 @@ export const zipRight: {
|
|
|
298
332
|
*/
|
|
299
333
|
export const defaultLogger: Logger<unknown, void> = fiberRuntime.defaultLogger
|
|
300
334
|
|
|
335
|
+
/**
|
|
336
|
+
* @since 2.0.0
|
|
337
|
+
* @category constructors
|
|
338
|
+
*/
|
|
339
|
+
export const jsonLogger: Logger<unknown, string> = internal.jsonLogger
|
|
340
|
+
|
|
301
341
|
/**
|
|
302
342
|
* @since 2.0.0
|
|
303
343
|
* @category constructors
|
|
@@ -310,20 +350,57 @@ export const logfmtLogger: Logger<unknown, string> = internal.logfmtLogger
|
|
|
310
350
|
*/
|
|
311
351
|
export const stringLogger: Logger<unknown, string> = internal.stringLogger
|
|
312
352
|
|
|
353
|
+
/**
|
|
354
|
+
* @since 2.0.0
|
|
355
|
+
* @category constructors
|
|
356
|
+
*/
|
|
357
|
+
export const structuredLogger: Logger<
|
|
358
|
+
unknown,
|
|
359
|
+
{
|
|
360
|
+
readonly logLevel: string
|
|
361
|
+
readonly fiberId: string
|
|
362
|
+
readonly timestamp: string
|
|
363
|
+
readonly message: unknown
|
|
364
|
+
readonly cause: string | undefined
|
|
365
|
+
readonly annotations: Record<string, unknown>
|
|
366
|
+
readonly spans: Record<string, number>
|
|
367
|
+
}
|
|
368
|
+
> = internal.structuredLogger
|
|
369
|
+
|
|
313
370
|
/**
|
|
314
371
|
* @since 2.0.0
|
|
315
372
|
* @category constructors
|
|
316
373
|
*/
|
|
317
374
|
export const tracerLogger: Logger<unknown, void> = fiberRuntime.tracerLogger
|
|
318
375
|
|
|
376
|
+
/**
|
|
377
|
+
* @since 2.0.0
|
|
378
|
+
* @category constructors
|
|
379
|
+
*/
|
|
380
|
+
export const json: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.jsonLogger)
|
|
381
|
+
|
|
319
382
|
/**
|
|
320
383
|
* @since 2.0.0
|
|
321
384
|
* @category constructors
|
|
322
385
|
*/
|
|
323
386
|
export const logFmt: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.logFmtLogger)
|
|
324
387
|
|
|
388
|
+
/**
|
|
389
|
+
* @since 2.0.0
|
|
390
|
+
* @category constructors
|
|
391
|
+
*/
|
|
392
|
+
export const structured: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.structuredLogger)
|
|
393
|
+
|
|
325
394
|
/**
|
|
326
395
|
* @since 2.0.0
|
|
327
396
|
* @category context
|
|
328
397
|
*/
|
|
329
398
|
export const minimumLogLevel: (level: LogLevel.LogLevel) => Layer.Layer<never> = circular.minimumLogLevel
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Returns `true` if the specified value is a `Logger`, otherwise returns `false`.
|
|
402
|
+
*
|
|
403
|
+
* @since 1.0.0
|
|
404
|
+
* @category guards
|
|
405
|
+
*/
|
|
406
|
+
export const isLogger: (u: unknown) => u is Logger<unknown, unknown> = internal.isLogger
|
package/src/Option.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type { Order } from "./Order.js"
|
|
|
14
14
|
import * as order from "./Order.js"
|
|
15
15
|
import type { Pipeable } from "./Pipeable.js"
|
|
16
16
|
import type { Predicate, Refinement } from "./Predicate.js"
|
|
17
|
-
import type { Covariant, NoInfer } from "./Types.js"
|
|
17
|
+
import type { Covariant, NoInfer, NotFunction } from "./Types.js"
|
|
18
18
|
import type * as Unify from "./Unify.js"
|
|
19
19
|
import * as Gen from "./Utils.js"
|
|
20
20
|
|
|
@@ -75,6 +75,17 @@ export interface OptionUnify<A extends { [Unify.typeSymbol]?: any }> {
|
|
|
75
75
|
Option?: () => A[Unify.typeSymbol] extends Option<infer A0> | infer _ ? Option<A0> : never
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* @since 2.0.0
|
|
80
|
+
*/
|
|
81
|
+
export declare namespace Option {
|
|
82
|
+
/**
|
|
83
|
+
* @since 2.0.0
|
|
84
|
+
* @category type-level
|
|
85
|
+
*/
|
|
86
|
+
export type Value<T extends Option<any>> = [T] extends [Option<infer _A>] ? _A : never
|
|
87
|
+
}
|
|
88
|
+
|
|
78
89
|
/**
|
|
79
90
|
* @category models
|
|
80
91
|
* @since 2.0.0
|
|
@@ -649,11 +660,11 @@ export const andThen: {
|
|
|
649
660
|
<A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>
|
|
650
661
|
<B>(f: Option<B>): <A>(self: Option<A>) => Option<B>
|
|
651
662
|
<A, B>(f: (a: A) => B): (self: Option<A>) => Option<B>
|
|
652
|
-
<B>(f: B): <A>(self: Option<A>) => Option<B>
|
|
663
|
+
<B>(f: NotFunction<B>): <A>(self: Option<A>) => Option<B>
|
|
653
664
|
<A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>
|
|
654
665
|
<A, B>(self: Option<A>, f: Option<B>): Option<B>
|
|
655
666
|
<A, B>(self: Option<A>, f: (a: A) => B): Option<B>
|
|
656
|
-
<A, B>(self: Option<A>, f: B): Option<B>
|
|
667
|
+
<A, B>(self: Option<A>, f: NotFunction<B>): Option<B>
|
|
657
668
|
} = dual(
|
|
658
669
|
2,
|
|
659
670
|
<A, B>(self: Option<A>, f: (a: A) => Option<B> | Option<B>): Option<B> =>
|
package/src/Predicate.ts
CHANGED
|
@@ -53,6 +53,43 @@ export const mapInput: {
|
|
|
53
53
|
<A, B>(self: Predicate<A>, f: (b: B) => A): Predicate<B>
|
|
54
54
|
} = dual(2, <A, B>(self: Predicate<A>, f: (b: B) => A): Predicate<B> => (b) => self(f(b)))
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Tests if a value is a `Set`.
|
|
58
|
+
*
|
|
59
|
+
* @param input - The value to test.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* import { isSet } from "effect/Predicate"
|
|
63
|
+
*
|
|
64
|
+
* assert.deepStrictEqual(isSet(new Set([1, 2])), true)
|
|
65
|
+
* assert.deepStrictEqual(isSet(new Set()), true)
|
|
66
|
+
* assert.deepStrictEqual(isSet({}), false)
|
|
67
|
+
* assert.deepStrictEqual(isSet(null), false)
|
|
68
|
+
* assert.deepStrictEqual(isSet(undefined), false)
|
|
69
|
+
*
|
|
70
|
+
* @category guards
|
|
71
|
+
* @since 2.0.0
|
|
72
|
+
*/
|
|
73
|
+
export const isSet = (input: unknown): input is Set<unknown> => input instanceof Set
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Tests if a value is a `Map`.
|
|
77
|
+
*
|
|
78
|
+
* @param input - The value to test.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* import { isMap } from "effect/Predicate"
|
|
82
|
+
*
|
|
83
|
+
* assert.deepStrictEqual(isMap(new Map()), true)
|
|
84
|
+
* assert.deepStrictEqual(isMap({}), false)
|
|
85
|
+
* assert.deepStrictEqual(isMap(null), false)
|
|
86
|
+
* assert.deepStrictEqual(isMap(undefined), false)
|
|
87
|
+
*
|
|
88
|
+
* @category guards
|
|
89
|
+
* @since 2.0.0
|
|
90
|
+
*/
|
|
91
|
+
export const isMap = (input: unknown): input is Map<unknown, unknown> => input instanceof Map
|
|
92
|
+
|
|
56
93
|
/**
|
|
57
94
|
* Tests if a value is a `string`.
|
|
58
95
|
*
|
|
@@ -192,7 +229,7 @@ export const isUndefined = (input: unknown): input is undefined => input === und
|
|
|
192
229
|
export const isNotUndefined = <A>(input: A): input is Exclude<A, undefined> => input !== undefined
|
|
193
230
|
|
|
194
231
|
/**
|
|
195
|
-
* Tests if a value is `
|
|
232
|
+
* Tests if a value is `null`.
|
|
196
233
|
*
|
|
197
234
|
* @param input - The value to test.
|
|
198
235
|
*
|
|
@@ -210,7 +247,7 @@ export const isNotUndefined = <A>(input: A): input is Exclude<A, undefined> => i
|
|
|
210
247
|
export const isNull = (input: unknown): input is null => input === null
|
|
211
248
|
|
|
212
249
|
/**
|
|
213
|
-
* Tests if a value is not `
|
|
250
|
+
* Tests if a value is not `null`.
|
|
214
251
|
*
|
|
215
252
|
* @param input - The value to test.
|
|
216
253
|
*
|
package/src/Request.ts
CHANGED
|
@@ -57,7 +57,7 @@ export declare namespace Request {
|
|
|
57
57
|
* @category models
|
|
58
58
|
*/
|
|
59
59
|
export interface Constructor<R extends Request<any, any>, T extends keyof R = never> {
|
|
60
|
-
(args: Omit<R, T | keyof (Request.Variance<Request.
|
|
60
|
+
(args: Omit<R, T | keyof (Request.Variance<Request.Success<R>, Request.Error<R>>)>): R
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
@@ -127,17 +127,17 @@ export const tagged: <R extends Request<any, any> & { _tag: string }>(
|
|
|
127
127
|
* @example
|
|
128
128
|
* import * as Request from "effect/Request"
|
|
129
129
|
*
|
|
130
|
-
* type Error = never
|
|
131
130
|
* type Success = string
|
|
131
|
+
* type Error = never
|
|
132
132
|
*
|
|
133
|
-
* class MyRequest extends Request.Class<
|
|
133
|
+
* class MyRequest extends Request.Class<Success, Error, {
|
|
134
134
|
* readonly id: string
|
|
135
135
|
* }> {}
|
|
136
136
|
*
|
|
137
137
|
* @since 2.0.0
|
|
138
138
|
* @category constructors
|
|
139
139
|
*/
|
|
140
|
-
export const Class: new<
|
|
140
|
+
export const Class: new<Success, Error, A extends Record<string, any>>(
|
|
141
141
|
args: Types.Equals<Omit<A, keyof Request<unknown, unknown>>, {}> extends true ? void
|
|
142
142
|
: { readonly [P in keyof A as P extends keyof Request<unknown, unknown> ? never : P]: A[P] }
|
|
143
143
|
) => Request<Success, Error> & Readonly<A> = internal.Class as any
|
|
@@ -148,10 +148,10 @@ export const Class: new<Error, Success, A extends Record<string, any>>(
|
|
|
148
148
|
* @example
|
|
149
149
|
* import * as Request from "effect/Request"
|
|
150
150
|
*
|
|
151
|
-
* type Error = never
|
|
152
151
|
* type Success = string
|
|
152
|
+
* type Error = never
|
|
153
153
|
*
|
|
154
|
-
* class MyRequest extends Request.TaggedClass("MyRequest")<
|
|
154
|
+
* class MyRequest extends Request.TaggedClass("MyRequest")<Success, Error, {
|
|
155
155
|
* readonly name: string
|
|
156
156
|
* }> {}
|
|
157
157
|
*
|
|
@@ -160,7 +160,7 @@ export const Class: new<Error, Success, A extends Record<string, any>>(
|
|
|
160
160
|
*/
|
|
161
161
|
export const TaggedClass: <Tag extends string>(
|
|
162
162
|
tag: Tag
|
|
163
|
-
) => new<
|
|
163
|
+
) => new<Success, Error, A extends Record<string, any>>(
|
|
164
164
|
args: Types.Equals<Omit<A, keyof Request<unknown, unknown>>, {}> extends true ? void
|
|
165
165
|
: { readonly [P in keyof A as P extends "_tag" | keyof Request<unknown, unknown> ? never : P]: A[P] }
|
|
166
166
|
) => Request<Success, Error> & Readonly<A> & { readonly _tag: Tag } = internal.TaggedClass as any
|
package/src/STM.ts
CHANGED
|
@@ -103,7 +103,7 @@ export interface STMTypeLambda extends TypeLambda {
|
|
|
103
103
|
* @category models
|
|
104
104
|
*/
|
|
105
105
|
declare module "./Context.js" {
|
|
106
|
-
interface Tag<
|
|
106
|
+
interface Tag<Id, Value> extends STM<Value, never, Id> {}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
/**
|
package/src/SortedSet.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @since 2.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Equal from "./Equal.js"
|
|
5
|
+
import type * as Equivalence from "./Equivalence.js"
|
|
5
6
|
import * as Dual from "./Function.js"
|
|
6
7
|
import { pipe } from "./Function.js"
|
|
7
8
|
import * as Hash from "./Hash.js"
|
|
@@ -381,3 +382,9 @@ export const union: {
|
|
|
381
382
|
* @category getters
|
|
382
383
|
*/
|
|
383
384
|
export const values = <A>(self: SortedSet<A>): IterableIterator<A> => RBT.keys(self.keyTree)
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* @since 2.0.0
|
|
388
|
+
* @category equivalence
|
|
389
|
+
*/
|
|
390
|
+
export const getEquivalence = <A>(): Equivalence.Equivalence<SortedSet<A>> => (a, b) => isSubset(a, b) && isSubset(b, a)
|
package/src/Struct.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import * as Equivalence from "./Equivalence.js"
|
|
8
8
|
import { dual } from "./Function.js"
|
|
9
9
|
import * as order from "./Order.js"
|
|
10
|
+
import * as Predicate from "./Predicate.js"
|
|
10
11
|
import type { MatchRecord, Simplify } from "./Types.js"
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -17,23 +18,32 @@ import type { MatchRecord, Simplify } from "./Types.js"
|
|
|
17
18
|
* import { pipe } from "effect/Function"
|
|
18
19
|
*
|
|
19
20
|
* assert.deepStrictEqual(pipe({ a: "a", b: 1, c: true }, pick("a", "b")), { a: "a", b: 1 })
|
|
21
|
+
* assert.deepStrictEqual(pick({ a: "a", b: 1, c: true }, "a", "b"), { a: "a", b: 1 })
|
|
20
22
|
*
|
|
21
23
|
* @since 2.0.0
|
|
22
24
|
*/
|
|
23
|
-
export const pick
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<S extends { [K in Keys[number]]?: any }>(
|
|
27
|
-
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
export const pick: {
|
|
26
|
+
<Keys extends Array<PropertyKey>>(
|
|
27
|
+
...keys: Keys
|
|
28
|
+
): <S extends { [K in Keys[number]]?: any }>(
|
|
29
|
+
s: S
|
|
30
|
+
) => MatchRecord<S, { [K in Keys[number]]?: S[K] }, Simplify<Pick<S, Keys[number]>>>
|
|
31
|
+
<S extends object, Keys extends Array<keyof S>>(
|
|
32
|
+
s: S,
|
|
33
|
+
...keys: Keys
|
|
34
|
+
): MatchRecord<S, { [K in Keys[number]]?: S[K] }, Simplify<Pick<S, Keys[number]>>>
|
|
35
|
+
} = dual(
|
|
36
|
+
(args) => Predicate.isObject(args[0]),
|
|
37
|
+
<S extends object, Keys extends Array<keyof S>>(s: S, ...keys: Keys) => {
|
|
38
|
+
const out: any = {}
|
|
39
|
+
for (const k of keys) {
|
|
40
|
+
if (k in s) {
|
|
41
|
+
out[k] = (s as any)[k]
|
|
42
|
+
}
|
|
33
43
|
}
|
|
44
|
+
return out
|
|
34
45
|
}
|
|
35
|
-
|
|
36
|
-
}
|
|
46
|
+
)
|
|
37
47
|
|
|
38
48
|
/**
|
|
39
49
|
* Create a new object by omitting properties of an existing object.
|
|
@@ -43,19 +53,28 @@ export const pick = <Keys extends Array<PropertyKey>>(
|
|
|
43
53
|
* import { pipe } from "effect/Function"
|
|
44
54
|
*
|
|
45
55
|
* assert.deepStrictEqual(pipe({ a: "a", b: 1, c: true }, omit("c")), { a: "a", b: 1 })
|
|
56
|
+
* assert.deepStrictEqual(omit({ a: "a", b: 1, c: true }, "c"), { a: "a", b: 1 })
|
|
46
57
|
*
|
|
47
58
|
* @since 2.0.0
|
|
48
59
|
*/
|
|
49
|
-
export const omit
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<S extends { [K in Keys[number]]?: any }>(s: S)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
export const omit: {
|
|
61
|
+
<Keys extends Array<PropertyKey>>(
|
|
62
|
+
...keys: Keys
|
|
63
|
+
): <S extends { [K in Keys[number]]?: any }>(s: S) => Simplify<Omit<S, Keys[number]>>
|
|
64
|
+
<S extends object, Keys extends Array<keyof S>>(
|
|
65
|
+
s: S,
|
|
66
|
+
...keys: Keys
|
|
67
|
+
): Simplify<Omit<S, Keys[number]>>
|
|
68
|
+
} = dual(
|
|
69
|
+
(args) => Predicate.isObject(args[0]),
|
|
70
|
+
<S extends object, Keys extends Array<keyof S>>(s: S, ...keys: Keys) => {
|
|
71
|
+
const out: any = { ...s }
|
|
72
|
+
for (const k of keys) {
|
|
73
|
+
delete out[k]
|
|
74
|
+
}
|
|
75
|
+
return out
|
|
56
76
|
}
|
|
57
|
-
|
|
58
|
-
}
|
|
77
|
+
)
|
|
59
78
|
|
|
60
79
|
/**
|
|
61
80
|
* Given a struct of `Equivalence`s returns a new `Equivalence` that compares values of a struct
|
package/src/Types.ts
CHANGED
|
@@ -1871,10 +1871,10 @@ export const serviceFunction = <T extends Effect.Effect<any, any, any>, Args ext
|
|
|
1871
1871
|
export const serviceFunctions = <S, SE, SR>(
|
|
1872
1872
|
getService: Effect.Effect<S, SE, SR>
|
|
1873
1873
|
): {
|
|
1874
|
-
[k in
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1874
|
+
[k in keyof S as S[k] extends (...args: Array<any>) => Effect.Effect<any, any, any> ? k : never]: S[k] extends
|
|
1875
|
+
(...args: infer Args) => Effect.Effect<infer A, infer E, infer R>
|
|
1876
|
+
? (...args: Args) => Effect.Effect<A, E | SE, R | SR>
|
|
1877
|
+
: never
|
|
1878
1878
|
} =>
|
|
1879
1879
|
new Proxy({} as any, {
|
|
1880
1880
|
get(_target: any, prop: any, _receiver) {
|
|
@@ -1899,10 +1899,10 @@ export const serviceConstants = <S, SE, SR>(
|
|
|
1899
1899
|
/** @internal */
|
|
1900
1900
|
export const serviceMembers = <S, SE, SR>(getService: Effect.Effect<S, SE, SR>): {
|
|
1901
1901
|
functions: {
|
|
1902
|
-
[k in
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1902
|
+
[k in keyof S as S[k] extends (...args: Array<any>) => Effect.Effect<any, any, any> ? k : never]: S[k] extends
|
|
1903
|
+
(...args: infer Args) => Effect.Effect<infer A, infer E, infer R>
|
|
1904
|
+
? (...args: Args) => Effect.Effect<A, E | SE, R | SR>
|
|
1905
|
+
: never
|
|
1906
1906
|
}
|
|
1907
1907
|
constants: {
|
|
1908
1908
|
[k in { [k in keyof S]: k }[keyof S]]: S[k] extends Effect.Effect<infer A, infer E, infer R> ?
|
|
@@ -1910,7 +1910,7 @@ export const serviceMembers = <S, SE, SR>(getService: Effect.Effect<S, SE, SR>):
|
|
|
1910
1910
|
Effect.Effect<S[k], SE, SR>
|
|
1911
1911
|
}
|
|
1912
1912
|
} => ({
|
|
1913
|
-
functions: serviceFunctions(getService),
|
|
1913
|
+
functions: serviceFunctions(getService) as any,
|
|
1914
1914
|
constants: serviceConstants(getService)
|
|
1915
1915
|
})
|
|
1916
1916
|
|
package/src/internal/core.ts
CHANGED
|
@@ -35,7 +35,7 @@ import type * as RuntimeFlags from "../RuntimeFlags.js"
|
|
|
35
35
|
import * as RuntimeFlagsPatch from "../RuntimeFlagsPatch.js"
|
|
36
36
|
import type * as Scope from "../Scope.js"
|
|
37
37
|
import type * as Tracer from "../Tracer.js"
|
|
38
|
-
import type { NoInfer } from "../Types.js"
|
|
38
|
+
import type { NoInfer, NotFunction } from "../Types.js"
|
|
39
39
|
import * as _blockedRequests from "./blockedRequests.js"
|
|
40
40
|
import * as internalCause from "./cause.js"
|
|
41
41
|
import * as deferred from "./deferred.js"
|
|
@@ -697,7 +697,7 @@ export const andThen: {
|
|
|
697
697
|
: [X] extends [Promise<infer A1>] ? Effect.Effect<A1, E | Cause.UnknownException, R>
|
|
698
698
|
: Effect.Effect<X, E, R>
|
|
699
699
|
<X>(
|
|
700
|
-
f: X
|
|
700
|
+
f: NotFunction<X>
|
|
701
701
|
): <A, E, R>(
|
|
702
702
|
self: Effect.Effect<A, E, R>
|
|
703
703
|
) => [X] extends [Effect.Effect<infer A1, infer E1, infer R1>] ? Effect.Effect<A1, E | E1, R | R1>
|
|
@@ -711,7 +711,7 @@ export const andThen: {
|
|
|
711
711
|
: Effect.Effect<X, E, R>
|
|
712
712
|
<A, E, R, X>(
|
|
713
713
|
self: Effect.Effect<A, E, R>,
|
|
714
|
-
f: X
|
|
714
|
+
f: NotFunction<X>
|
|
715
715
|
): [X] extends [Effect.Effect<infer A1, infer E1, infer R1>] ? Effect.Effect<A1, E | E1, R | R1>
|
|
716
716
|
: [X] extends [Promise<infer A1>] ? Effect.Effect<A1, E | Cause.UnknownException, R>
|
|
717
717
|
: Effect.Effect<X, E, R>
|
|
@@ -1169,7 +1169,7 @@ export const tap = dual<
|
|
|
1169
1169
|
: [X] extends [Promise<infer _A1>] ? Effect.Effect<A, E | Cause.UnknownException, R>
|
|
1170
1170
|
: Effect.Effect<A, E, R>
|
|
1171
1171
|
<X>(
|
|
1172
|
-
f: X
|
|
1172
|
+
f: NotFunction<X>
|
|
1173
1173
|
): <A, E, R>(
|
|
1174
1174
|
self: Effect.Effect<A, E, R>
|
|
1175
1175
|
) => [X] extends [Effect.Effect<infer _A1, infer E1, infer R1>] ? Effect.Effect<A, E | E1, R | R1>
|
|
@@ -1185,7 +1185,7 @@ export const tap = dual<
|
|
|
1185
1185
|
: Effect.Effect<A, E, R>
|
|
1186
1186
|
<A, E, R, X>(
|
|
1187
1187
|
self: Effect.Effect<A, E, R>,
|
|
1188
|
-
f: X
|
|
1188
|
+
f: NotFunction<X>
|
|
1189
1189
|
): [X] extends [Effect.Effect<infer _A1, infer E1, infer R1>] ? Effect.Effect<A, E | E1, R | R1>
|
|
1190
1190
|
: [X] extends [Promise<infer _A1>] ? Effect.Effect<A, E | Cause.UnknownException, R>
|
|
1191
1191
|
: Effect.Effect<A, E, R>
|
|
@@ -5,6 +5,7 @@ import type * as Clock from "../Clock.js"
|
|
|
5
5
|
import type { ConfigProvider } from "../ConfigProvider.js"
|
|
6
6
|
import * as Context from "../Context.js"
|
|
7
7
|
import * as Deferred from "../Deferred.js"
|
|
8
|
+
import type * as Duration from "../Duration.js"
|
|
8
9
|
import type * as Effect from "../Effect.js"
|
|
9
10
|
import { EffectTypeId } from "../Effectable.js"
|
|
10
11
|
import type * as Either from "../Either.js"
|
|
@@ -1361,6 +1362,16 @@ export const defaultLogger: Logger<unknown, void> = globalValue(
|
|
|
1361
1362
|
})
|
|
1362
1363
|
)
|
|
1363
1364
|
|
|
1365
|
+
/** @internal */
|
|
1366
|
+
export const jsonLogger: Logger<unknown, void> = globalValue(
|
|
1367
|
+
Symbol.for("effect/Logger/jsonLogger"),
|
|
1368
|
+
() =>
|
|
1369
|
+
internalLogger.makeLogger((options) => {
|
|
1370
|
+
const formatted = internalLogger.jsonLogger.log(options)
|
|
1371
|
+
getConsole(options.context).log(formatted)
|
|
1372
|
+
})
|
|
1373
|
+
)
|
|
1374
|
+
|
|
1364
1375
|
/** @internal */
|
|
1365
1376
|
export const logFmtLogger: Logger<unknown, void> = globalValue(
|
|
1366
1377
|
Symbol.for("effect/Logger/logFmtLogger"),
|
|
@@ -1371,6 +1382,16 @@ export const logFmtLogger: Logger<unknown, void> = globalValue(
|
|
|
1371
1382
|
})
|
|
1372
1383
|
)
|
|
1373
1384
|
|
|
1385
|
+
/** @internal */
|
|
1386
|
+
export const structuredLogger: Logger<unknown, void> = globalValue(
|
|
1387
|
+
Symbol.for("effect/Logger/structuredLogger"),
|
|
1388
|
+
() =>
|
|
1389
|
+
internalLogger.makeLogger((options) => {
|
|
1390
|
+
const formatted = internalLogger.structuredLogger.log(options)
|
|
1391
|
+
getConsole(options.context).log(formatted)
|
|
1392
|
+
})
|
|
1393
|
+
)
|
|
1394
|
+
|
|
1374
1395
|
/** @internal */
|
|
1375
1396
|
export const tracerLogger = globalValue(
|
|
1376
1397
|
Symbol.for("effect/Logger/tracerLogger"),
|
|
@@ -1434,6 +1455,53 @@ export const currentLoggers: FiberRef.FiberRef<
|
|
|
1434
1455
|
() => core.fiberRefUnsafeMakeHashSet(HashSet.make(defaultLogger, tracerLogger))
|
|
1435
1456
|
)
|
|
1436
1457
|
|
|
1458
|
+
/** @internal */
|
|
1459
|
+
export const batchedLogger = dual<
|
|
1460
|
+
<Output, R>(
|
|
1461
|
+
window: Duration.DurationInput,
|
|
1462
|
+
f: (messages: Array<NoInfer<Output>>) => Effect.Effect<void, never, R>
|
|
1463
|
+
) => <Message>(
|
|
1464
|
+
self: Logger<Message, Output>
|
|
1465
|
+
) => Effect.Effect<Logger<Message, void>, never, Scope.Scope | R>,
|
|
1466
|
+
<Message, Output, R>(
|
|
1467
|
+
self: Logger<Message, Output>,
|
|
1468
|
+
window: Duration.DurationInput,
|
|
1469
|
+
f: (messages: Array<NoInfer<Output>>) => Effect.Effect<void, never, R>
|
|
1470
|
+
) => Effect.Effect<Logger<Message, void>, never, Scope.Scope | R>
|
|
1471
|
+
>(3, <Message, Output, R>(
|
|
1472
|
+
self: Logger<Message, Output>,
|
|
1473
|
+
window: Duration.DurationInput,
|
|
1474
|
+
f: (messages: Array<NoInfer<Output>>) => Effect.Effect<void, never, R>
|
|
1475
|
+
): Effect.Effect<Logger<Message, void>, never, Scope.Scope | R> =>
|
|
1476
|
+
core.flatMap(scope, (scope) => {
|
|
1477
|
+
let buffer: Array<Output> = []
|
|
1478
|
+
const flush = core.suspend(() => {
|
|
1479
|
+
if (buffer.length === 0) {
|
|
1480
|
+
return core.unit
|
|
1481
|
+
}
|
|
1482
|
+
const arr = buffer
|
|
1483
|
+
buffer = []
|
|
1484
|
+
return f(arr)
|
|
1485
|
+
})
|
|
1486
|
+
|
|
1487
|
+
return core.uninterruptibleMask((restore) =>
|
|
1488
|
+
pipe(
|
|
1489
|
+
internalEffect.sleep(window),
|
|
1490
|
+
core.zipRight(flush),
|
|
1491
|
+
internalEffect.forever,
|
|
1492
|
+
restore,
|
|
1493
|
+
forkDaemon,
|
|
1494
|
+
core.flatMap((fiber) => core.scopeAddFinalizer(scope, core.interruptFiber(fiber))),
|
|
1495
|
+
core.zipRight(addFinalizer(() => flush)),
|
|
1496
|
+
core.as(
|
|
1497
|
+
internalLogger.makeLogger((options) => {
|
|
1498
|
+
buffer.push(self.log(options))
|
|
1499
|
+
})
|
|
1500
|
+
)
|
|
1501
|
+
)
|
|
1502
|
+
)
|
|
1503
|
+
}))
|
|
1504
|
+
|
|
1437
1505
|
// circular with Effect
|
|
1438
1506
|
|
|
1439
1507
|
/* @internal */
|
package/src/internal/logger.ts
CHANGED
|
@@ -215,7 +215,7 @@ export const stringLogger: Logger.Logger<unknown, string> = makeLogger<unknown,
|
|
|
215
215
|
|
|
216
216
|
export const serializeUnknown = (u: unknown): string => {
|
|
217
217
|
try {
|
|
218
|
-
return typeof u === "object" ?
|
|
218
|
+
return typeof u === "object" ? jsonStringifyCircular(u) : String(u)
|
|
219
219
|
} catch (_) {
|
|
220
220
|
return String(u)
|
|
221
221
|
}
|
|
@@ -288,6 +288,76 @@ export const logfmtLogger = makeLogger<unknown, string>(
|
|
|
288
288
|
}
|
|
289
289
|
)
|
|
290
290
|
|
|
291
|
+
/** @internal */
|
|
292
|
+
export const structuredLogger = makeLogger<unknown, {
|
|
293
|
+
readonly logLevel: string
|
|
294
|
+
readonly fiberId: string
|
|
295
|
+
readonly timestamp: string
|
|
296
|
+
readonly message: unknown
|
|
297
|
+
readonly cause: string | undefined
|
|
298
|
+
readonly annotations: Record<string, unknown>
|
|
299
|
+
readonly spans: Record<string, number>
|
|
300
|
+
}>(
|
|
301
|
+
({ annotations, cause, date, fiberId, logLevel, message, spans }) => {
|
|
302
|
+
const now = date.getTime()
|
|
303
|
+
const annotationsObj: Record<string, unknown> = {}
|
|
304
|
+
const spansObj: Record<string, number> = {}
|
|
305
|
+
|
|
306
|
+
if (HashMap.size(annotations) > 0) {
|
|
307
|
+
for (const [k, v] of annotations) {
|
|
308
|
+
annotationsObj[k] = structuredMessage(v)
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (List.isCons(spans)) {
|
|
313
|
+
for (const span of spans) {
|
|
314
|
+
spansObj[span.label] = now - span.startTime
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
message: structuredMessage(message),
|
|
320
|
+
logLevel: logLevel.label,
|
|
321
|
+
timestamp: date.toISOString(),
|
|
322
|
+
cause: Cause.isEmpty(cause) ? undefined : Cause.pretty(cause),
|
|
323
|
+
annotations: annotationsObj,
|
|
324
|
+
spans: spansObj,
|
|
325
|
+
fiberId: _fiberId.threadName(fiberId)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
export const structuredMessage = (u: unknown): unknown => {
|
|
331
|
+
switch (typeof u) {
|
|
332
|
+
case "bigint":
|
|
333
|
+
case "function":
|
|
334
|
+
case "symbol": {
|
|
335
|
+
return String(u)
|
|
336
|
+
}
|
|
337
|
+
default: {
|
|
338
|
+
return u
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const jsonStringifyCircular = (obj: unknown) => {
|
|
344
|
+
let cache: Array<unknown> = []
|
|
345
|
+
const retVal = JSON.stringify(
|
|
346
|
+
obj,
|
|
347
|
+
(_key, value) =>
|
|
348
|
+
typeof value === "object" && value !== null
|
|
349
|
+
? cache.includes(value)
|
|
350
|
+
? undefined // circular reference
|
|
351
|
+
: cache.push(value) && value
|
|
352
|
+
: value
|
|
353
|
+
)
|
|
354
|
+
;(cache as any) = undefined
|
|
355
|
+
return retVal
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** @internal */
|
|
359
|
+
export const jsonLogger = map(structuredLogger, jsonStringifyCircular)
|
|
360
|
+
|
|
291
361
|
/** @internal */
|
|
292
362
|
const filterKeyName = (key: string) => key.replace(/[\s="]/g, "_")
|
|
293
363
|
|
|
@@ -303,3 +373,8 @@ const renderLogSpanLogfmt = (now: number) => (self: LogSpan.LogSpan): string =>
|
|
|
303
373
|
const label = filterKeyName(self.label)
|
|
304
374
|
return `${label}=${now - self.startTime}ms`
|
|
305
375
|
}
|
|
376
|
+
|
|
377
|
+
/** @internal */
|
|
378
|
+
export const isLogger = (u: unknown): u is Logger.Logger<unknown, unknown> => {
|
|
379
|
+
return typeof u === "object" && u != null && LoggerTypeId in u
|
|
380
|
+
}
|