effect 3.8.2 → 3.8.4

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/src/Micro.ts CHANGED
@@ -64,11 +64,11 @@ export type runSymbol = typeof runSymbol
64
64
  */
65
65
  export interface Micro<out A, out E = never, out R = never> extends Effect<A, E, R> {
66
66
  readonly [TypeId]: Micro.Variance<A, E, R>
67
- readonly [runSymbol]: (env: Env<any>, onExit: (exit: MicroExit<A, E>) => void) => void
67
+ [runSymbol](env: Env<any>, onExit: (exit: MicroExit<A, E>) => void): void
68
+ [Symbol.iterator](): MicroIterator<Micro<A, E, R>>
68
69
  [Unify.typeSymbol]?: unknown
69
70
  [Unify.unifySymbol]?: MicroUnify<this>
70
71
  [Unify.ignoreSymbol]?: MicroUnifyIgnore
71
- [Symbol.iterator](): MicroIterator<Micro<A, E, R>>
72
72
  }
73
73
 
74
74
  /**
@@ -144,6 +144,58 @@ export interface MicroIterator<T extends Micro<any, any, any>> {
144
144
  next(...args: ReadonlyArray<any>): IteratorResult<YieldWrap<T>, Micro.Success<T>>
145
145
  }
146
146
 
147
+ /**
148
+ * @since 3.8.4
149
+ * @experimental
150
+ * @category models
151
+ */
152
+ export interface MicroClass {
153
+ new<A, E = never, R = never>(): Micro<A, E, R>
154
+ }
155
+
156
+ // ----------------------------------------------------------------------------
157
+ // Microable
158
+ // ----------------------------------------------------------------------------
159
+
160
+ const MicroProto = {
161
+ ...Effectable.EffectPrototype,
162
+ _op: "Micro",
163
+ [TypeId]: {
164
+ _A: identity,
165
+ _E: identity,
166
+ _R: identity
167
+ },
168
+ [Symbol.iterator]() {
169
+ return new SingleShotGen(new YieldWrap(this)) as any
170
+ }
171
+ }
172
+
173
+ const MicroBase: MicroClass = (function() {
174
+ function Base() {}
175
+ Base.prototype = MicroProto
176
+ return Base as any
177
+ })()
178
+
179
+ /**
180
+ * @since 3.8.4
181
+ * @experimental
182
+ * @category constructors
183
+ */
184
+ export abstract class Class<out A, out E = never, out R = never> extends MicroBase<A, E, R> {
185
+ /**
186
+ * @since 3.8.4
187
+ * @experimental
188
+ */
189
+ abstract asMicro(): Micro<A, E, R>
190
+ /**
191
+ * @since 3.8.4
192
+ * @experimental
193
+ */
194
+ [runSymbol](env: Env<any>, onExit: (exit: MicroExit<A, E>) => void): void {
195
+ this.asMicro()[runSymbol](env, onExit)
196
+ }
197
+ }
198
+
147
199
  // ----------------------------------------------------------------------------
148
200
  // MicroCause
149
201
  // ----------------------------------------------------------------------------
@@ -512,31 +564,6 @@ export interface Env<R> extends Pipeable {
512
564
  readonly refs: ReadonlyRecord<string, unknown>
513
565
  }
514
566
 
