effect 3.4.9 → 3.5.1

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 (166) hide show
  1. package/RcMap/package.json +6 -0
  2. package/RcRef/package.json +6 -0
  3. package/dist/cjs/Cause.js +22 -1
  4. package/dist/cjs/Cause.js.map +1 -1
  5. package/dist/cjs/Channel.js.map +1 -1
  6. package/dist/cjs/Config.js.map +1 -1
  7. package/dist/cjs/Console.js.map +1 -1
  8. package/dist/cjs/Data.js +3 -1
  9. package/dist/cjs/Data.js.map +1 -1
  10. package/dist/cjs/Duration.js +23 -2
  11. package/dist/cjs/Duration.js.map +1 -1
  12. package/dist/cjs/Effect.js +78 -15
  13. package/dist/cjs/Effect.js.map +1 -1
  14. package/dist/cjs/Logger.js +234 -13
  15. package/dist/cjs/Logger.js.map +1 -1
  16. package/dist/cjs/PubSub.js.map +1 -1
  17. package/dist/cjs/Random.js +24 -1
  18. package/dist/cjs/Random.js.map +1 -1
  19. package/dist/cjs/RcMap.js +52 -0
  20. package/dist/cjs/RcMap.js.map +1 -0
  21. package/dist/cjs/RcRef.js +51 -0
  22. package/dist/cjs/RcRef.js.map +1 -0
  23. package/dist/cjs/Stream.js +29 -2
  24. package/dist/cjs/Stream.js.map +1 -1
  25. package/dist/cjs/index.js +6 -2
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/internal/cause.js +21 -5
  28. package/dist/cjs/internal/cause.js.map +1 -1
  29. package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
  30. package/dist/cjs/internal/channel.js.map +1 -1
  31. package/dist/cjs/internal/core-effect.js +0 -5
  32. package/dist/cjs/internal/core-effect.js.map +1 -1
  33. package/dist/cjs/internal/core.js +15 -10
  34. package/dist/cjs/internal/core.js.map +1 -1
  35. package/dist/cjs/internal/defaultServices.js +1 -1
  36. package/dist/cjs/internal/defaultServices.js.map +1 -1
  37. package/dist/cjs/internal/fiberRuntime.js +3 -1
  38. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  39. package/dist/cjs/internal/logger.js +129 -27
  40. package/dist/cjs/internal/logger.js.map +1 -1
  41. package/dist/cjs/internal/pubsub.js +216 -36
  42. package/dist/cjs/internal/pubsub.js.map +1 -1
  43. package/dist/cjs/internal/random.js +2 -1
  44. package/dist/cjs/internal/random.js.map +1 -1
  45. package/dist/cjs/internal/rcMap.js +129 -0
  46. package/dist/cjs/internal/rcMap.js.map +1 -0
  47. package/dist/cjs/internal/rcRef.js +122 -0
  48. package/dist/cjs/internal/rcRef.js.map +1 -0
  49. package/dist/cjs/internal/stream.js +57 -11
  50. package/dist/cjs/internal/stream.js.map +1 -1
  51. package/dist/cjs/internal/version.js +1 -1
  52. package/dist/dts/Cause.d.ts +40 -1
  53. package/dist/dts/Cause.d.ts.map +1 -1
  54. package/dist/dts/Channel.d.ts +3 -3
  55. package/dist/dts/Channel.d.ts.map +1 -1
  56. package/dist/dts/Config.d.ts +5 -0
  57. package/dist/dts/Config.d.ts.map +1 -1
  58. package/dist/dts/Console.d.ts +2 -4
  59. package/dist/dts/Console.d.ts.map +1 -1
  60. package/dist/dts/Duration.d.ts +5 -0
  61. package/dist/dts/Duration.d.ts.map +1 -1
  62. package/dist/dts/Effect.d.ts +78 -15
  63. package/dist/dts/Effect.d.ts.map +1 -1
  64. package/dist/dts/Logger.d.ts +238 -12
  65. package/dist/dts/Logger.d.ts.map +1 -1
  66. package/dist/dts/PubSub.d.ts +15 -4
  67. package/dist/dts/PubSub.d.ts.map +1 -1
  68. package/dist/dts/Random.d.ts +23 -0
  69. package/dist/dts/Random.d.ts.map +1 -1
  70. package/dist/dts/RcMap.d.ts +93 -0
  71. package/dist/dts/RcMap.d.ts.map +1 -0
  72. package/dist/dts/RcRef.d.ts +83 -0
  73. package/dist/dts/RcRef.d.ts.map +1 -0
  74. package/dist/dts/Stream.d.ts +64 -26
  75. package/dist/dts/Stream.d.ts.map +1 -1
  76. package/dist/dts/index.d.ts +8 -0
  77. package/dist/dts/index.d.ts.map +1 -1
  78. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  79. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  80. package/dist/dts/internal/logger.d.ts.map +1 -1
  81. package/dist/dts/internal/random.d.ts +1 -1
  82. package/dist/dts/internal/random.d.ts.map +1 -1
  83. package/dist/dts/internal/rcMap.d.ts +2 -0
  84. package/dist/dts/internal/rcMap.d.ts.map +1 -0
  85. package/dist/dts/internal/rcRef.d.ts +2 -0
  86. package/dist/dts/internal/rcRef.d.ts.map +1 -0
  87. package/dist/dts/internal/stream.d.ts +1 -0
  88. package/dist/dts/internal/stream.d.ts.map +1 -1
  89. package/dist/esm/Cause.js +21 -0
  90. package/dist/esm/Cause.js.map +1 -1
  91. package/dist/esm/Channel.js.map +1 -1
  92. package/dist/esm/Config.js.map +1 -1
  93. package/dist/esm/Console.js.map +1 -1
  94. package/dist/esm/Data.js +3 -1
  95. package/dist/esm/Data.js.map +1 -1
  96. package/dist/esm/Duration.js +20 -0
  97. package/dist/esm/Duration.js.map +1 -1
  98. package/dist/esm/Effect.js +78 -15
  99. package/dist/esm/Effect.js.map +1 -1
  100. package/dist/esm/Logger.js +233 -12
  101. package/dist/esm/Logger.js.map +1 -1
  102. package/dist/esm/PubSub.js.map +1 -1
  103. package/dist/esm/Random.js +23 -0
  104. package/dist/esm/Random.js.map +1 -1
  105. package/dist/esm/RcMap.js +44 -0
  106. package/dist/esm/RcMap.js.map +1 -0
  107. package/dist/esm/RcRef.js +43 -0
  108. package/dist/esm/RcRef.js.map +1 -0
  109. package/dist/esm/Stream.js +27 -0
  110. package/dist/esm/Stream.js.map +1 -1
  111. package/dist/esm/index.js +8 -0
  112. package/dist/esm/index.js.map +1 -1
  113. package/dist/esm/internal/cause.js +21 -5
  114. package/dist/esm/internal/cause.js.map +1 -1
  115. package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
  116. package/dist/esm/internal/channel.js.map +1 -1
  117. package/dist/esm/internal/core-effect.js +0 -5
  118. package/dist/esm/internal/core-effect.js.map +1 -1
  119. package/dist/esm/internal/core.js +11 -7
  120. package/dist/esm/internal/core.js.map +1 -1
  121. package/dist/esm/internal/defaultServices.js +1 -1
  122. package/dist/esm/internal/defaultServices.js.map +1 -1
  123. package/dist/esm/internal/fiberRuntime.js +2 -0
  124. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  125. package/dist/esm/internal/logger.js +127 -26
  126. package/dist/esm/internal/logger.js.map +1 -1
  127. package/dist/esm/internal/pubsub.js +216 -36
  128. package/dist/esm/internal/pubsub.js.map +1 -1
  129. package/dist/esm/internal/random.js +2 -1
  130. package/dist/esm/internal/random.js.map +1 -1
  131. package/dist/esm/internal/rcMap.js +120 -0
  132. package/dist/esm/internal/rcMap.js.map +1 -0
  133. package/dist/esm/internal/rcRef.js +112 -0
  134. package/dist/esm/internal/rcRef.js.map +1 -0
  135. package/dist/esm/internal/stream.js +53 -8
  136. package/dist/esm/internal/stream.js.map +1 -1
  137. package/dist/esm/internal/version.js +1 -1
  138. package/package.json +17 -1
  139. package/src/Cause.ts +47 -1
  140. package/src/Channel.ts +3 -3
  141. package/src/Config.ts +6 -0
  142. package/src/Console.ts +2 -4
  143. package/src/Data.ts +1 -1
  144. package/src/Duration.ts +18 -0
  145. package/src/Effect.ts +78 -15
  146. package/src/Logger.ts +242 -12
  147. package/src/PubSub.ts +11 -4
  148. package/src/Random.ts +24 -0
  149. package/src/RcMap.ts +103 -0
  150. package/src/RcRef.ts +91 -0
  151. package/src/Stream.ts +83 -26
  152. package/src/index.ts +10 -0
  153. package/src/internal/cause.ts +26 -5
  154. package/src/internal/channel/channelExecutor.ts +1 -1
  155. package/src/internal/channel.ts +4 -3
  156. package/src/internal/core-effect.ts +0 -5
  157. package/src/internal/core.ts +19 -9
  158. package/src/internal/defaultServices.ts +1 -1
  159. package/src/internal/fiberRuntime.ts +6 -0
  160. package/src/internal/logger.ts +135 -27
  161. package/src/internal/pubsub.ts +249 -58
  162. package/src/internal/random.ts +2 -1
  163. package/src/internal/rcMap.ts +213 -0
  164. package/src/internal/rcRef.ts +172 -0
  165. package/src/internal/stream.ts +325 -111
  166. package/src/internal/version.ts +1 -1
