effect 2.4.1 → 2.4.3

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 (130) hide show
  1. package/ManagedRuntime/package.json +6 -0
  2. package/dist/cjs/Context.js.map +1 -1
  3. package/dist/cjs/Duration.js +9 -1
  4. package/dist/cjs/Duration.js.map +1 -1
  5. package/dist/cjs/Effect.js +51 -5
  6. package/dist/cjs/Effect.js.map +1 -1
  7. package/dist/cjs/Either.js.map +1 -1
  8. package/dist/cjs/FiberMap.js +31 -5
  9. package/dist/cjs/FiberMap.js.map +1 -1
  10. package/dist/cjs/FiberSet.js +31 -5
  11. package/dist/cjs/FiberSet.js.map +1 -1
  12. package/dist/cjs/Layer.js +9 -1
  13. package/dist/cjs/Layer.js.map +1 -1
  14. package/dist/cjs/Logger.js +50 -1
  15. package/dist/cjs/Logger.js.map +1 -1
  16. package/dist/cjs/ManagedRuntime.js +58 -0
  17. package/dist/cjs/ManagedRuntime.js.map +1 -0
  18. package/dist/cjs/Option.js.map +1 -1
  19. package/dist/cjs/Request.js +4 -4
  20. package/dist/cjs/SortedSet.js +7 -1
  21. package/dist/cjs/SortedSet.js.map +1 -1
  22. package/dist/cjs/Struct.js +7 -6
  23. package/dist/cjs/Struct.js.map +1 -1
  24. package/dist/cjs/index.js +4 -2
  25. package/dist/cjs/index.js.map +1 -1
  26. package/dist/cjs/internal/core-effect.js.map +1 -1
  27. package/dist/cjs/internal/fiberRuntime.js +26 -1
  28. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  29. package/dist/cjs/internal/layer.js +7 -4
  30. package/dist/cjs/internal/layer.js.map +1 -1
  31. package/dist/cjs/internal/logger.js +64 -2
  32. package/dist/cjs/internal/logger.js.map +1 -1
  33. package/dist/cjs/internal/managedRuntime.js +94 -0
  34. package/dist/cjs/internal/managedRuntime.js.map +1 -0
  35. package/dist/cjs/internal/version.js +1 -1
  36. package/dist/dts/Context.d.ts +10 -11
  37. package/dist/dts/Context.d.ts.map +1 -1
  38. package/dist/dts/Duration.d.ts +1 -1
  39. package/dist/dts/Duration.d.ts.map +1 -1
  40. package/dist/dts/Effect.d.ts +23 -15
  41. package/dist/dts/Effect.d.ts.map +1 -1
  42. package/dist/dts/Either.d.ts +18 -3
  43. package/dist/dts/Either.d.ts.map +1 -1
  44. package/dist/dts/FiberMap.d.ts +22 -2
  45. package/dist/dts/FiberMap.d.ts.map +1 -1
  46. package/dist/dts/FiberSet.d.ts +20 -0
  47. package/dist/dts/FiberSet.d.ts.map +1 -1
  48. package/dist/dts/Layer.d.ts +11 -0
  49. package/dist/dts/Layer.d.ts.map +1 -1
  50. package/dist/dts/Logger.d.ts +61 -0
  51. package/dist/dts/Logger.d.ts.map +1 -1
  52. package/dist/dts/ManagedRuntime.d.ts +96 -0
  53. package/dist/dts/ManagedRuntime.d.ts.map +1 -0
  54. package/dist/dts/Option.d.ts +13 -3
  55. package/dist/dts/Option.d.ts.map +1 -1
  56. package/dist/dts/Request.d.ts +7 -7
  57. package/dist/dts/Request.d.ts.map +1 -1
  58. package/dist/dts/STM.d.ts +1 -1
  59. package/dist/dts/STM.d.ts.map +1 -1
  60. package/dist/dts/SortedSet.d.ts +6 -0
  61. package/dist/dts/SortedSet.d.ts.map +1 -1
  62. package/dist/dts/Struct.d.ts +18 -2
  63. package/dist/dts/Struct.d.ts.map +1 -1
  64. package/dist/dts/Types.d.ts +4 -0
  65. package/dist/dts/Types.d.ts.map +1 -1
  66. package/dist/dts/index.d.ts +4 -0
  67. package/dist/dts/index.d.ts.map +1 -1
  68. package/dist/dts/internal/logger.d.ts +1 -0
  69. package/dist/dts/internal/logger.d.ts.map +1 -1
  70. package/dist/dts/internal/managedRuntime.d.ts +2 -0
  71. package/dist/dts/internal/managedRuntime.d.ts.map +1 -0
  72. package/dist/esm/Context.js.map +1 -1
  73. package/dist/esm/Duration.js +9 -1
  74. package/dist/esm/Duration.js.map +1 -1
  75. package/dist/esm/Effect.js +46 -1
  76. package/dist/esm/Effect.js.map +1 -1
  77. package/dist/esm/Either.js.map +1 -1
  78. package/dist/esm/FiberMap.js +29 -4
  79. package/dist/esm/FiberMap.js.map +1 -1
  80. package/dist/esm/FiberSet.js +29 -4
  81. package/dist/esm/FiberSet.js.map +1 -1
  82. package/dist/esm/Layer.js +8 -0
  83. package/dist/esm/Layer.js.map +1 -1
  84. package/dist/esm/Logger.js +49 -0
  85. package/dist/esm/Logger.js.map +1 -1
  86. package/dist/esm/ManagedRuntime.js +27 -0
  87. package/dist/esm/ManagedRuntime.js.map +1 -0
  88. package/dist/esm/Option.js.map +1 -1
  89. package/dist/esm/Request.js +4 -4
  90. package/dist/esm/SortedSet.js +5 -0
  91. package/dist/esm/SortedSet.js.map +1 -1
  92. package/dist/esm/Struct.js +7 -4
  93. package/dist/esm/Struct.js.map +1 -1
  94. package/dist/esm/index.js +4 -0
  95. package/dist/esm/index.js.map +1 -1
  96. package/dist/esm/internal/core-effect.js.map +1 -1
  97. package/dist/esm/internal/fiberRuntime.js +25 -0
  98. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  99. package/dist/esm/internal/layer.js +5 -3
  100. package/dist/esm/internal/layer.js.map +1 -1
  101. package/dist/esm/internal/logger.js +61 -1
  102. package/dist/esm/internal/logger.js.map +1 -1
  103. package/dist/esm/internal/managedRuntime.js +62 -0
  104. package/dist/esm/internal/managedRuntime.js.map +1 -0
  105. package/dist/esm/internal/version.js +1 -1
  106. package/package.json +10 -2
  107. package/src/Context.ts +10 -11
  108. package/src/Duration.ts +17 -1
  109. package/src/Effect.ts +92 -22
  110. package/src/Either.ts +19 -3
  111. package/src/FiberMap.ts +44 -6
  112. package/src/FiberSet.ts +38 -4
  113. package/src/Layer.ts +17 -0
  114. package/src/Logger.ts +77 -0
  115. package/src/ManagedRuntime.ts +115 -0
  116. package/src/Option.ts +14 -3
  117. package/src/Request.ts +7 -7
  118. package/src/STM.ts +1 -1
  119. package/src/SortedSet.ts +7 -0
  120. package/src/Struct.ts +40 -21
  121. package/src/Types.ts +5 -0
  122. package/src/index.ts +5 -0
  123. package/src/internal/core-effect.ts +9 -9
  124. package/src/internal/core.ts +5 -5
  125. package/src/internal/fiberRuntime.ts +68 -0
  126. package/src/internal/layer.ts +25 -4
  127. package/src/internal/logger.ts +76 -1
  128. package/src/internal/managedRuntime.ts +111 -0
  129. package/src/internal/request.ts +2 -2
  130. package/src/internal/version.ts +1 -1
