effect 3.1.6 → 3.2.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 (113) hide show
  1. package/dist/cjs/Array.js +139 -2
  2. package/dist/cjs/Array.js.map +1 -1
  3. package/dist/cjs/Cause.js +8 -1
  4. package/dist/cjs/Cause.js.map +1 -1
  5. package/dist/cjs/Chunk.js +18 -1
  6. package/dist/cjs/Chunk.js.map +1 -1
  7. package/dist/cjs/Config.js.map +1 -1
  8. package/dist/cjs/Data.js +11 -8
  9. package/dist/cjs/Data.js.map +1 -1
  10. package/dist/cjs/Effect.js +20 -3
  11. package/dist/cjs/Effect.js.map +1 -1
  12. package/dist/cjs/Stream.js +19 -1
  13. package/dist/cjs/Stream.js.map +1 -1
  14. package/dist/cjs/Tracer.js.map +1 -1
  15. package/dist/cjs/internal/cause.js +55 -48
  16. package/dist/cjs/internal/cause.js.map +1 -1
  17. package/dist/cjs/internal/channel.js +11 -1
  18. package/dist/cjs/internal/channel.js.map +1 -1
  19. package/dist/cjs/internal/config.js.map +1 -1
  20. package/dist/cjs/internal/core-effect.js +51 -9
  21. package/dist/cjs/internal/core-effect.js.map +1 -1
  22. package/dist/cjs/internal/core.js +8 -4
  23. package/dist/cjs/internal/core.js.map +1 -1
  24. package/dist/cjs/internal/fiberRuntime.js +27 -14
  25. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  26. package/dist/cjs/internal/layer/circular.js +4 -1
  27. package/dist/cjs/internal/layer/circular.js.map +1 -1
  28. package/dist/cjs/internal/layer.js +11 -1
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/runtime.js +7 -4
  31. package/dist/cjs/internal/runtime.js.map +1 -1
  32. package/dist/cjs/internal/stream.js +27 -9
  33. package/dist/cjs/internal/stream.js.map +1 -1
  34. package/dist/cjs/internal/tracer.js +31 -1
  35. package/dist/cjs/internal/tracer.js.map +1 -1
  36. package/dist/cjs/internal/version.js +1 -1
  37. package/dist/dts/Array.d.ts +199 -0
  38. package/dist/dts/Array.d.ts.map +1 -1
  39. package/dist/dts/Cause.d.ts +15 -0
  40. package/dist/dts/Cause.d.ts.map +1 -1
  41. package/dist/dts/Chunk.d.ts +20 -0
  42. package/dist/dts/Chunk.d.ts.map +1 -1
  43. package/dist/dts/Config.d.ts +4 -4
  44. package/dist/dts/Config.d.ts.map +1 -1
  45. package/dist/dts/Data.d.ts +46 -13
  46. package/dist/dts/Data.d.ts.map +1 -1
  47. package/dist/dts/Effect.d.ts +36 -0
  48. package/dist/dts/Effect.d.ts.map +1 -1
  49. package/dist/dts/Stream.d.ts +23 -1
  50. package/dist/dts/Stream.d.ts.map +1 -1
  51. package/dist/dts/Tracer.d.ts +1 -0
  52. package/dist/dts/Tracer.d.ts.map +1 -1
  53. package/dist/dts/internal/core-effect.d.ts +7 -1
  54. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  55. package/dist/dts/internal/core.d.ts.map +1 -1
  56. package/dist/dts/internal/stream.d.ts.map +1 -1
  57. package/dist/esm/Array.js +182 -0
  58. package/dist/esm/Array.js.map +1 -1
  59. package/dist/esm/Cause.js +7 -0
  60. package/dist/esm/Cause.js.map +1 -1
  61. package/dist/esm/Chunk.js +16 -0
  62. package/dist/esm/Chunk.js.map +1 -1
  63. package/dist/esm/Config.js.map +1 -1
  64. package/dist/esm/Data.js +11 -8
  65. package/dist/esm/Data.js.map +1 -1
  66. package/dist/esm/Effect.js +17 -0
  67. package/dist/esm/Effect.js.map +1 -1
  68. package/dist/esm/Stream.js +18 -0
  69. package/dist/esm/Stream.js.map +1 -1
  70. package/dist/esm/Tracer.js.map +1 -1
  71. package/dist/esm/internal/cause.js +54 -47
  72. package/dist/esm/internal/cause.js.map +1 -1
  73. package/dist/esm/internal/channel.js +10 -1
  74. package/dist/esm/internal/channel.js.map +1 -1
  75. package/dist/esm/internal/config.js.map +1 -1
  76. package/dist/esm/internal/core-effect.js +47 -7
  77. package/dist/esm/internal/core-effect.js.map +1 -1
  78. package/dist/esm/internal/core.js +7 -3
  79. package/dist/esm/internal/core.js.map +1 -1
  80. package/dist/esm/internal/fiberRuntime.js +26 -14
  81. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  82. package/dist/esm/internal/layer/circular.js +4 -1
  83. package/dist/esm/internal/layer/circular.js.map +1 -1
  84. package/dist/esm/internal/layer.js +10 -1
  85. package/dist/esm/internal/layer.js.map +1 -1
  86. package/dist/esm/internal/runtime.js +7 -4
  87. package/dist/esm/internal/runtime.js.map +1 -1
  88. package/dist/esm/internal/stream.js +23 -7
  89. package/dist/esm/internal/stream.js.map +1 -1
  90. package/dist/esm/internal/tracer.js +29 -0
  91. package/dist/esm/internal/tracer.js.map +1 -1
  92. package/dist/esm/internal/version.js +1 -1
  93. package/package.json +1 -1
  94. package/src/Array.ts +214 -0
  95. package/src/Cause.ts +17 -0
  96. package/src/Chunk.ts +30 -0
  97. package/src/Config.ts +4 -3
  98. package/src/Data.ts +121 -48
  99. package/src/Effect.ts +40 -0
  100. package/src/Stream.ts +31 -1
  101. package/src/Tracer.ts +1 -0
  102. package/src/internal/cause.ts +70 -52
  103. package/src/internal/channel.ts +32 -14
  104. package/src/internal/config.ts +1 -1
  105. package/src/internal/core-effect.ts +74 -25
  106. package/src/internal/core.ts +8 -3
  107. package/src/internal/fiberRuntime.ts +22 -11
  108. package/src/internal/layer/circular.ts +4 -2
  109. package/src/internal/layer.ts +37 -14
  110. package/src/internal/runtime.ts +9 -4
  111. package/src/internal/stream.ts +37 -13
  112. package/src/internal/tracer.ts +21 -0
  113. package/src/internal/version.ts +1 -1