@@ -1,4 +1,4 @@
1
- let moduleVersion = "3.4.9";
1
+ let moduleVersion = "3.5.1";
2
2
  export const getCurrentVersion = () => moduleVersion;
3
3
  export const setCurrentVersion = version => {
4
4
  moduleVersion = version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect",
3
- "version": "3.4.9",
3
+ "version": "3.5.1",
4
4
  "description": "The missing standard library for TypeScript, for writing production-grade software.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -472,6 +472,16 @@
472
472
  "import": "./dist/esm/RateLimiter.js",
473
473
  "default": "./dist/cjs/RateLimiter.js"
474
474
  },
475
+ "./RcMap": {
476
+ "types": "./dist/dts/RcMap.d.ts",
477
+ "import": "./dist/esm/RcMap.js",
478
+ "default": "./dist/cjs/RcMap.js"
479
+ },
480
+ "./RcRef": {
481
+ "types": "./dist/dts/RcRef.d.ts",
482
+ "import": "./dist/esm/RcRef.js",
483
+ "default": "./dist/cjs/RcRef.js"
484
+ },
475
485
  "./Readable": {
476
486
  "types": "./dist/dts/Readable.d.ts",
477
487
  "import": "./dist/esm/Readable.js",
@@ -1085,6 +1095,12 @@
1085
1095
  "RateLimiter": [
1086
1096
  "./dist/dts/RateLimiter.d.ts"
1087
1097
  ],
1098
+ "RcMap": [
1099
+ "./dist/dts/RcMap.d.ts"
1100
+ ],
1101
+ "RcRef": [
1102
+ "./dist/dts/RcRef.d.ts"
1103
+ ],
1088
1104
  "Readable": [
1089
1105
  "./dist/dts/Readable.d.ts"
1090
1106
  ],
package/src/Cause.ts CHANGED
@@ -111,6 +111,18 @@ export const InvalidPubSubCapacityExceptionTypeId: unique symbol = core.InvalidP
111
111
  */
112
112
  export type InvalidPubSubCapacityExceptionTypeId = typeof InvalidPubSubCapacityExceptionTypeId
113
113
 
114
+ /**
115
+ * @since 3.5.0
116
+ * @category symbols
117
+ */
118
+ export const ExceededCapacityExceptionTypeId: unique symbol = core.ExceededCapacityExceptionTypeId
119
+
120
+ /**
121
+ * @since 3.5.0
122
+ * @category symbols
123
+ */
124
+ export type ExceededCapacityExceptionTypeId = typeof ExceededCapacityExceptionTypeId
125
+
114
126
  /**
115
127
  * @since 2.0.0
116
128
  * @category symbols
@@ -264,6 +276,18 @@ export interface InvalidPubSubCapacityException extends YieldableError {
264
276
  readonly [InvalidPubSubCapacityExceptionTypeId]: InvalidPubSubCapacityExceptionTypeId
265
277
  }
266
278
 
279
+ /**
280
+ * Represents a checked exception which occurs when a resources capacity has
281
+ * been exceeded.
282
+ *
283
+ * @since 3.5.0
284
+ * @category models
285
+ */
286
+ export interface ExceededCapacityException extends YieldableError {
287
+ readonly _tag: "ExceededCapacityException"
288
+ readonly [ExceededCapacityExceptionTypeId]: ExceededCapacityExceptionTypeId
289
+ }
290
+
267
291
  /**
268
292
  * Represents a checked exception which occurs when a computation doesn't
269
293
  * finish on schedule.
@@ -907,13 +931,35 @@ export const UnknownException: new(error: unknown, message?: string | undefined)
907
931
  */
908
932
  export const isUnknownException: (u: unknown) => u is UnknownException = core.isUnknownException
909
933
 
934
+ /**
935
+ * Represents a checked exception which occurs when a resources capacity has
936
+ * been exceeded.
937
+ *
938
+ * @since 3.5.0
939
+ * @category errors
940
+ */
941
+ export const ExceededCapacityException: new(message?: string | undefined) => ExceededCapacityException =
942
+ core.ExceededCapacityException
943
+
944
+ /**
945
+ * Returns `true` if the specified value is an `ExceededCapacityException`, `false`
946
+ * otherwise.
947
+ *
948
+ * @since 3.5.0
949
+ * @category refinements
950
+ */
951
+ export const isExceededCapacityException: (u: unknown) => u is ExceededCapacityException =
952
+ core.isExceededCapacityException
953
+
910
954
  /**
911
955
  * Returns the specified `Cause` as a pretty-printed string.
912
956
  *
913
957
  * @since 2.0.0
914
958
  * @category rendering
915
959
  */
916
- export const pretty: <E>(cause: Cause<E>) => string = internal.pretty
960
+ export const pretty: <E>(cause: Cause<E>, options?: {
961
+ readonly renderErrorCause?: boolean | undefined
962
+ }) => string = internal.pretty
917
963
 
918
964
  /**
919
965
  * @since 3.2.0
package/src/Channel.ts CHANGED
@@ -1916,7 +1916,7 @@ export const repeated: <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
1916
1916
  */
1917
1917
  export const run: <OutErr, InErr, OutDone, InDone, Env>(
1918
1918
  self: Channel<never, unknown, OutErr, InErr, OutDone, InDone, Env>
1919
- ) => Effect.Effect<OutDone, OutErr, Env> = channel.run
1919
+ ) => Effect.Effect<OutDone, OutErr, Exclude<Env, Scope.Scope>> = channel.run
1920
1920
 