515
- /**
516
- * @since 3.4.0
517
- * @experimental
518
- * @category environment
519
- */
520
- export const EnvRefTypeId: unique symbol = Symbol.for("effect/Micro/EnvRef")
521
-
522
- /**
523
- * @since 3.4.0
524
- * @experimental
525
- * @category environment
526
- */
527
- export type EnvRefTypeId = typeof EnvRefTypeId
528
-
529
- /**
530
- * @since 3.4.0
531
- * @experimental
532
- * @category environment
533
- */
534
- export interface EnvRef<A> {
535
- readonly [EnvRefTypeId]: EnvRefTypeId
536
- readonly key: string
537
- readonly initial: A
538
- }
539
-
540
567
  const EnvProto = {
541
568
  [EnvTypeId]: {
542
569
  _R: identity
@@ -818,8 +845,59 @@ export class MicroSchedulerDefault implements MicroScheduler {
818
845
  // Env refs
819
846
  // ========================================================================
820
847
 
821
- const EnvRefProto = {
822
- [EnvRefTypeId]: EnvRefTypeId
848
+ /**
849
+ * @since 3.4.0
850
+ * @experimental
851
+ * @category environment
852
+ */
853
+ export const EnvRefTypeId: unique symbol = Symbol.for("effect/Micro/EnvRef")
854
+
855
+ /**
856
+ * @since 3.4.0
857
+ * @experimental
858
+ * @category environment
859
+ */
860
+ export type EnvRefTypeId = typeof EnvRefTypeId
861
+
862
+ /**
863
+ * @since 3.4.0
864
+ * @experimental
865
+ * @category environment
866
+ */
867
+ export interface EnvRef<A> extends Micro<A> {
868
+ readonly [EnvRefTypeId]: EnvRefTypeId
869
+ readonly key: string
870
+ readonly initial: A
871
+
872
+ [Unify.typeSymbol]?: unknown
873
+ [Unify.unifySymbol]?: EnvRefUnify<this>
874
+ [Unify.ignoreSymbol]?: EnvRefUnifyIgnore
875
+ }
876
+
877
+ /**
878
+ * @category models
879
+ * @since 3.8.4
880
+ * @experimental
881
+ */
882
+ export interface EnvRefUnify<A extends { [Unify.typeSymbol]?: any }> extends MicroUnify<A> {
883
+ EnvRef?: () => A[Unify.typeSymbol] extends EnvRef<infer A0> | infer _ ? EnvRef<A0> : never
884
+ }
885
+
886
+ /**
887
+ * @category models
888
+ * @since 3.8.4
889
+ * @experimental
890
+ */
891
+ export interface EnvRefUnifyIgnore extends MicroUnifyIgnore {
892
+ Micro?: true
893
+ }
894
+
895
+ const EnvRefProto: ThisType<EnvRef<any>> = {
896
+ ...MicroProto,
897
+ [EnvRefTypeId]: EnvRefTypeId,
898
+ [runSymbol](env: Env<any>, onExit: (exit: MicroExit<any, any>) => void) {
899
+ getEnvRef(this)[runSymbol](env, onExit)
900
+ }
823
901
  }
824
902
 
825
903
  /**
@@ -929,19 +1007,6 @@ export const withConcurrency: {
929
1007
  // constructors
930
1008
  // ----------------------------------------------------------------------------
931
1009
 
932
- const MicroProto = {
933
- ...Effectable.EffectPrototype,
934
- _op: "Micro",
935
- [TypeId]: {
936
- _A: identity,
937
- _E: identity,
938
- _R: identity
939
- },
940
- [Symbol.iterator]() {
941
- return new SingleShotGen(new YieldWrap(this)) as any
942
- }
943
- }
944
-
945
1010
  const microDepthState = globalValue("effect/Micro/microDepthState", () => ({
946
1011
  depth: 0,
947
1012
  maxDepthBeforeYield: currentMaxDepthBeforeYield.initial
@@ -3652,7 +3717,7 @@ export type HandleTypeId = typeof HandleTypeId
3652
3717
  * @experimental
3653
3718
  * @category handle & forking
3654
3719
  */
3655
- export interface Handle<A, E = never> {
3720
+ export interface Handle<A, E = never> extends Micro<A, E> {
3656
3721
  readonly [HandleTypeId]: HandleTypeId
3657
3722
  readonly await: Micro<MicroExit<A, E>>
3658
3723
  readonly join: Micro<A, E>
@@ -3661,6 +3726,28 @@ export interface Handle<A, E = never> {
3661
3726
  readonly addObserver: (observer: (exit: MicroExit<A, E>) => void) => void
3662
3727
  readonly removeObserver: (observer: (exit: MicroExit<A, E>) => void) => void
3663
3728
  readonly unsafePoll: () => MicroExit<A, E> | null
3729
+
3730
+ [Unify.typeSymbol]?: unknown
3731
+ [Unify.unifySymbol]?: HandleUnify<this>
3732
+ [Unify.ignoreSymbol]?: HandleUnifyIgnore
3733
+ }
3734
+
3735
+ /**
3736
+ * @category models
3737
+ * @since 3.8.4
3738
+ * @experimental
3739
+ */
3740
+ export interface HandleUnify<A extends { [Unify.typeSymbol]?: any }> extends MicroUnify<A> {
3741
+ Handle?: () => A[Unify.typeSymbol] extends Handle<infer A0, infer E0> | infer _ ? Handle<A0, E0> : never
3742
+ }
3743
+
3744
+ /**
3745
+ * @category models
3746
+ * @since 3.8.4
3747
+ * @experimental
3748
+ */
3749
+ export interface HandleUnifyIgnore extends MicroUnifyIgnore {
3750
+ Micro?: true
3664
3751
  }
3665
3752
 
3666
3753
  /**
@@ -3671,7 +3758,7 @@ export interface Handle<A, E = never> {
3671
3758
  export const isHandle = (u: unknown): u is Handle<unknown, unknown> =>
3672
3759
  typeof u === "object" && u !== null && HandleTypeId in u
3673
3760
 
3674
- class HandleImpl<A, E> implements Handle<A, E> {
3761
+ class HandleImpl<A, E> extends Class<A, E> implements Handle<A, E> {
3675
3762
  readonly [HandleTypeId]: HandleTypeId
3676
3763
 
3677
3764
  readonly observers: Set<(exit: MicroExit<A, E>) => void> = new Set()
@@ -3680,6 +3767,7 @@ class HandleImpl<A, E> implements Handle<A, E> {
3680
3767
  readonly isRoot: boolean
3681
3768
 
3682
3769
  constructor(readonly parentSignal: AbortSignal, controller?: AbortController) {
3770
+ super()
3683
3771
  this[HandleTypeId] = HandleTypeId
3684
3772
  this.isRoot = controller !== undefined
3685
3773
  this._controller = controller ?? new AbortController()
@@ -3746,6 +3834,10 @@ class HandleImpl<A, E> implements Handle<A, E> {
3746
3834
  return this.await
3747
3835
  })
3748
3836
  }
3837
+
3838
+ asMicro(): Micro<A, E> {
3839
+ return this.join
3840
+ }
3749
3841
  }
3750
3842
 
3751
3843
  /**
package/src/Scope.ts CHANGED
@@ -11,47 +11,67 @@ import * as fiberRuntime from "./internal/fiberRuntime.js"
11
11
  import type { Pipeable } from "./Pipeable.js"
12
12
 
13
13
  /**
14
+ * A unique identifier for the `Scope` type.
15
+ *
14
16
  * @since 2.0.0
15
17
  * @category symbols
16
18
  */
17
19
  export const ScopeTypeId: unique symbol = core.ScopeTypeId
18
20
 
19
21
  /**
22
+ * The type of the unique identifier for `Scope`.
23
+ *
20
24
  * @since 2.0.0
21
25
  * @category symbols
22
26
  */
23
27
  export type ScopeTypeId = typeof ScopeTypeId
24
28
 
25
29
  /**
30
+ * A unique identifier for the `CloseableScope` type.
31
+ *
26
32
  * @since 2.0.0
27
33
  * @category symbols
28
34
  */
29
35
  export const CloseableScopeTypeId: unique symbol = core.CloseableScopeTypeId
30
36
 
31
37
  /**
38
+ * The type of the unique identifier for `CloseableScope`.
39
+ *
32
40
  * @since 2.0.0
33
41
  * @category symbols
34
42
  */
35
43
  export type CloseableScopeTypeId = typeof CloseableScopeTypeId
36
44
 
37
45
  /**
46
+ * Represents a scope that manages finalizers and can fork child scopes.
47
+ *
38
48
  * @since 2.0.0
39
49
  * @category models
40
50
  */
41
51
  export interface Scope extends Pipeable {
42
52
  readonly [ScopeTypeId]: ScopeTypeId
53
+ /**
54
+ * The execution strategy for running finalizers in this scope.
55
+ */
43
56
  readonly strategy: ExecutionStrategy.ExecutionStrategy
44
57
  /**
58
+ * Forks a new child scope with the specified execution strategy. The child scope
59
+ * will automatically be closed when this scope is closed.
60
+ *
45
61
  * @internal
46
62
  */
47
63
  fork(strategy: ExecutionStrategy.ExecutionStrategy): Effect.Effect<Scope.Closeable>
48
64
  /**
65
+ * Adds a finalizer to this scope. The finalizer will be run when the scope is closed.
66
+ *
49
67
  * @internal
50
68
  */
51
69
  addFinalizer(finalizer: Scope.Finalizer): Effect.Effect<void>
52
70
  }
53
71
 
54
72
  /**
73
+ * A scope that can be explicitly closed with a specified exit value.
74
+ *
55
75
  * @since 2.0.0
56
76
  * @category models
57
77
  */
@@ -59,12 +79,16 @@ export interface CloseableScope extends Scope, Pipeable {
59
79
  readonly [CloseableScopeTypeId]: CloseableScopeTypeId
60
80
 
61
81
  /**
82
+ * Closes this scope with the given exit value, running all finalizers.
83
+ *
62
84
  * @internal
63
85
  */
64
86
  close(exit: Exit.Exit<unknown, unknown>): Effect.Effect<void>
65
87
  }
66
88
 
67
89
  /**
90
+ * A tag representing the current `Scope` in the environment.
91
+ *
68
92
  * @since 2.0.0
69
93
  * @category context
70
94
  */
@@ -75,11 +99,15 @@ export const Scope: Context.Tag<Scope, Scope> = fiberRuntime.scopeTag
75
99
  */
76
100
  export declare namespace Scope {
77
101
  /**
102
+ * A finalizer function that takes an `Exit` value and returns an `Effect`.
103
+ *
78
104
  * @since 2.0.0
79
105
  * @category model
80
106
  */
81
107
  export type Finalizer = (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>
82
108
  /**
109
+ * A closeable scope that can be explicitly closed.
110
+ *
83
111
  * @since 2.0.0
84
112
  * @category model
85
113
  */
@@ -88,8 +116,10 @@ export declare namespace Scope {
88
116
 
89
117
  /**
90
118
  * Adds a finalizer to this scope. The finalizer is guaranteed to be run when
91
- * the scope is closed.
119
+ * the scope is closed. Use this when the finalizer does not need to know the
120
+ * `Exit` value that the scope is closed with.
92
121
  *
122
+ * @see {@link addFinalizerExit}
93
123
  * @since 2.0.0
94
124
  * @category utils
95
125
  */
@@ -99,9 +129,11 @@ export const addFinalizer: (
99
129
  ) => Effect.Effect<void> = core.scopeAddFinalizer
100
130
 
101
131
  /**
102
- * A simplified version of `addFinalizerWith` when the `finalizer` does not
103
- * depend on the `Exit` value that the scope is closed with.
132
+ * Adds a finalizer to this scope. The finalizer receives the `Exit` value
133
+ * when the scope is closed, allowing it to perform different actions based
134
+ * on the exit status.
104
135
  *
136
+ * @see {@link addFinalizer}
105
137
  * @since 2.0.0
106
138
  * @category utils
107
139
  */
@@ -109,7 +141,7 @@ export const addFinalizerExit: (self: Scope, finalizer: Scope.Finalizer) => Effe
109
141
  core.scopeAddFinalizerExit
110
142
 
111
143
  /**
112
- * Closes a scope with the specified exit value, running all finalizers that
144
+ * Closes this scope with the specified exit value, running all finalizers that
113
145
  * have been added to the scope.
114
146
  *
115
147
  * @since 2.0.0
@@ -118,9 +150,9 @@ export const addFinalizerExit: (self: Scope, finalizer: Scope.Finalizer) => Effe
118
150
  export const close: (self: CloseableScope, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void> = core.scopeClose
119
151
 
120
152
  /**
121
- * Extends the scope of an `Effect` workflow that needs a scope into this
122
- * scope by providing it to the workflow but not closing the scope when the
123
- * workflow completes execution. This allows extending a scoped value into a
153
+ * Extends the scope of an `Effect` that requires a scope into this scope.
154
+ * It provides this scope to the effect but does not close the scope when the
155
+ * effect completes execution. This allows extending a scoped value into a
124
156
  * larger scope.
125
157
  *
126
158
  * @since 2.0.0
@@ -132,8 +164,8 @@ export const extend: {
132
164
  } = fiberRuntime.scopeExtend
133
165
 
134
166
  /**
135
- * Forks a new scope that is a child of this scope. The child scope will
136
- * automatically be closed when this scope is closed.
167
+ * Forks a new child scope with the specified execution strategy. The child scope
168
+ * will automatically be closed when this scope is closed.
137
169
  *
138
170
  * @since 2.0.0
139
171
  * @category utils
@@ -144,9 +176,9 @@ export const fork: (
144
176
  ) => Effect.Effect<CloseableScope> = core.scopeFork
145
177
 
146
178
  /**
147
- * Uses the scope by providing it to an `Effect` workflow that needs a scope,
148
- * guaranteeing that the scope is closed with the result of that workflow as
149
- * soon as the workflow completes execution, whether by success, failure, or
179
+ * Provides this closeable scope to an `Effect` that requires a scope,
180
+ * guaranteeing that the scope is closed with the result of that effect as
181
+ * soon as the effect completes execution, whether by success, failure, or
150
182
  * interruption.
151
183
  *
152
184
  * @since 2.0.0
@@ -158,9 +190,9 @@ export const use: {
158
190
  } = fiberRuntime.scopeUse
159
191
 
160
192
  /**
161
- * Creates a Scope where Finalizers will run according to the `ExecutionStrategy`.
162
- *
163
- * If an ExecutionStrategy is not provided `sequential` will be used.
193
+ * Creates a new closeable scope where finalizers will run according to the
194
+ * specified `ExecutionStrategy`. If no execution strategy is provided, `sequential`
195
+ * will be used by default.
164
196
  *
165
197
  * @since 2.0.0
166
198
  * @category constructors
@@ -1471,26 +1471,32 @@ export const tracerLogger = globalValue(
1471
1471
  logLevel,
1472
1472
  message
1473
1473
  }) => {
1474
- const span = Option.flatMap(fiberRefs.get(context, core.currentContext), Context.getOption(tracer.spanTag))
1475
- const clockService = Option.map(
1476
- fiberRefs.get(context, defaultServices.currentServices),
1477
- (_) => Context.get(_, clock.clockTag)
1474
+ const span = Context.getOption(
1475
+ fiberRefs.getOrDefault(context, core.currentContext),
1476
+ tracer.spanTag
1478
1477
  )
1479
- if (span._tag === "None" || span.value._tag === "ExternalSpan" || clockService._tag === "None") {
1478
+ if (span._tag === "None" || span.value._tag === "ExternalSpan") {
1480
1479
  return
1481
1480
  }
1481
+ const clockService = Context.unsafeGet(
1482
+ fiberRefs.getOrDefault(context, defaultServices.currentServices),
1483
+ clock.clockTag
1484
+ )
1482
1485
 
1483
- const attributes = Object.fromEntries(HashMap.map(annotations, Inspectable.toStringUnknown))
1486
+ const attributes: Record<string, unknown> = {}
1487
+ for (const [key, value] of annotations) {
1488
+ attributes[key] = value
1489
+ }
1484
1490
  attributes["effect.fiberId"] = FiberId.threadName(fiberId)
1485
1491
  attributes["effect.logLevel"] = logLevel.label
1486
1492
 
1487
1493
  if (cause !== null && cause._tag !== "Empty") {
1488
- attributes["effect.cause"] = internalCause.pretty(cause)
1494
+ attributes["effect.cause"] = internalCause.pretty(cause, { renderErrorCause: true })
1489
1495
  }
1490
1496
 
1491
1497
  span.value.event(
1492
- String(message),
1493
- clockService.value.unsafeCurrentTimeNanos(),
1498
+ Inspectable.toStringUnknown(Array.isArray(message) ? message[0] : message),
1499
+ clockService.unsafeCurrentTimeNanos(),
1494
1500
  attributes
1495
1501
  )
1496
1502
  })
@@ -1,4 +1,4 @@
1
- let moduleVersion = "3.8.2"
1
+ let moduleVersion = "3.8.4"
2
2
 
3
3
  export const getCurrentVersion = () => moduleVersion
4
4