package/src/Effect.ts CHANGED
@@ -24,6 +24,7 @@ import type * as HashMap from "./HashMap.js"
24
24
  import type * as HashSet from "./HashSet.js"
25
25
  import type { TypeLambda } from "./HKT.js"
26
26
  import * as _console from "./internal/console.js"
27
+ import { TagProto } from "./internal/context.js"
27
28
  import * as effect from "./internal/core-effect.js"
28
29
  import * as core from "./internal/core.js"
29
30
  import * as defaultServices from "./internal/defaultServices.js"
@@ -42,7 +43,7 @@ import type { Pipeable } from "./Pipeable.js"
42
43
  import type { Predicate, Refinement } from "./Predicate.js"
43
44
  import type * as Random from "./Random.js"
44
45
  import type * as Ref from "./Ref.js"
45
- import type * as Request from "./Request.js"
46
+ import * as Request from "./Request.js"
46
47
  import type { RequestBlock } from "./RequestBlock.js"
47
48
  import type { RequestResolver } from "./RequestResolver.js"
48
49
  import type * as Runtime from "./Runtime.js"
@@ -53,7 +54,7 @@ import * as Scheduler from "./Scheduler.js"
53
54
  import type * as Scope from "./Scope.js"
54
55
  import type * as Supervisor from "./Supervisor.js"
55
56
  import type * as Tracer from "./Tracer.js"