1921
1921
  /**
1922
1922
  * Run the channel until it finishes with a done value or fails with an error
@@ -1929,7 +1929,7 @@ export const run: <OutErr, InErr, OutDone, InDone, Env>(
1929
1929
  */
1930
1930
  export const runCollect: <OutElem, OutErr, InErr, OutDone, InDone, Env>(
1931
1931
  self: Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, Env>
1932
- ) => Effect.Effect<[Chunk.Chunk<OutElem>, OutDone], OutErr, Env> = channel.runCollect
1932
+ ) => Effect.Effect<[Chunk.Chunk<OutElem>, OutDone], OutErr, Exclude<Env, Scope.Scope>> = channel.runCollect
1933
1933
 
1934
1934
  /**
1935
1935
  * Runs a channel until the end is received.
@@ -1939,7 +1939,7 @@ export const runCollect: <OutElem, OutErr, InErr, OutDone, InDone, Env>(
1939
1939
  */
1940
1940
  export const runDrain: <OutElem, OutErr, InErr, OutDone, InDone, Env>(
1941
1941
  self: Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, Env>
1942
- ) => Effect.Effect<OutDone, OutErr, Env> = channel.runDrain
1942
+ ) => Effect.Effect<OutDone, OutErr, Exclude<Env, Scope.Scope>> = channel.runDrain
1943
1943
 