package/src/Stream.ts CHANGED
@@ -22,6 +22,7 @@ import type { Pipeable } from "./Pipeable.js"
22
22
  import type { Predicate, Refinement } from "./Predicate.js"
23
23
  import type * as PubSub from "./PubSub.js"
24
24
  import type * as Queue from "./Queue.js"
25
+ import type { Runtime } from "./Runtime.js"
25
26
  import type * as Schedule from "./Schedule.js"
26
27
  import type * as Scope from "./Scope.js"
27
28
  import type * as Sink from "./Sink.js"
@@ -3859,7 +3860,36 @@ export const toQueueOfElements: {
3859
3860
  * @since 2.0.0
3860
3861
  * @category destructors
3861
3862
  */
3862
- export const toReadableStream: <A, E>(source: Stream<A, E>) => ReadableStream<A> = internal.toReadableStream
3863
+ export const toReadableStream: <A, E>(self: Stream<A, E>) => ReadableStream<A> = internal.toReadableStream
3864
+
3865
+ /**
3866
+ * Converts the stream to a `Effect<ReadableStream>`.
3867
+ *
3868
+ * See https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream.
3869
+ *
3870
+ * @since 2.0.0
3871
+ * @category destructors
3872
+ */
3873
+ export const toReadableStreamEffect: <A, E, R>(self: Stream<A, E, R>) => Effect.Effect<ReadableStream<A>, never, R> =
3874
+ internal.toReadableStreamEffect
3875
+
3876
+ /**
3877
+ * Converts the stream to a `ReadableStream` using the provided runtime.
3878
+ *
3879
+ * See https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream.
3880
+ *
3881
+ * @since 2.0.0
3882
+ * @category destructors
3883
+ */
3884
+ export const toReadableStreamRuntime: {
3885
+ <XR>(
3886
+ runtime: Runtime<XR>
3887
+ ): <A, E, R extends XR>(self: Stream<A, E, R>) => ReadableStream<A>
3888
+ <A, E, XR, R extends XR>(
3889
+ self: Stream<A, E, R>,
3890
+ runtime: Runtime<XR>
3891
+ ): ReadableStream<A>
3892
+ } = internal.toReadableStreamRuntime
3863
3893
 
3864
3894
  /**
3865
3895
  * Applies the transducer to the stream and emits its outputs.
package/src/Tracer.ts CHANGED
@@ -92,6 +92,7 @@ export interface SpanOptions {
92
92
  readonly root?: boolean | undefined
93
93
  readonly context?: Context.Context<never> | undefined
94
94
  readonly kind?: SpanKind | undefined
95
+ readonly captureStackTrace?: boolean | string | undefined
95
96
  }
96
97
 
97
98
  /**
@@ -10,8 +10,8 @@ import * as HashSet from "../HashSet.js"
10
10
  import { NodeInspectSymbol, toJSON } from "../Inspectable.js"
11
11
  import * as Option from "../Option.js"
12
12
  import { pipeArguments } from "../Pipeable.js"
13
- import { hasProperty, isFunction } from "../Predicate.js"
14
13
  import type { Predicate, Refinement } from "../Predicate.js"
14
+ import { hasProperty, isFunction } from "../Predicate.js"
15
15
  import type { AnySpan, Span } from "../Tracer.js"
16
16
  import type { NoInfer } from "../Types.js"
17
17
  import { getBugErrorMessage } from "./errors.js"
@@ -968,53 +968,45 @@ export const reduceWithContext = dual<
968
968
  // Pretty Printing
969
969
  // -----------------------------------------------------------------------------
970
970
 
971
- const filterStack = (stack: string) => {
972
- const lines = stack.split("\n")
973
- const out: Array<string> = []
974
- for (let i = 0; i < lines.length; i++) {
975
- out.push(lines[i].replace(/at .*effect_instruction_i.*\((.*)\)/, "at $1"))
976
- if (lines[i].includes("effect_instruction_i")) {
977
- return out.join("\n")
978
- }
979
- }
980
- return out.join("\n")
981
- }
982
-
983
971
  /** @internal */
984
972
  export const pretty = <E>(cause: Cause.Cause<E>): string => {
985
973
  if (isInterruptedOnly(cause)) {
986
974
  return "All fibers interrupted without errors."
987
975
  }
988
- const final = prettyErrors<E>(cause).map((e) => {
989
- let message = e.message
990
- if (e.stack) {
991
- message += `\r\n${filterStack(e.stack)}`
992
- }
993
- if (e.span) {
994
- let current: Span | AnySpan | undefined = e.span
995
- let i = 0
996
- while (current && current._tag === "Span" && i < 10) {
997
- message += `\r\n at ${current.name}`
998
- current = Option.getOrUndefined(current.parent)
999
- i++
976
+ return prettyErrors<E>(cause).map((e) => e.stack).join("\n")
977
+ }
978
+
979
+ class PrettyError extends globalThis.Error implements Cause.PrettyError {
980
+ span: undefined | Span = undefined
981
+ constructor(originalError: unknown) {
982
+ const prevLimit = Error.stackTraceLimit
983
+ Error.stackTraceLimit = 0
984
+ super(prettyErrorMessage(originalError))
985
+ Error.stackTraceLimit = prevLimit
986
+
987
+ this.name = originalError instanceof Error ? originalError.name : "Error"
988
+ if (typeof originalError === "object" && originalError !== null) {
989
+ if (spanSymbol in originalError) {
990
+ this.span = originalError[spanSymbol] as Span
1000
991
  }
992
+ Object.keys(originalError).forEach((key) => {
993
+ if (!(key in this)) {
994
+ // @ts-expect-error
995
+ this[key] = originalError[key]
996
+ }
997
+ })
1001
998
  }
1002
- return message
1003
- }).join("\r\n")
1004
- return final
1005
- }
999
+ this.stack = prettyErrorStack(
1000
+ this.message,
1001
+ originalError instanceof Error && originalError.stack
1002
+ ? originalError.stack
1003
+ : "",
1004
+ this.span
1005
+ )
1006
+ }
1006
1007
 
1007
- class PrettyError {
1008
- constructor(
1009
- readonly message: string,
1010
- readonly stack: string | undefined,
1011
- readonly span: Span | undefined
1012
- ) {}
1013
1008
  toJSON() {
1014
- const out: any = { message: this.message }
1015
- if (this.stack) {
1016
- out.stack = this.stack
1017
- }
1009
+ const out: any = { message: this.message, stack: this.stack }
1018
1010
  if (this.span) {
1019
1011
  out.span = this.span
1020
1012
  }
@@ -1058,29 +1050,55 @@ export const prettyErrorMessage = (u: unknown): string => {
1058
1050
  return `Error: ${JSON.stringify(u)}`
1059
1051
  }
1060
1052
 
1061
- const spanSymbol = Symbol.for("effect/SpanAnnotation")
1053
+ const locationRegex = /\((.*)\)/
1054
+
1055
+ const prettyErrorStack = (message: string, stack: string, span?: Span | undefined): string => {
1056
+ const out: Array<string> = [message]
1057
+ const lines = stack.split("\n")
1062
1058
 
1063
- const defaultRenderError = (error: unknown): PrettyError => {
1064
- const span: any = hasProperty(error, spanSymbol) && error[spanSymbol]
1065
- if (error instanceof Error) {
1066
- return new PrettyError(
1067
- prettyErrorMessage(error),
1068
- error.stack?.split("\n").filter((_) => _.match(/at (.*)/)).join("\n"),
1069
- span
1059
+ for (let i = 1; i < lines.length; i++) {
1060
+ if (lines[i].includes("effect_cutpoint") || lines[i].includes("Generator.next")) {
1061
+ break
1062
+ }
1063
+ out.push(
1064
+ lines[i].replace(/at .*effect_instruction_i.*\((.*)\)/, "at $1").replace(/EffectPrimitive\.\w+/, "<anonymous>")
1070
1065
  )
1066
+ if (lines[i].includes("effect_instruction_i")) {
1067
+ break
1068
+ }
1071
1069
  }
1072
- return new PrettyError(prettyErrorMessage(error), void 0, span)
1070
+
1071
+ if (span) {
1072
+ let current: Span | AnySpan | undefined = span
1073
+ let i = 0
1074
+ while (current && current._tag === "Span" && i < 10) {
1075
+ const stack = current.attributes.get("code.stacktrace")
1076
+ if (typeof stack === "string") {
1077
+ const locationMatch = stack.match(locationRegex)
1078
+ const location = locationMatch ? locationMatch[1] : stack.replace(/^at /, "")
1079
+ out.push(` at ${current.name} (${location})`)
1080
+ } else {
1081
+ out.push(` at ${current.name}`)
1082
+ }
1083
+ current = Option.getOrUndefined(current.parent)
1084
+ i++
1085
+ }
1086
+ }
1087
+
1088
+ return out.join("\n")
1073
1089
  }
1074
1090
 
1091
+ const spanSymbol = Symbol.for("effect/SpanAnnotation")
1092
+
1075
1093
  /** @internal */
1076
- export const prettyErrors = <E>(cause: Cause.Cause<E>): ReadonlyArray<PrettyError> =>
1094
+ export const prettyErrors = <E>(cause: Cause.Cause<E>): Array<PrettyError> =>
1077
1095
  reduceWithContext(cause, void 0, {
1078
- emptyCase: (): ReadonlyArray<PrettyError> => [],
1096
+ emptyCase: (): Array<PrettyError> => [],
1079
1097
  dieCase: (_, unknownError) => {
1080
- return [defaultRenderError(unknownError)]
1098
+ return [new PrettyError(unknownError)]
1081
1099
  },
1082
1100
  failCase: (_, error) => {
1083
- return [defaultRenderError(error)]
1101
+ return [new PrettyError(error)]
1084
1102
  },
1085
1103
  interruptCase: () => [],
1086
1104
  parallelCase: (_, l, r) => [...l, ...r],
@@ -2310,29 +2310,47 @@ export const updateService = dual<
2310
2310
  )))
2311
2311
 
2312
2312
  /** @internal */
2313
- export const withSpan = dual<
2313
+ export const withSpan: {
2314
2314
  (
2315
2315
  name: string,
2316
2316
  options?: Tracer.SpanOptions
2317
- ) => <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2317
+ ): <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2318
2318
  self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
2319
- ) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, Tracer.ParentSpan>>,
2319
+ ) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, Tracer.ParentSpan>>
2320
2320
  <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2321
2321
  self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
2322
2322
  name: string,
2323
2323
  options?: Tracer.SpanOptions
2324
- ) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, Tracer.ParentSpan>>
2325
- >(3, (self, name, options) =>
2326
- unwrapScoped(
2327
- Effect.flatMap(
2328
- Effect.context(),
2329
- (context) =>
2330
- Effect.map(
2331
- Effect.makeSpanScoped(name, options),
2332
- (span) => core.provideContext(self, Context.add(context, tracer.spanTag, span))
2333
- )
2324
+ ): Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, Tracer.ParentSpan>>
2325
+ } = function() {
2326
+ const dataFirst = typeof arguments[0] !== "string"
2327
+ const name = dataFirst ? arguments[1] : arguments[0]
2328
+ const options = tracer.addSpanStackTrace(dataFirst ? arguments[2] : arguments[1])
2329
+ if (dataFirst) {
2330
+ const self = arguments[0]
2331
+ return unwrapScoped(
2332
+ Effect.flatMap(
2333
+ Effect.context(),
2334
+ (context) =>
2335
+ Effect.map(
2336
+ Effect.makeSpanScoped(name, options),
2337
+ (span) => core.provideContext(self, Context.add(context, tracer.spanTag, span))
2338
+ )
2339
+ )
2340
+ )
2341
+ }
2342
+ return (self: Effect.Effect<any, any, any>) =>
2343
+ unwrapScoped(
2344
+ Effect.flatMap(
2345
+ Effect.context(),
2346
+ (context) =>
2347
+ Effect.map(
2348
+ Effect.makeSpanScoped(name, options),
2349
+ (span) => core.provideContext(self, Context.add(context, tracer.spanTag, span))
2350
+ )
2351
+ )
2334
2352
  )
2335
- ) as any)
2353
+ } as any
2336
2354
 
2337
2355
  /** @internal */
2338
2356
  export const writeAll = <OutElem>(
@@ -542,7 +542,7 @@ export const unwrap = <A>(wrapped: Config.Config.Wrap<A>): Config.Config<A> => {
542
542
  }
543
543
  return struct(
544
544
  Object.fromEntries(
545
- Object.entries(wrapped).map(([k, a]) => [k, unwrap(a)])
545
+ Object.entries(wrapped).map(([k, a]) => [k, unwrap(a as any)])
546
546
  )
547
547
  ) as any
548
548
  }
@@ -26,6 +26,7 @@ import * as Ref from "../Ref.js"
26
26
  import type * as runtimeFlagsPatch from "../RuntimeFlagsPatch.js"
27
27
  import * as Tracer from "../Tracer.js"
28
28
  import type { NoInfer } from "../Types.js"
29
+ import type { Unify } from "../Unify.js"
29
30
  import { yieldWrapGet } from "../Utils.js"
30
31
  import * as internalCause from "./cause.js"
31
32
  import { clockTag } from "./clock.js"
@@ -2011,7 +2012,7 @@ const bigint0 = BigInt(0)
2011
2012
  export const unsafeMakeSpan = <XA, XE>(
2012
2013
  fiber: FiberRuntime<XA, XE>,
2013
2014
  name: string,
2014
- options?: Tracer.SpanOptions
2015
+ options: Tracer.SpanOptions
2015
2016
  ) => {
2016
2017
  const enabled = fiber.getFiberRef(core.currentTracerEnabled)
2017
2018
  if (enabled === false) {
@@ -2029,34 +2030,38 @@ export const unsafeMakeSpan = <XA, XE>(
2029
2030
  const annotationsFromEnv = FiberRefs.get(fiberRefs, core.currentTracerSpanAnnotations)
2030
2031
  const linksFromEnv = FiberRefs.get(fiberRefs, core.currentTracerSpanLinks)
2031
2032
 
2032
- const parent = options?.parent
2033
+ const parent = options.parent
2033
2034
  ? Option.some(options.parent)
2034
- : options?.root
2035
+ : options.root
2035
2036
  ? Option.none()
2036
2037
  : Context.getOption(context, internalTracer.spanTag)
2037
2038
 
2038
2039
  const links = linksFromEnv._tag === "Some" ?
2039
- options?.links !== undefined ?
2040
+ options.links !== undefined ?
2040
2041
  [
2041
2042
  ...Chunk.toReadonlyArray(linksFromEnv.value),
2042
- ...(options?.links ?? [])
2043
+ ...(options.links ?? [])
2043
2044
  ] :
2044
2045
  Chunk.toReadonlyArray(linksFromEnv.value) :
2045
- options?.links ?? Arr.empty()
2046
+ options.links ?? Arr.empty()
2046
2047
 
2047
2048
  const span = tracer.span(
2048
2049
  name,
2049
2050
  parent,
2050
- options?.context ?? Context.empty(),
2051
+ options.context ?? Context.empty(),
2051
2052
  links,
2052
2053
  timingEnabled ? clock.unsafeCurrentTimeNanos() : bigint0,
2053
- options?.kind ?? "internal"
2054
+ options.kind ?? "internal"
2054
2055
  )
2055
2056
 
2057
+ if (typeof options.captureStackTrace === "string") {
2058
+ span.attribute("code.stacktrace", options.captureStackTrace)
2059
+ }
2060
+
2056
2061
  if (annotationsFromEnv._tag === "Some") {
2057
2062
  HashMap.forEach(annotationsFromEnv.value, (value, key) => span.attribute(key, value))
2058
2063
  }
2059
- if (options?.attributes !== undefined) {
2064
+ if (options.attributes !== undefined) {
2060
2065
  Object.entries(options.attributes).forEach(([k, v]) => span.attribute(k, v))
2061
2066
  }
2062
2067
 
@@ -2067,7 +2072,10 @@ export const unsafeMakeSpan = <XA, XE>(
2067
2072
  export const makeSpan = (
2068
2073
  name: string,
2069
2074
  options?: Tracer.SpanOptions
2070
- ): Effect.Effect<Tracer.Span> => core.withFiberRuntime((fiber) => core.succeed(unsafeMakeSpan(fiber, name, options)))
2075
+ ): Effect.Effect<Tracer.Span> => {
2076
+ options = internalTracer.addSpanStackTrace(options)
2077
+ return core.withFiberRuntime((fiber) => core.succeed(unsafeMakeSpan(fiber, name, options)))
2078
+ }
2071
2079
 
2072
2080
  /* @internal */
2073
2081
  export const spanAnnotations: Effect.Effect<HashMap.HashMap<string, unknown>> = core
@@ -2092,7 +2100,7 @@ export const useSpan: {
2092
2100
  evaluate: (span: Tracer.Span) => Effect.Effect<A, E, R>
2093
2101
  ]
2094
2102
  ) => {
2095
- const options: Tracer.SpanOptions | undefined = args.length === 1 ? undefined : args[0]
2103
+ const options = internalTracer.addSpanStackTrace(args.length === 1 ? undefined : args[0])
2096
2104
  const evaluate: (span: Tracer.Span) => Effect.Effect<A, E, R> = args[args.length - 1]
2097
2105
 
2098
2106
  return core.withFiberRuntime<A, E, R>((fiber) => {
@@ -2118,25 +2126,66 @@ export const withParentSpan = dual<
2118
2126
  >(2, (self, span) => provideService(self, internalTracer.spanTag, span))
2119
2127
 
2120
2128
  /** @internal */
2121
- export const withSpan = dual<
2129
+ export const withSpan: {
2122
2130
  (
2123
2131
  name: string,
2124
- options?: Tracer.SpanOptions
2125
- ) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>>,
2132
+ options?: Tracer.SpanOptions | undefined
2133
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>>
2126
2134
  <A, E, R>(
2127
2135
  self: Effect.Effect<A, E, R>,
2128
2136
  name: string,
2129
- options?: Tracer.SpanOptions
2130
- ) => Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>>
2131
- >(
2132
- (args) => typeof args[0] !== "string",
2133
- (self, name, options) =>
2134
- useSpan(
2135
- name,
2136
- options ?? {},
2137
- (span) => withParentSpan(self, span)
2138
- )
2139
- )
2137
+ options?: Tracer.SpanOptions | undefined
2138
+ ): Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>>
2139
+ } = function() {
2140
+ const dataFirst = typeof arguments[0] !== "string"
2141
+ const name = dataFirst ? arguments[1] : arguments[0]
2142
+ const options = internalTracer.addSpanStackTrace(dataFirst ? arguments[2] : arguments[1])
2143
+ if (dataFirst) {
2144
+ const self = arguments[0]
2145
+ return useSpan(name, options, (span) => withParentSpan(self, span))
2146
+ }
2147
+ return (self: Effect.Effect<any, any, any>) => useSpan(name, options, (span) => withParentSpan(self, span))
2148
+ } as any
2149
+
2150
+ export const functionWithSpan = <Args extends Array<any>, Ret extends Effect.Effect<any, any, any>>(
2151
+ options: {
2152
+ readonly body: (...args: Args) => Ret
2153
+ readonly options: Effect.FunctionWithSpanOptions | ((...args: Args) => Effect.FunctionWithSpanOptions)
2154
+ readonly captureStackTrace?: boolean | undefined
2155
+ }
2156
+ ): (...args: Args) => Unify<Ret> =>
2157
+ (function(this: any) {
2158
+ let captureStackTrace: string | boolean = options.captureStackTrace ?? false
2159
+ if (options.captureStackTrace !== false) {
2160
+ const limit = Error.stackTraceLimit
2161
+ Error.stackTraceLimit = 2
2162
+ const error = new Error()
2163
+ Error.stackTraceLimit = limit
2164
+ if (error.stack !== undefined) {
2165
+ const stack = error.stack.trim().split("\n")
2166
+ captureStackTrace = stack.slice(2).join("\n").trim()
2167
+ }
2168
+ }
2169
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
2170
+ const self = this
2171
+ const args = arguments
2172
+ return core.suspend(() => {
2173
+ const opts = typeof options.options === "function"
2174
+ ? options.options.apply(null, arguments as any)
2175
+ : options.options
2176
+
2177
+ return withSpan(
2178
+ core.custom(options.body, function() {
2179
+ return this.effect_instruction_i0.apply(self, args as any)
2180
+ }),
2181
+ opts.name,
2182
+ {
2183
+ ...opts,
2184
+ captureStackTrace
2185
+ }
2186
+ )
2187
+ })
2188
+ }) as any
2140
2189
 
2141
2190
  // -------------------------------------------------------------------------------------
2142
2191
  // optionality
@@ -459,6 +459,10 @@ export const as: {
459
459
  /* @internal */
460
460
  export const asVoid = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<void, E, R> => as(self, void 0)
461
461
 
462
+ function commitCallCutpoint(this: any) {
463
+ return this.effect_cutpoint()
464
+ }
465
+
462
466
  /* @internal */
463
467
  export const custom: {
464
468
  <X, A, E, R>(i0: X, body: (this: { effect_instruction_i0: X }) => Effect.Effect<A, E, R>): Effect.Effect<A, E, R>
@@ -477,23 +481,24 @@ export const custom: {
477
481
  ): Effect.Effect<A, E, R>
478
482
  } = function() {
479
483
  const wrapper = new EffectPrimitive(OpCodes.OP_COMMIT) as any
484
+ wrapper.commit = commitCallCutpoint
480
485
  switch (arguments.length) {
481
486
  case 2: {
482
487
  wrapper.effect_instruction_i0 = arguments[0]
483
- wrapper.commit = arguments[1]
488
+ wrapper.effect_cutpoint = arguments[1]
484
489
  break
485
490
  }
486
491
  case 3: {
487
492
  wrapper.effect_instruction_i0 = arguments[0]
488
493
  wrapper.effect_instruction_i1 = arguments[1]
489
- wrapper.commit = arguments[2]
494
+ wrapper.effect_cutpoint = arguments[2]
490
495
  break
491
496
  }
492
497
  case 4: {
493
498
  wrapper.effect_instruction_i0 = arguments[0]
494
499
  wrapper.effect_instruction_i1 = arguments[1]
495
500
  wrapper.effect_instruction_i2 = arguments[2]
496
- wrapper.commit = arguments[3]
501
+ wrapper.effect_cutpoint = arguments[3]
497
502
  break
498
503
  }
499
504
  default: {
@@ -1335,7 +1335,7 @@ export class FiberRuntime<in out A, in out E = never> implements Fiber.RuntimeFi
1335
1335
  internalCause.sequential(internalCause.die(e), internalCause.interrupt(FiberId.none))
1336
1336
  )
1337
1337
  } else {
1338
- cur = core.exitFailCause(internalCause.die(e))
1338
+ cur = core.die(e)
1339
1339
  }
1340
1340
  }
1341
1341
  }
@@ -3622,8 +3622,9 @@ export const interruptWhenPossible = dual<
3622
3622
  export const makeSpanScoped = (
3623
3623
  name: string,
3624
3624
  options?: Tracer.SpanOptions | undefined
3625
- ): Effect.Effect<Tracer.Span, never, Scope.Scope> =>
3626
- core.uninterruptible(
3625
+ ): Effect.Effect<Tracer.Span, never, Scope.Scope> => {
3626
+ options = tracer.addSpanStackTrace(options)
3627
+ return core.uninterruptible(
3627
3628
  core.withFiberRuntime((fiber) => {
3628
3629
  const scope = Context.unsafeGet(fiber.getFiberRef(core.currentContext), scopeTag)
3629
3630
  const span = internalEffect.unsafeMakeSpan(fiber, name, options)
@@ -3641,27 +3642,37 @@ export const makeSpanScoped = (
3641
3642
  )
3642
3643
  })
3643
3644
  )
3645
+ }
3644
3646
 
3645
3647
  /* @internal */
3646
3648
  export const withTracerScoped = (value: Tracer.Tracer): Effect.Effect<void, never, Scope.Scope> =>
3647
3649
  fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(tracer.tracerTag, value))
3648
3650
 
3649
3651
  /** @internal */
3650
- export const withSpanScoped = dual<
3652
+ export const withSpanScoped: {
3651
3653
  (
3652
3654
  name: string,
3653
3655
  options?: Tracer.SpanOptions
3654
- ) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan> | Scope.Scope>,
3656
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Scope.Scope | Exclude<R, Tracer.ParentSpan>>
3655
3657
  <A, E, R>(
3656
3658
  self: Effect.Effect<A, E, R>,
3657
3659
  name: string,
3658
3660
  options?: Tracer.SpanOptions
3659
- ) => Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan> | Scope.Scope>
3660
- >(
3661
- (args) => typeof args[0] !== "string",
3662
- (self, name, options) =>
3661
+ ): Effect.Effect<A, E, Scope.Scope | Exclude<R, Tracer.ParentSpan>>
3662
+ } = function() {
3663
+ const dataFirst = typeof arguments[0] !== "string"
3664
+ const name = dataFirst ? arguments[1] : arguments[0]
3665
+ const options = tracer.addSpanStackTrace(dataFirst ? arguments[2] : arguments[1])
3666
+ if (dataFirst) {
3667
+ const self = arguments[0]
3668
+ return core.flatMap(
3669
+ makeSpanScoped(name, tracer.addSpanStackTrace(options)),
3670
+ (span) => internalEffect.provideService(self, tracer.spanTag, span)
3671
+ )
3672
+ }
3673
+ return (self: Effect.Effect<any, any, any>) =>
3663
3674
  core.flatMap(
3664
- makeSpanScoped(name, options),
3675
+ makeSpanScoped(name, tracer.addSpanStackTrace(options)),
3665
3676
  (span) => internalEffect.provideService(self, tracer.spanTag, span)
3666
3677
  )
3667
- )
3678
+ } as any
@@ -196,8 +196,9 @@ export const span = (
196
196
  | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>)
197
197
  | undefined
198
198
  }
199
- ): Layer.Layer<Tracer.ParentSpan> =>
200
- layer.scoped(
199
+ ): Layer.Layer<Tracer.ParentSpan> => {
200
+ options = tracer.addSpanStackTrace(options) as any
201
+ return layer.scoped(
201
202
  tracer.spanTag,
202
203
  options?.onEnd
203
204
  ? core.tap(
@@ -206,6 +207,7 @@ export const span = (
206
207
  )
207
208
  : fiberRuntime.makeSpanScoped(name, options)
208
209
  )
210
+ }
209
211
 
210
212
  /** @internal */
211
213
  export const setTracer = (tracer: Tracer.Tracer): Layer.Layer<never> =>
@@ -1113,7 +1113,7 @@ export const unwrapScoped = <A, E1, R1, E, R>(
1113
1113
  // -----------------------------------------------------------------------------
1114
1114
 
1115
1115
  /** @internal */
1116
- export const withSpan = dual<
1116
+ export const withSpan: {
1117
1117
  (
1118
1118
  name: string,
1119
1119
  options?: Tracer.SpanOptions & {
@@ -1121,7 +1121,7 @@ export const withSpan = dual<
1121
1121
  | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>)
1122
1122
  | undefined
1123
1123
  }
1124
- ) => <A, E, R>(self: Layer.Layer<A, E, R>) => Layer.Layer<A, E, Exclude<R, Tracer.ParentSpan>>,
1124
+ ): <A, E, R>(self: Layer.Layer<A, E, R>) => Layer.Layer<A, E, Exclude<R, Tracer.ParentSpan>>
1125
1125
  <A, E, R>(
1126
1126
  self: Layer.Layer<A, E, R>,
1127
1127
  name: string,
@@ -1130,19 +1130,42 @@ export const withSpan = dual<
1130
1130
  | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>)
1131
1131
  | undefined
1132
1132
  }
1133
- ) => Layer.Layer<A, E, Exclude<R, Tracer.ParentSpan>>
1134
- >((args) => isLayer(args[0]), (self, name, options) =>
1135
- unwrapScoped(
1136
- core.map(
1137
- options?.onEnd
1138
- ? core.tap(
1139
- fiberRuntime.makeSpanScoped(name, options),
1140
- (span) => fiberRuntime.addFinalizer((exit) => options.onEnd!(span, exit))
1141
- )
1142
- : fiberRuntime.makeSpanScoped(name, options),
1143
- (span) => withParentSpan(self, span)
1133
+ ): Layer.Layer<A, E, Exclude<R, Tracer.ParentSpan>>
1134
+ } = function() {
1135
+ const dataFirst = typeof arguments[0] !== "string"
1136
+ const name = dataFirst ? arguments[1] : arguments[0]
1137
+ const options = tracer.addSpanStackTrace(dataFirst ? arguments[2] : arguments[1]) as Tracer.SpanOptions & {
1138
+ readonly onEnd?:
1139
+ | ((span: Tracer.Span, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void>)
1140
+ | undefined
1141
+ }
1142
+ if (dataFirst) {
1143
+ const self = arguments[0]
1144
+ return unwrapScoped(
1145
+ core.map(
1146
+ options?.onEnd
1147
+ ? core.tap(
1148
+ fiberRuntime.makeSpanScoped(name, options),
1149
+ (span) => fiberRuntime.addFinalizer((exit) => options.onEnd!(span, exit))
1150
+ )
1151
+ : fiberRuntime.makeSpanScoped(name, options),
1152
+ (span) => withParentSpan(self, span)
1153
+ )
1144
1154
  )
1145
- ))
1155
+ }
1156
+ return (self: Layer.Layer<any, any, any>) =>
1157
+ unwrapScoped(
1158
+ core.map(
1159
+ options?.onEnd
1160
+ ? core.tap(
1161
+ fiberRuntime.makeSpanScoped(name, options),
1162
+ (span) => fiberRuntime.addFinalizer((exit) => options.onEnd!(span, exit))
1163
+ )
1164
+ : fiberRuntime.makeSpanScoped(name, options),
1165
+ (span) => withParentSpan(self, span)
1166
+ )
1167
+ )
1168
+ } as any
1146
1169
 
1147
1170
  /** @internal */
1148
1171
  export const withParentSpan = dual<