56
- import type { Concurrency, Covariant, MergeRecord, NoInfer } from "./Types.js"
57
+ import type { Concurrency, Covariant, MergeRecord, NoInfer, NotFunction } from "./Types.js"
57
58
  import type * as Unify from "./Unify.js"
58
59
 
59
60
  // -------------------------------------------------------------------------------------
@@ -137,7 +138,7 @@ export interface Blocked<out A, out E> extends Effect<A, E> {
137
138
  * @category models
138
139
  */
139
140
  declare module "./Context.js" {
140
- interface Tag<Identifier, Service> extends Effect<Service, never, Identifier> {}
141
+ interface Tag<Id, Value> extends Effect<Value, never, Id> {}
141
142
  interface TagUnifyIgnore {
142
143
  Effect?: true
143
144
  Either?: true
@@ -3103,11 +3104,10 @@ export const serviceFunctionEffect: <T extends Effect<any, any, any>, Args exten
3103
3104
  export const serviceFunctions: <S, SE, SR>(
3104
3105
  getService: Effect<S, SE, SR>
3105
3106
  ) => {
3106
- [k in { [k in keyof S]: S[k] extends (...args: Array<any>) => Effect<any, any, any> ? k : never }[keyof S]]:
3107
- S[k] extends (...args: infer Args) => Effect<infer A, infer E, infer R> ?
3108
- (...args: Args) => Effect<A, SE | E, SR | R> :
3109
- never
3110
- } = effect.serviceFunctions
3107
+ [k in keyof S as S[k] extends (...args: Array<any>) => Effect<any, any, any> ? k : never]: S[k] extends
3108
+ (...args: infer Args) => Effect<infer A, infer E, infer R> ? (...args: Args) => Effect<A, SE | E, SR | R>
3109
+ : never
3110
+ } = effect.serviceFunctions as any
3111
3111
 
3112
3112
  /**
3113
3113
  * @since 2.0.0
@@ -3124,20 +3124,19 @@ export const serviceConstants: <S, SE, SR>(
3124
3124
  * @since 2.0.0
3125
3125
  * @category context
3126
3126
  */
3127
- export const serviceMembers: <SR, SE, S>(
3127
+ export const serviceMembers: <S, SE, SR>(
3128
3128
  getService: Effect<S, SE, SR>
3129
3129
  ) => {
3130
3130
  functions: {
3131
- [k in { [k in keyof S]: S[k] extends (...args: Array<any>) => Effect<any, any, any> ? k : never }[keyof S]]:
3132
- S[k] extends (...args: infer Args) => Effect<infer A, infer E, infer R> ?
3133
- (...args: Args) => Effect<A, SE | E, SR | R>
3134
- : never
3131
+ [k in keyof S as S[k] extends (...args: Array<any>) => Effect<any, any, any> ? k : never]: S[k] extends
3132
+ (...args: infer Args) => Effect<infer A, infer E, infer R> ? (...args: Args) => Effect<A, SE | E, SR | R>
3133
+ : never
3135
3134
  }
3136
3135
  constants: {
3137
3136
  [k in { [k in keyof S]: k }[keyof S]]: S[k] extends Effect<infer A, infer E, infer R> ? Effect<A, SE | E, SR | R>
3138
3137
  : Effect<S[k], SE, SR>
3139
3138
  }
3140
- } = effect.serviceMembers
3139
+ } = effect.serviceMembers as any
3141
3140
 
3142
3141
  /**
3143
3142
  * @since 2.0.0
@@ -3558,7 +3557,7 @@ export const andThen: {
3558
3557
  : [X] extends [Promise<infer A1>] ? Effect<A1, E | Cause.UnknownException, R>
3559
3558
  : Effect<X, E, R>
3560
3559
  <X>(
3561
- f: X
3560
+ f: NotFunction<X>
3562
3561
  ): <A, E, R>(
3563
3562
  self: Effect<A, E, R>
3564
3563
  ) => [X] extends [Effect<infer A1, infer E1, infer R1>] ? Effect<A1, E | E1, R | R1>
@@ -3572,7 +3571,7 @@ export const andThen: {
3572
3571
  : Effect<X, E, R>
3573
3572
  <A, E, R, X>(
3574
3573
  self: Effect<A, E, R>,
3575
- f: X
3574
+ f: NotFunction<X>
3576
3575
  ): [X] extends [Effect<infer A1, infer E1, infer R1>] ? Effect<A1, E | E1, R | R1>
3577
3576
  : [X] extends [Promise<infer A1>] ? Effect<A1, E | Cause.UnknownException, R>
3578
3577
  : Effect<X, E, R>
@@ -3687,7 +3686,7 @@ export const tap: {
3687
3686
  : [X] extends [Promise<infer _A1>] ? Effect<A, E | Cause.UnknownException, R>
3688
3687
  : Effect<A, E, R>
3689
3688
  <X>(
3690
- f: X
3689
+ f: NotFunction<X>
3691
3690
  ): <A, E, R>(
3692
3691
  self: Effect<A, E, R>
3693
3692
  ) => [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1>
@@ -3701,7 +3700,7 @@ export const tap: {
3701
3700
  : Effect<A, E, R>
3702
3701
  <A, E, R, X>(
3703
3702
  self: Effect<A, E, R>,
3704
- f: X
3703
+ f: NotFunction<X>
3705
3704
  ): [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1>
3706
3705
  : [X] extends [Promise<infer _A1>] ? Effect<A, E | Cause.UnknownException, R>
3707
3706
  : Effect<A, E, R>
@@ -4914,18 +4913,27 @@ export const step: <A, E, R>(self: Effect<A, E, R>) => Effect<Exit.Exit<A, E> |
4914
4913
  * @category requests & batching
4915
4914
  */
4916
4915
  export const request: {
4916
+ <A extends Request.Request<any, any>, Ds extends RequestResolver<A> | Effect<RequestResolver<A>, any, any>>(
4917
+ dataSource: Ds
4918
+ ): (
4919
+ self: A
4920
+ ) => Effect<
4921
+ Request.Request.Success<A>,
4922
+ Request.Request.Error<A>,
4923
+ [Ds] extends [Effect<any, any, any>] ? Effect.Context<Ds> : never
4924
+ >
4917
4925
  <
4918
- A extends Request.Request<any, any>,
4919
- Ds extends RequestResolver<A> | Effect<RequestResolver<A>, any, any>
4926
+ Ds extends RequestResolver<A> | Effect<RequestResolver<A>, any, any>,
4927
+ A extends Request.Request<any, any>
4920
4928
  >(
4921
- request: A,
4929
+ self: A,
4922
4930
  dataSource: Ds
4923
4931
  ): Effect<
4924
4932
  Request.Request.Success<A>,
4925
4933
  Request.Request.Error<A>,
4926
4934
  [Ds] extends [Effect<any, any, any>] ? Effect.Context<Ds> : never
4927
4935
  >
4928
- } = query.fromRequest as any
4936
+ } = dual((args) => Request.isRequest(args[0]), query.fromRequest)
4929
4937
 
4930
4938
  /**
4931
4939
  * @since 2.0.0
@@ -5230,3 +5238,65 @@ export const fromNullable: <A>(value: A) => Effect<NonNullable<A>, Cause.NoSuchE
5230
5238
  export const optionFromOptional: <A, E, R>(
5231
5239
  self: Effect<A, E, R>
5232
5240
  ) => Effect<Option.Option<A>, Exclude<E, Cause.NoSuchElementException>, R> = effect.optionFromOptional
5241
+
5242
+ /**
5243
+ * @since 2.0.0
5244
+ * @category constructors
5245
+ */
5246
+ export const Tag: <const Id extends string>(id: Id) => <Self, Type>() =>
5247
+ & Context.TagClass<Self, Id, Type>
5248
+ & (Type extends Record<PropertyKey, any> ? {
5249
+ [
5250
+ k in keyof Type as Type[k] extends ((...args: [...infer Args]) => infer Ret) ?
5251
+ ((...args: Readonly<Args>) => Ret) extends Type[k] ? k : never
5252
+ : k
5253
+ ]: Type[k] extends (...args: [...infer Args]) => Effect<infer A, infer E, infer R> ?
5254
+ (...args: Readonly<Args>) => Effect<A, E, Self | R>
5255
+ : Type[k] extends (...args: [...infer Args]) => infer A ? (...args: Readonly<Args>) => Effect<A, never, Self>
5256
+ : Type[k] extends Effect<infer A, infer E, infer R> ? Effect<A, E, Self | R>
5257
+ : Effect<Type[k], never, Self>
5258
+ } :
5259
+ {})
5260
+ & {
5261
+ use: <X>(
5262
+ body: (_: Type) => X
5263
+ ) => X extends Effect<infer A, infer E, infer R> ? Effect<A, E, R | Self> : Effect<X, never, Self>
5264
+ } = (id) => () => {
5265
+ const limit = Error.stackTraceLimit
5266
+ Error.stackTraceLimit = 2
5267
+ const creationError = new Error()
5268
+ Error.stackTraceLimit = limit
5269
+ function TagClass() {}
5270
+ Object.setPrototypeOf(TagClass, TagProto)
5271
+ TagClass.key = id
5272
+ Object.defineProperty(TagClass, "stack", {
5273
+ get() {
5274
+ return creationError.stack
5275
+ }
5276
+ })
5277
+ const cache = new Map()
5278
+ const done = new Proxy(TagClass, {
5279
+ get(_target: any, prop: any, _receiver) {
5280
+ if (prop === "use") {
5281
+ // @ts-expect-error
5282
+ return (body) => core.andThen(TagClass, body)
5283
+ }
5284
+ if (prop in TagClass) {
5285
+ // @ts-expect-error
5286
+ return TagClass[prop]
5287
+ }
5288
+ if (cache.has(prop)) {
5289
+ return cache.get(prop)
5290
+ }
5291
+ // @ts-expect-error
5292
+ const fn = (...args: Array<any>) => core.andThen(TagClass, (s: any) => s[prop](...args))
5293
+ // @ts-expect-error
5294
+ const cn = core.andThen(TagClass, (s) => s[prop])
5295
+ Object.assign(fn, cn)
5296
+ Object.setPrototypeOf(fn, Object.getPrototypeOf(cn))
5297
+ cache.set(prop, fn)
5298
+ return fn
5299
+ }
5300
+ })
5301
+ return done
5302
+ }
package/src/Either.ts CHANGED
@@ -12,7 +12,7 @@ import type { Option } from "./Option.js"
12
12
  import type { Pipeable } from "./Pipeable.js"
13
13
  import type { Predicate, Refinement } from "./Predicate.js"
14
14
  import { isFunction } from "./Predicate.js"
15
- import type { Covariant, MergeRecord, NoInfer } from "./Types.js"
15
+ import type { Covariant, MergeRecord, NoInfer, NotFunction } from "./Types.js"
16
16
  import type * as Unify from "./Unify.js"
17
17
  import * as Gen from "./Utils.js"
18
18
 
@@ -90,6 +90,22 @@ export interface EitherTypeLambda extends TypeLambda {
90
90
  readonly type: Either<this["Target"], this["Out1"]>
91
91
  }
92
92
 
93
+ /**
94
+ * @since 2.0.0
95
+ */
96
+ export declare namespace Either {
97
+ /**
98
+ * @since 2.0.0
99
+ * @category type-level
100
+ */
101
+ export type Left<T extends Either<any, any>> = [T] extends [Either<infer _A, infer _E>] ? _E : never
102
+ /**
103
+ * @since 2.0.0
104
+ * @category type-level
105
+ */
106
+ export type Right<T extends Either<any, any>> = [T] extends [Either<infer _A, infer _E>] ? _A : never
107
+ }
108
+
93
109
  /**
94
110
  * Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias
95
111
  * of this structure.
@@ -571,11 +587,11 @@ export const andThen: {
571
587
  <R, R2, L2>(f: (right: R) => Either<R2, L2>): <L>(self: Either<R, L>) => Either<R2, L | L2>
572
588
  <R2, L2>(f: Either<R2, L2>): <L, R1>(self: Either<R1, L>) => Either<R2, L | L2>
573
589
  <R, R2>(f: (right: R) => R2): <L>(self: Either<R, L>) => Either<R2, L>
574
- <R2>(right: R2): <R1, L>(self: Either<R1, L>) => Either<R2, L>
590
+ <R2>(right: NotFunction<R2>): <R1, L>(self: Either<R1, L>) => Either<R2, L>
575
591
  <R, L, R2, L2>(self: Either<R, L>, f: (right: R) => Either<R2, L2>): Either<R2, L | L2>
576
592
  <R, L, R2, L2>(self: Either<R, L>, f: Either<R2, L2>): Either<R2, L | L2>
577
593
  <R, L, R2>(self: Either<R, L>, f: (right: R) => R2): Either<R2, L>
578
- <R, L, R2>(self: Either<R, L>, f: R2): Either<R2, L>
594
+ <R, L, R2>(self: Either<R, L>, f: NotFunction<R2>): Either<R2, L>
579
595
  } = dual(
580
596
  2,
581
597
  <R, L, R2, L2>(self: Either<R, L>, f: (right: R) => Either<R2, L2> | Either<R2, L2>): Either<R2, L | L2> =>
package/src/FiberMap.ts CHANGED
@@ -4,6 +4,9 @@
4
4
  import * as Effect from "effect/Effect"
5
5
  import type * as Scope from "effect/Scope"
6
6
  import type { NoSuchElementException } from "./Cause.js"
7
+ import * as Cause from "./Cause.js"
8
+ import * as Deferred from "./Deferred.js"
9
+ import * as Exit from "./Exit.js"
7
10
  import * as Fiber from "./Fiber.js"
8
11
  import * as FiberId from "./FiberId.js"
9
12
  import { dual } from "./Function.js"
@@ -30,11 +33,12 @@ export type TypeId = typeof TypeId
30
33
  * @since 2.0.0
31
34
  * @categories models
32
35
  */
33
- export interface FiberMap<K, A = unknown, E = unknown>
36
+ export interface FiberMap<in out K, out A = unknown, out E = unknown>
34
37
  extends Pipeable, Inspectable.Inspectable, Iterable<[K, Fiber.RuntimeFiber<A, E>]>
35
38
  {
36
39
  readonly [TypeId]: TypeId
37
40
  readonly backing: MutableHashMap.MutableHashMap<K, Fiber.RuntimeFiber<A, E>>
41
+ readonly deferred: Deferred.Deferred<never, unknown>
38
42
  }
39
43
 
40
44
  /**
@@ -65,9 +69,13 @@ const Proto = {
65
69
  }
66
70
  }
67
71
 
68
- const unsafeMake = <K, A = unknown, E = unknown>(): FiberMap<K, A, E> => {
72
+ const unsafeMake = <K, A = unknown, E = unknown>(
73
+ backing: MutableHashMap.MutableHashMap<K, Fiber.RuntimeFiber<A, E>>,
74
+ deferred: Deferred.Deferred<never, E>
75
+ ): FiberMap<K, A, E> => {
69
76
  const self = Object.create(Proto)
70
- self.backing = MutableHashMap.empty()
77
+ self.backing = backing
78
+ self.deferred = deferred
71
79
  return self
72
80
  }
73
81
 
@@ -97,7 +105,14 @@ const unsafeMake = <K, A = unknown, E = unknown>(): FiberMap<K, A, E> => {
97
105
  * @categories constructors
98
106
  */
99
107
  export const make = <K, A = unknown, E = unknown>(): Effect.Effect<FiberMap<K, A, E>, never, Scope.Scope> =>
100
- Effect.acquireRelease(Effect.sync(() => unsafeMake<K, A, E>()), clear)
108
+ Effect.acquireRelease(
109
+ Effect.map(Deferred.make<never, E>(), (deferred) =>
110
+ unsafeMake<K, A, E>(
111
+ MutableHashMap.empty(),
112
+ deferred
113
+ )),
114
+ clear
115
+ )
101
116
 
102
117
  /**
103
118
  * Create an Effect run function that is backed by a FiberMap.
@@ -159,11 +174,14 @@ export const unsafeSet: {
159
174
  previous.value.unsafeInterruptAsFork(interruptAs ?? FiberId.none)
160
175
  }
161
176
  MutableHashMap.set(self.backing, key, fiber)
162
- fiber.addObserver((_) => {
177
+ fiber.addObserver((exit) => {
163
178
  const current = MutableHashMap.get(self.backing, key)
164
179
  if (Option.isSome(current) && fiber === current.value) {
165
180
  MutableHashMap.remove(self.backing, key)
166
181
  }
182
+ if (Exit.isFailure(exit) && !Cause.isInterruptedOnly(exit.cause)) {
183
+ Deferred.unsafeDone(self.deferred, exit as any)
184
+ }
167
185
  })
168
186
  })
169
187
 
@@ -372,5 +390,25 @@ export const runtime: <K, A, E>(
372
390
  * @since 2.0.0
373
391
  * @categories combinators
374
392
  */
375
- export const size = <K, E, A>(self: FiberMap<K, E, A>): Effect.Effect<number> =>
393
+ export const size = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<number> =>
376
394
  Effect.sync(() => MutableHashMap.size(self.backing))
395
+
396
+ /**
397
+ * Join all fibers in the FiberMap. If any of the Fiber's in the map terminate with a failure,
398
+ * the returned Effect will terminate with the first failure that occurred.
399
+ *
400
+ * @since 2.0.0
401
+ * @categories combinators
402
+ * @example
403
+ * import { Effect, FiberMap } from "effect";
404
+ *
405
+ * Effect.gen(function* (_) {
406
+ * const map = yield* _(FiberMap.make());
407
+ * yield* _(FiberMap.set(map, "a", Effect.runFork(Effect.fail("error"))));
408
+ *
409
+ * // parent fiber will fail with "error"
410
+ * yield* _(FiberMap.join(map));
411
+ * });
412
+ */
413
+ export const join = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<never, E> =>
414
+ Deferred.await(self.deferred as Deferred.Deferred<never, E>)
package/src/FiberSet.ts CHANGED
@@ -3,6 +3,9 @@
3
3
  */
4
4
  import * as Effect from "effect/Effect"
5
5
  import type * as Scope from "effect/Scope"
6
+ import * as Cause from "./Cause.js"
7
+ import * as Deferred from "./Deferred.js"
8
+ import * as Exit from "./Exit.js"
6
9
  import * as Fiber from "./Fiber.js"
7
10
  import { dual } from "./Function.js"
8
11
  import * as Inspectable from "./Inspectable.js"
@@ -31,6 +34,7 @@ export interface FiberSet<out A = unknown, out E = unknown>
31
34
  {
32
35
  readonly [TypeId]: TypeId
33
36
  readonly backing: Set<Fiber.RuntimeFiber<A, E>>
37
+ readonly deferred: Deferred.Deferred<never, unknown>
34
38
  }
35
39
 
36
40
  /**
@@ -61,9 +65,13 @@ const Proto = {
61
65
  }
62
66
  }
63
67
 
64
- const unsafeMake = <A, E>(): FiberSet<A, E> => {
68
+ const unsafeMake = <A, E>(
69
+ backing: Set<Fiber.RuntimeFiber<A, E>>,
70
+ deferred: Deferred.Deferred<never, unknown>
71
+ ): FiberSet<A, E> => {
65
72
  const self = Object.create(Proto)
66
- self.backing = new Set()
73
+ self.backing = backing
74
+ self.deferred = deferred
67
75
  return self
68
76
  }
69
77
 
@@ -93,7 +101,10 @@ const unsafeMake = <A, E>(): FiberSet<A, E> => {
93
101
  * @categories constructors
94
102
  */
95
103
  export const make = <A = unknown, E = unknown>(): Effect.Effect<FiberSet<A, E>, never, Scope.Scope> =>
96
- Effect.acquireRelease(Effect.sync(() => unsafeMake<A, E>()), clear)
104
+ Effect.acquireRelease(
105
+ Effect.map(Deferred.make<never, unknown>(), (deferred) => unsafeMake(new Set(), deferred)),
106
+ clear
107
+ )
97
108
 
98
109
  /**
99
110
  * Create an Effect run function that is backed by a FiberSet.
@@ -136,8 +147,11 @@ export const unsafeAdd: {
136
147
  return
137
148
  }
138
149
  self.backing.add(fiber)
139
- fiber.addObserver((_) => {
150
+ fiber.addObserver((exit) => {
140
151
  self.backing.delete(fiber)
152
+ if (Exit.isFailure(exit) && !Cause.isInterruptedOnly(exit.cause)) {
153
+ Deferred.unsafeDone(self.deferred, exit as any)
154
+ }
141
155
  })
142
156
  })
143
157
 
@@ -264,3 +278,23 @@ export const runtime: <A, E>(
264
278
  * @categories combinators
265
279
  */
266
280
  export const size = <A, E>(self: FiberSet<A, E>): Effect.Effect<number> => Effect.sync(() => self.backing.size)
281
+
282
+ /**
283
+ * Join all fibers in the FiberSet. If any of the Fiber's in the set terminate with a failure,
284
+ * the returned Effect will terminate with the first failure that occurred.
285
+ *
286
+ * @since 2.0.0
287
+ * @categories combinators
288
+ * @example
289
+ * import { Effect, FiberSet } from "effect";
290
+ *
291
+ * Effect.gen(function* (_) {
292
+ * const set = yield* _(FiberSet.make());
293
+ * yield* _(FiberSet.add(set, Effect.runFork(Effect.fail("error"))));
294
+ *
295
+ * // parent fiber will fail with "error"
296
+ * yield* _(FiberSet.join(set));
297
+ * });
298
+ */
299
+ export const join = <A, E>(self: FiberSet<A, E>): Effect.Effect<never, E> =>
300
+ Deferred.await(self.deferred as Deferred.Deferred<never, E>)
package/src/Layer.ts CHANGED
@@ -784,6 +784,23 @@ export const toRuntime: <RIn, E, ROut>(
784
784
  self: Layer<ROut, E, RIn>
785
785
  ) => Effect.Effect<Runtime.Runtime<ROut>, E, Scope.Scope | RIn> = internal.toRuntime
786
786
 
787
+ /**
788
+ * Converts a layer that requires no services into a scoped runtime, which can
789
+ * be used to execute effects.
790
+ *
791
+ * @since 2.0.0
792
+ * @category conversions
793
+ */
794
+ export const toRuntimeWithMemoMap: {
795
+ (
796
+ memoMap: MemoMap
797
+ ): <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => Effect.Effect<Runtime.Runtime<ROut>, E, Scope.Scope | RIn>
798
+ <RIn, E, ROut>(
799
+ self: Layer<ROut, E, RIn>,
800
+ memoMap: MemoMap
801
+ ): Effect.Effect<Runtime.Runtime<ROut>, E, Scope.Scope | RIn>
802
+ } = internal.toRuntimeWithMemoMap
803
+
787
804
  /**
788
805
  * Feeds the output services of this builder into the input of the specified
789
806
  * builder, resulting in a new builder with the inputs of this builder as
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
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @since 2.0.0
3
+ */
4
+ import type * as Effect from "./Effect.js"
5
+ import type * as Exit from "./Exit.js"
6
+ import type * as Fiber from "./Fiber.js"
7
+ import * as internal from "./internal/managedRuntime.js"
8
+ import type * as Layer from "./Layer.js"
9
+ import type { Pipeable } from "./Pipeable.js"
10
+ import type * as Runtime from "./Runtime.js"
11
+
12
+ /**
13
+ * @since 2.0.0
14
+ * @category models
15
+ */
16
+ export interface ManagedRuntime<in R, out ER> extends Pipeable {
17
+ readonly memoMap: Layer.MemoMap
18
+ readonly runtimeEffect: Effect.Effect<Runtime.Runtime<R>, ER>
19
+ readonly runtime: () => Promise<Runtime.Runtime<R>>
20
+
21
+ /**
22
+ * Executes the effect using the provided Scheduler or using the global
23
+ * Scheduler if not provided
24
+ */
25
+ readonly runFork: <A, E>(
26
+ self: Effect.Effect<A, E, R>,
27
+ options?: Runtime.RunForkOptions
28
+ ) => Fiber.RuntimeFiber<A, E | ER>
29
+
30
+ /**
31
+ * Executes the effect synchronously returning the exit.
32
+ *
33
+ * This method is effectful and should only be invoked at the edges of your
34
+ * program.
35
+ */
36
+ readonly runSyncExit: <A, E>(effect: Effect.Effect<A, E, R>) => Exit.Exit<A, ER | E>
37
+
38
+ /**
39
+ * Executes the effect synchronously throwing in case of errors or async boundaries.
40
+ *
41
+ * This method is effectful and should only be invoked at the edges of your
42
+ * program.
43
+ */
44
+ readonly runSync: <A, E>(effect: Effect.Effect<A, E, R>) => A
45
+
46
+ /**
47
+ * Executes the effect asynchronously, eventually passing the exit value to
48
+ * the specified callback.
49
+ *
50
+ * This method is effectful and should only be invoked at the edges of your
51
+ * program.
52
+ */
53
+ readonly runCallback: <A, E>(
54
+ effect: Effect.Effect<A, E, R>,
55
+ options?: Runtime.RunCallbackOptions<A, E | ER> | undefined
56
+ ) => Runtime.Cancel<A, E | ER>
57
+
58
+ /**
59
+ * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
60
+ * with the value of the effect once the effect has been executed, or will be
61
+ * rejected with the first error or exception throw by the effect.
62
+ *
63
+ * This method is effectful and should only be used at the edges of your
64
+ * program.
65
+ */
66
+ readonly runPromise: <A, E>(effect: Effect.Effect<A, E, R>) => Promise<A>
67
+
68
+ /**
69
+ * Runs the `Effect`, returning a JavaScript `Promise` that will be resolved
70
+ * with the `Exit` state of the effect once the effect has been executed.
71
+ *
72
+ * This method is effectful and should only be used at the edges of your
73
+ * program.
74
+ */
75
+ readonly runPromiseExit: <A, E>(effect: Effect.Effect<A, E, R>) => Promise<Exit.Exit<A, ER | E>>
76
+
77
+ /**
78
+ * Dispose of the resources associated with the runtime.
79
+ */
80
+ readonly dispose: () => Promise<void>
81
+
82
+ /**
83
+ * Dispose of the resources associated with the runtime.
84
+ */
85
+ readonly disposeEffect: Effect.Effect<void, never, never>
86
+ }
87
+
88
+ /**
89
+ * Convert a Layer into an ManagedRuntime, that can be used to run Effect's using
90
+ * your services.
91
+ *
92
+ * @since 2.0.0
93
+ * @category runtime class
94
+ * @example
95
+ * import { Console, Effect, Layer, ManagedRuntime } from "effect"
96
+ *
97
+ * class Notifications extends Effect.Tag("Notifications")<
98
+ * Notifications,
99
+ * { readonly notify: (message: string) => Effect.Effect<void> }
100
+ * >() {
101
+ * static Live = Layer.succeed(this, { notify: (message) => Console.log(message) })
102
+ * }
103
+ *
104
+ * async function main() {
105
+ * const runtime = ManagedRuntime.make(Notifications.Live)
106
+ * await runtime.runPromise(Notifications.notify("Hello, world!"))
107
+ * await runtime.dispose()
108
+ * }
109
+ *
110
+ * main()
111
+ */
112
+ export const make: <R, E>(
113
+ layer: Layer.Layer<R, E, never>,
114
+ memoMap?: Layer.MemoMap | undefined
115
+ ) => ManagedRuntime<R, E> = internal.make