1944
1944
  /**
1945
1945
  * Use a scoped effect to emit an output element.
package/src/Config.ts CHANGED
@@ -51,6 +51,12 @@ export declare namespace Config {
51
51
  }
52
52
  }
53
53
 
54
+ /**
55
+ * @since 2.5.0
56
+ * @category models
57
+ */
58
+ export type Success<T extends Config<any>> = [T] extends [Config<infer _A>] ? _A : never
59
+
54
60
  /**
55
61
  * @since 2.0.0
56
62
  * @category models
package/src/Console.ts CHANGED
@@ -63,10 +63,8 @@ export interface UnsafeConsole {
63
63
  dir(item: any, options?: any): void
64
64
  dirxml(...args: ReadonlyArray<any>): void
65
65
  error(...args: ReadonlyArray<any>): void
66
- group(options?: {
67
- readonly label?: string | undefined
68
- readonly collapsed?: boolean | undefined
69
- }): void
66
+ group(label?: string | undefined): void
67
+ groupCollapsed(label?: string | undefined): void
70
68
  groupEnd(): void
71
69
  info(...args: ReadonlyArray<any>): void
72
70
  log(...args: ReadonlyArray<any>): void
package/src/Data.ts CHANGED
@@ -532,7 +532,7 @@ export const Error: new<A extends Record<string, any> = {}>(
532
532
  ) => Cause.YieldableError & Readonly<A> = (function() {
533
533
  return class Base extends core.YieldableError {
534
534
  constructor(args: any) {
535
- super()
535
+ super(args?.message, { cause: args?.cause })
536
536
  if (args) {
537
537
  Object.assign(this, args)
538
538
  }
package/src/Duration.ts CHANGED
@@ -200,6 +200,24 @@ export const isDuration = (u: unknown): u is Duration => hasProperty(u, TypeId)
200
200
  */
201
201
  export const isFinite = (self: Duration): boolean => self.value._tag !== "Infinity"
202
202
 
203
+ /**
204
+ * @since 3.5.0
205
+ * @category guards
206
+ */
207
+ export const isZero = (self: Duration): boolean => {
208
+ switch (self.value._tag) {
209
+ case "Millis": {
210
+ return self.value.millis === 0
211
+ }
212
+ case "Nanos": {
213
+ return self.value.nanos === bigint0
214
+ }
215
+ case "Infinity": {
216
+ return false
217
+ }
218
+ }
219
+ }
220
+
203
221
  /**
204
222
  * @since 2.0.0
205
223
  * @category constructors
package/src/Effect.ts CHANGED
@@ -4798,9 +4798,25 @@ export const matchEffect: {
4798
4798
  // -------------------------------------------------------------------------------------
4799
4799
 
4800
4800
  /**
4801
- * Logs the specified message or cause at the current log level.
4801
+ * Logs one or more messages or error causes at the current log level, which is INFO by default.
4802
+ * This function allows logging multiple items at once and can include detailed error information using `Cause` instances.
4802
4803
  *
4803
- * You can set the current log level using `FiberRef.currentLogLevel`.
4804
+ * To adjust the log level, use the `Logger.withMinimumLogLevel` function.
4805
+ *
4806
+ * @example
4807
+ * import { Cause, Effect } from "effect"
4808
+ *
4809
+ * const program = Effect.log(
4810
+ * "message1",
4811
+ * "message2",
4812
+ * Cause.die("Oh no!"),
4813
+ * Cause.die("Oh uh!")
4814
+ * )
4815
+ *
4816
+ * // Effect.runFork(program)
4817
+ * // Output:
4818
+ * // timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!
4819
+ * // Error: Oh uh!"
4804
4820
  *
4805
4821
  * @since 2.0.0
4806
4822
  * @category logging
@@ -4827,7 +4843,19 @@ export const logWithLevel = (
4827
4843
  export const logTrace: (...message: ReadonlyArray<any>) => Effect<void, never, never> = effect.logTrace
4828
4844
 
4829
4845
  /**
4830
- * Logs the specified message or cause at the Debug log level.
4846
+ * Logs the specified messages at the DEBUG log level.
4847
+ * DEBUG messages are not shown by default.
4848
+ *
4849
+ * To view DEBUG messages, adjust the logging settings using
4850
+ * `Logger.withMinimumLogLevel` and set the log level to `LogLevel.Debug`.
4851
+ *
4852
+ * @example
4853
+ * import { Effect, Logger, LogLevel } from "effect"
4854
+ *
4855
+ * const program = Effect.logDebug("message1").pipe(Logger.withMinimumLogLevel(LogLevel.Debug))
4856
+ *
4857
+ * // Effect.runFork(program)
4858
+ * // timestamp=... level=DEBUG fiber=#0 message=message1
4831
4859
  *
4832
4860
  * @since 2.0.0
4833
4861
  * @category logging
@@ -4867,7 +4895,20 @@ export const logError: (...message: ReadonlyArray<any>) => Effect<void, never, n
4867
4895
  export const logFatal: (...message: ReadonlyArray<any>) => Effect<void, never, never> = effect.logFatal
4868
4896
 
4869
4897
  /**
4870
- * Adjusts the label for the current logging span.
4898
+ * Adds a log span to your effects, which tracks and logs the duration of
4899
+ * operations or tasks. This is useful for performance monitoring and debugging
4900
+ * time-sensitive processes.
4901
+ *
4902
+ * @example
4903
+ * import { Effect } from "effect"
4904
+ *
4905
+ * const program = Effect.gen(function*() {
4906
+ * yield* Effect.sleep("1 second")
4907
+ * yield* Effect.log("The job is finished!")
4908
+ * }).pipe(Effect.withLogSpan("myspan"))
4909
+ *
4910
+ * // Effect.runFork(program)
4911
+ * // timestamp=... level=INFO fiber=#0 message="The job is finished!" myspan=1011ms
4871
4912
  *
4872
4913
  * @since 2.0.0
4873
4914
  * @category logging
@@ -4878,7 +4919,21 @@ export const withLogSpan: {
4878
4919
  } = effect.withLogSpan
4879
4920
 
4880
4921
  /**
4881
- * Annotates each log in this effect with the specified log annotation.
4922
+ * Augments log outputs by appending custom annotations to log entries generated
4923
+ * within an effect. This function provides a way to add more context and detail
4924
+ * to log messages, making them more informative and easier to trace.
4925
+ *
4926
+ * @example
4927
+ * import { Effect } from "effect"
4928
+ *
4929
+ * const program = Effect.gen(function*() {
4930
+ * yield* Effect.log("message1")
4931
+ * yield* Effect.log("message2")
4932
+ * }).pipe(Effect.annotateLogs("key", "value")) // Annotation as key/value pair
4933
+ *
4934
+ * // Effect.runFork(program)
4935
+ * // timestamp=... level=INFO fiber=#0 message=message1 key=value
4936
+ * // timestamp=... level=INFO fiber=#0 message=message2 key=value
4882
4937
  *
4883
4938
  * @since 2.0.0
4884
4939
  * @category logging
@@ -4891,21 +4946,29 @@ export const annotateLogs: {
4891
4946
  } = effect.annotateLogs
4892
4947
 
4893
4948
  /**
4894
- * Annotates each log with the specified log annotation(s), until the Scope is closed.
4949
+ * Applies log annotations with a limited scope, restricting their appearance to
4950
+ * specific sections of your effect computations. Use
4951
+ * `Effect.annotateLogsScoped` to add metadata to logs that only appear within a
4952
+ * defined `Scope`, making it easier to manage context-specific logging.
4895
4953
  *
4896
- * @since 3.1.0
4897
- * @category logging
4898
4954
  * @example
4899
4955
  * import { Effect } from "effect"
4900
4956
  *
4901
- * Effect.gen(function*() {
4957
+ * const program = Effect.gen(function*() {
4902
4958
  * yield* Effect.log("no annotations")
4903
- * yield* Effect.annotateLogsScoped({ foo: "bar" })
4904
- * yield* Effect.log("annotated with foo=bar")
4905
- * }).pipe(
4906
- * Effect.scoped,
4907
- * Effect.andThen(Effect.log("no annotations again"))
4908
- * )
4959
+ * yield* Effect.annotateLogsScoped({ key: "value" })
4960
+ * yield* Effect.log("message1") // Annotation is applied to this log
4961
+ * yield* Effect.log("message2") // Annotation is applied to this log
4962
+ * }).pipe(Effect.scoped, Effect.andThen(Effect.log("no annotations again")))
4963
+ *
4964
+ * // Effect.runFork(program)
4965
+ * // timestamp=... level=INFO fiber=#0 message="no annotations"
4966
+ * // timestamp=... level=INFO fiber=#0 message=message1 key=value
4967
+ * // timestamp=... level=INFO fiber=#0 message=message2 key=value
4968
+ * // timestamp=... level=INFO fiber=#0 message="no annotations again"
4969
+ *
4970
+ * @since 3.1.0
4971
+ * @category logging
4909
4972
  */
4910
4973
  export const annotateLogsScoped: {
4911
4974
  (key: string, value: unknown): Effect<void, never, Scope.Scope>
package/src/Logger.ts CHANGED
@@ -73,6 +73,35 @@ export declare namespace Logger {
73
73
  }
74
74
 
75
75
  /**
76
+ * Creates a custom logger that formats log messages according to the provided
77
+ * function.
78
+ *
79
+ * @example
80
+ * import { Effect, Logger, LogLevel } from "effect"
81
+ *
82
+ * const logger = Logger.make(({ logLevel, message }) => {
83
+ * globalThis.console.log(`[${logLevel.label}] ${message}`)
84
+ * })
85
+ *
86
+ * const task1 = Effect.logDebug("task1 done")
87
+ * const task2 = Effect.logDebug("task2 done")
88
+ *
89
+ * const program = Effect.gen(function*() {
90
+ * yield* Effect.log("start")
91
+ * yield* task1
92
+ * yield* task2
93
+ * yield* Effect.log("done")
94
+ * }).pipe(
95
+ * Logger.withMinimumLogLevel(LogLevel.Debug),
96
+ * Effect.provide(Logger.replace(Logger.defaultLogger, logger))
97
+ * )
98
+ *
99
+ * // Effect.runFork(program)
100
+ * // [INFO] start
101
+ * // [DEBUG] task1 done
102
+ * // [DEBUG] task2 done
103
+ * // [INFO] done
104
+ *
76
105
  * @category constructors
77
106
  * @since 2.0.0
78
107
  */
@@ -160,25 +189,36 @@ export const map: {
160
189
  } = internal.map
161
190
 
162
191
  /**
163
- * @since 2.0.0
164
- * @category mapping
192
+ * Creates a batched logger that groups log messages together and processes them
193
+ * in intervals.
194
+ *
195
+ * @param window - The time window in which to batch log messages.
196
+ *
165
197
  * @example
166
- * import { Console, Effect, Logger } from "effect";
198
+ * import { Console, Effect, Logger } from "effect"
167
199
  *
168
200
  * const LoggerLive = Logger.replaceScoped(
169
201
  * Logger.defaultLogger,
170
202
  * Logger.logfmtLogger.pipe(
171
- * Logger.batched("500 millis", (messages) =>
172
- * Console.log("BATCH", messages.join("\n"))
173
- * )
203
+ * Logger.batched("500 millis", (messages) => Console.log("BATCH", `[\n${messages.join("\n")}\n]`))
174
204
  * )
175
- * );
205
+ * )
206
+ *
207
+ * const program = Effect.gen(function*() {
208
+ * yield* Effect.log("one")
209
+ * yield* Effect.log("two")
210
+ * yield* Effect.log("three")
211
+ * }).pipe(Effect.provide(LoggerLive))
212
+ *
213
+ * // Effect.runFork(program)
214
+ * // BATCH [
215
+ * // timestamp=... level=INFO fiber=#0 message=one
216
+ * // timestamp=... level=INFO fiber=#0 message=two
217
+ * // timestamp=... level=INFO fiber=#0 message=three
218
+ * // ]
176
219
  *
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);
220
+ * @since 2.0.0
221
+ * @category mapping
182
222
  */
183
223
  export const batched: {
184
224
  <Output, R>(
@@ -278,6 +318,17 @@ export const test: {
278
318
  } = internalCircular.test
279
319
 
280
320
  /**
321
+ * Sets the minimum log level for subsequent logging operations, allowing
322
+ * control over which log messages are displayed based on their severity.
323
+ *
324
+ * @example
325
+ * import { Effect, Logger, LogLevel } from "effect"
326
+ *
327
+ * const program = Effect.logDebug("message1").pipe(Logger.withMinimumLogLevel(LogLevel.Debug))
328
+ *
329
+ * // Effect.runFork(program)
330
+ * // timestamp=... level=DEBUG fiber=#0 message=message1
331
+ *
281
332
  * @since 2.0.0
282
333
  * @category context
283
334
  */
@@ -345,12 +396,40 @@ export const zipRight: {
345
396
  export const defaultLogger: Logger<unknown, void> = fiberRuntime.defaultLogger
346
397
 
347
398
  /**
399
+ * The `jsonLogger` logger formats log entries as JSON objects, making them easy to
400
+ * integrate with logging systems that consume JSON data.
401
+ *
402
+ * @example
403
+ * import { Effect, Logger } from "effect"
404
+ *
405
+ * const program = Effect.log("message1", "message2").pipe(
406
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
407
+ * Effect.withLogSpan("myspan")
408
+ * )
409
+ *
410
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.json)))
411
+ * // {"message":["message1","message2"],"logLevel":"INFO","timestamp":"...","annotations":{"key2":"value2","key1":"value1"},"spans":{"myspan":0},"fiberId":"#0"}
412
+ *
348
413
  * @since 2.0.0
349
414
  * @category constructors
350
415
  */
351
416
  export const jsonLogger: Logger<unknown, string> = internal.jsonLogger
352
417
 
353
418
  /**
419
+ * This logger outputs logs in a human-readable format that is easy to read
420
+ * during development or in a production console.
421
+ *
422
+ * @example
423
+ * import { Effect, Logger } from "effect"
424
+ *
425
+ * const program = Effect.log("message1", "message2").pipe(
426
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
427
+ * Effect.withLogSpan("myspan")
428
+ * )
429
+ *
430
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.logFmt)))
431
+ * // timestamp=... level=INFO fiber=#0 message=message1 message=message2 myspan=0ms key2=value2 key1=value1
432
+ *
354
433
  * @since 2.0.0
355
434
  * @category constructors
356
435
  */
@@ -363,6 +442,63 @@ export const logfmtLogger: Logger<unknown, string> = internal.logfmtLogger
363
442
  export const stringLogger: Logger<unknown, string> = internal.stringLogger
364
443
 
365
444
  /**
445
+ * The pretty logger utilizes the capabilities of the console API to generate
446
+ * visually engaging and color-enhanced log outputs. This feature is
447
+ * particularly useful for improving the readability of log messages during
448
+ * development and debugging processes.
449
+ *
450
+ * @example
451
+ * import { Effect, Logger } from "effect"
452
+ *
453
+ * const program = Effect.log("message1", "message2").pipe(
454
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
455
+ * Effect.withLogSpan("myspan")
456
+ * )
457
+ *
458
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.pretty)))
459
+ * // green --v v-- bold and cyan
460
+ * // [07:51:54.434] INFO (#0) myspan=1ms: message1
461
+ * // message2
462
+ * // v-- bold
463
+ * // key2: value2
464
+ * // key1: value1
465
+ *
466
+ * @since 3.5.0
467
+ * @category constructors
468
+ */
469
+ export const prettyLogger: (
470
+ options?: {
471
+ readonly colors?: "auto" | boolean | undefined
472
+ readonly stderr?: boolean | undefined
473
+ readonly formatDate?: ((date: Date) => string) | undefined
474
+ readonly mode?: "browser" | "tty" | "auto" | undefined
475
+ }
476
+ ) => Logger<unknown, void> = internal.prettyLogger
477
+
478
+ /**
479
+ * The structured logger provides detailed log outputs, structured in a way that
480
+ * retains comprehensive traceability of the events, suitable for deeper
481
+ * analysis and troubleshooting.
482
+ *
483
+ * @example
484
+ * import { Effect, Logger } from "effect"
485
+ *
486
+ * const program = Effect.log("message1", "message2").pipe(
487
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
488
+ * Effect.withLogSpan("myspan")
489
+ * )
490
+ *
491
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.structured)))
492
+ * // {
493
+ * // message: [ 'message1', 'message2' ],
494
+ * // logLevel: 'INFO',
495
+ * // timestamp: '2024-07-09T14:05:41.623Z',
496
+ * // cause: undefined,
497
+ * // annotations: { key2: 'value2', key1: 'value1' },
498
+ * // spans: { myspan: 0 },
499
+ * // fiberId: '#0'
500
+ * // }
501
+ *
366
502
  * @since 2.0.0
367
503
  * @category constructors
368
504
  */
@@ -386,24 +522,118 @@ export const structuredLogger: Logger<
386
522
  export const tracerLogger: Logger<unknown, void> = fiberRuntime.tracerLogger
387
523
 
388
524
  /**
525
+ * The `json` logger formats log entries as JSON objects, making them easy to
526
+ * integrate with logging systems that consume JSON data.
527
+ *
528
+ * @example
529
+ * import { Effect, Logger } from "effect"
530
+ *
531
+ * const program = Effect.log("message1", "message2").pipe(
532
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
533
+ * Effect.withLogSpan("myspan")
534
+ * )
535
+ *
536
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.json)))
537
+ * // {"message":["message1","message2"],"logLevel":"INFO","timestamp":"...","annotations":{"key2":"value2","key1":"value1"},"spans":{"myspan":0},"fiberId":"#0"}
538
+ *
389
539
  * @since 2.0.0
390
540
  * @category constructors
391
541
  */
392
542
  export const json: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.jsonLogger)
393
543
 
394
544
  /**
545
+ * This logger outputs logs in a human-readable format that is easy to read
546
+ * during development or in a production console.
547
+ *
548
+ * @example
549
+ * import { Effect, Logger } from "effect"
550
+ *
551
+ * const program = Effect.log("message1", "message2").pipe(
552
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
553
+ * Effect.withLogSpan("myspan")
554
+ * )
555
+ *
556
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.logFmt)))
557
+ * // timestamp=... level=INFO fiber=#0 message=message1 message=message2 myspan=0ms key2=value2 key1=value1
558
+ *
395
559
  * @since 2.0.0
396
560
  * @category constructors
397
561
  */
398
562
  export const logFmt: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.logFmtLogger)
399
563
 
400
564
  /**
565
+ * The pretty logger utilizes the capabilities of the console API to generate
566
+ * visually engaging and color-enhanced log outputs. This feature is
567
+ * particularly useful for improving the readability of log messages during
568
+ * development and debugging processes.
569
+ *
570
+ * @example
571
+ * import { Effect, Logger } from "effect"
572
+ *
573
+ * const program = Effect.log("message1", "message2").pipe(
574
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
575
+ * Effect.withLogSpan("myspan")
576
+ * )
577
+ *
578
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.pretty)))
579
+ * // green --v v-- bold and cyan
580
+ * // [07:51:54.434] INFO (#0) myspan=1ms: message1
581
+ * // message2
582
+ * // v-- bold
583
+ * // key2: value2
584
+ * // key1: value1
585
+ *
586
+ * @since 3.5.0
587
+ * @category constructors
588
+ */
589
+ export const pretty: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.prettyLogger)
590
+
591
+ /**
592
+ * The structured logger provides detailed log outputs, structured in a way that
593
+ * retains comprehensive traceability of the events, suitable for deeper
594
+ * analysis and troubleshooting.
595
+ *
596
+ * @example
597
+ * import { Effect, Logger } from "effect"
598
+ *
599
+ * const program = Effect.log("message1", "message2").pipe(
600
+ * Effect.annotateLogs({ key1: "value1", key2: "value2" }),
601
+ * Effect.withLogSpan("myspan")
602
+ * )
603
+ *
604
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.structured)))
605
+ * // {
606
+ * // message: [ 'message1', 'message2' ],
607
+ * // logLevel: 'INFO',
608
+ * // timestamp: '2024-07-09T14:05:41.623Z',
609
+ * // cause: undefined,
610
+ * // annotations: { key2: 'value2', key1: 'value1' },
611
+ * // spans: { myspan: 0 },
612
+ * // fiberId: '#0'
613
+ * // }
614
+ *
401
615
  * @since 2.0.0
402
616
  * @category constructors
403
617
  */
404
618
  export const structured: Layer.Layer<never> = replace(fiberRuntime.defaultLogger, fiberRuntime.structuredLogger)
405
619
 
406
620
  /**
621
+ * Sets the minimum log level for logging operations, allowing control over
622
+ * which log messages are displayed based on their severity.
623
+ *
624
+ * @example
625
+ * import { Effect, Logger, LogLevel } from "effect"
626
+ *
627
+ * const program = Effect.gen(function*() {
628
+ * yield* Effect.log("Executing task...")
629
+ * yield* Effect.sleep("100 millis")
630
+ * console.log("task done")
631
+ * })
632
+ *
633
+ * // Logging disabled using a layer
634
+ * // Effect.runFork(program.pipe(Effect.provide(Logger.minimumLogLevel(LogLevel.None))))
635
+ * // task done
636
+ *
407
637
  * @since 2.0.0
408
638
  * @category context
409
639
  */