effect 4.0.0-beta.53 → 4.0.0-beta.55

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.
@@ -50,6 +50,12 @@ export interface Socket {
50
50
  readonly onOpen?: Effect.Effect<void> | undefined
51
51
  }
52
52
  ) => Effect.Effect<void, SocketError | E, R>
53
+ readonly runString: <_, E = never, R = never>(
54
+ handler: (_: string) => Effect.Effect<_, E, R> | void,
55
+ options?: {
56
+ readonly onOpen?: Effect.Effect<void> | undefined
57
+ }
58
+ ) => Effect.Effect<void, SocketError | E, R>
53
59
  readonly runRaw: <_, E = never, R = never>(
54
60
  handler: (_: string | Uint8Array) => Effect.Effect<_, E, R> | void,
55
61
  options?: {
@@ -63,6 +69,61 @@ export interface Socket {
63
69
  >
64
70
  }
65
71
 
72
+ /**
73
+ * @since 4.0.0
74
+ * @category Constructors
75
+ */
76
+ export const make = (options: {
77
+ readonly runRaw: <_, E, R>(
78
+ handler: (_: string | Uint8Array) => Effect.Effect<_, E, R> | void,
79
+ options?: {
80
+ readonly onOpen?: Effect.Effect<void> | undefined
81
+ }
82
+ ) => Effect.Effect<void, SocketError | E, R>
83
+ readonly run?: <_, E, R>(
84
+ handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void,
85
+ options?: {
86
+ readonly onOpen?: Effect.Effect<void> | undefined
87
+ }
88
+ ) => Effect.Effect<void, SocketError | E, R>
89
+ readonly runString?: <_, E, R>(
90
+ handler: (_: string) => Effect.Effect<_, E, R> | void,
91
+ options?: {
92
+ readonly onOpen?: Effect.Effect<void> | undefined
93
+ }
94
+ ) => Effect.Effect<void, SocketError | E, R>
95
+ readonly writer: Effect.Effect<
96
+ (chunk: Uint8Array | string | CloseEvent) => Effect.Effect<void, SocketError>,
97
+ never,
98
+ Scope.Scope
99
+ >
100
+ }): Socket =>
101
+ Socket.of({
102
+ [TypeId]: TypeId,
103
+ runRaw: options.runRaw,
104
+ run: options.run ?? ((handler, opts) =>
105
+ options.runRaw((data) =>
106
+ typeof data === "string"
107
+ ? handler(encoder.encode(data))
108
+ : data instanceof Uint8Array
109
+ ? handler(data)
110
+ : handler(new Uint8Array(data)), opts)),
111
+ runString: options.runString ??
112
+ (options.run ?
113
+ (handler, opts) => options.run!((data) => handler(decoder.decode(data)), opts) :
114
+ (handler, opts) =>
115
+ options.runRaw((data) =>
116
+ typeof data === "string"
117
+ ? handler(data)
118
+ : data instanceof Uint8Array
119
+ ? handler(decoder.decode(data))
120
+ : handler(decoder.decode(new Uint8Array(data))), opts)),
121
+ writer: options.writer
122
+ })
123
+
124
+ const encoder = new TextEncoder()
125
+ const decoder = new TextDecoder()
126
+
66
127
  const CloseEventTypeId = "~effect/socket/Socket/CloseEvent"
67
128
 
68
129
  /**
@@ -563,17 +624,6 @@ export const fromWebSocket = <RO>(
563
624
  }))
564
625
  )
565
626
 
566
- const encoder = new TextEncoder()
567
- const run = <_, E, R>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void, opts?: {
568
- readonly onOpen?: Effect.Effect<void> | undefined
569
- }) =>
570
- runRaw((data) =>
571
- typeof data === "string"
572
- ? handler(encoder.encode(data))
573
- : data instanceof Uint8Array
574
- ? handler(data)
575
- : handler(new Uint8Array(data)), opts)
576
-
577
627
  const write = (chunk: Uint8Array | string | CloseEvent) =>
578
628
  latch.whenOpen(Effect.sync(() => {
579
629
  const ws = currentWS!
@@ -585,9 +635,7 @@ export const fromWebSocket = <RO>(
585
635
  }))
586
636
  const writer = Effect.succeed(write)
587
637
 
588
- return Effect.succeed(Socket.of({
589
- [TypeId]: TypeId,
590
- run,
638
+ return Effect.succeed(make({
591
639
  runRaw,
592
640
  writer
593
641
  }))
@@ -711,15 +759,6 @@ export const fromTransformStream = <R>(acquire: Effect.Effect<InputTransformStre
711
759
  }))
712
760
  )
713
761
 
714
- const encoder = new TextEncoder()
715
- const run = <_, E, R>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void, opts?: {
716
- readonly onOpen?: Effect.Effect<void> | undefined
717
- }) =>
718
- runRaw((data) =>
719
- typeof data === "string"
720
- ? handler(encoder.encode(data))
721
- : handler(data), opts)
722
-
723
762
  const writers = new WeakMap<InputTransformStream, WritableStreamDefaultWriter<Uint8Array>>()
724
763
  const getWriter = (stream: InputTransformStream) => {
725
764
  let writer = writers.get(stream)
@@ -751,9 +790,7 @@ export const fromTransformStream = <R>(acquire: Effect.Effect<InputTransformStre
751
790
  })
752
791
  )
753
792
 
754
- return Effect.succeed(Socket.of({
755
- [TypeId]: TypeId,
756
- run,
793
+ return Effect.succeed(make({
757
794
  runRaw,
758
795
  writer
759
796
  }))
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * @since 4.0.0
3
3
  */
4
+ import * as Arr from "../../Array.ts"
4
5
  import type { NonEmptyReadonlyArray } from "../../Array.ts"
5
6
  import type * as Brand from "../../Brand.ts"
6
- import type * as Cause from "../../Cause.ts"
7
+ import * as Cause from "../../Cause.ts"
7
8
  import * as Context from "../../Context.ts"
8
9
  import * as Effect from "../../Effect.ts"
9
10
  import * as Encoding from "../../Encoding.ts"
10
11
  import * as Exit from "../../Exit.ts"
12
+ import * as Filter from "../../Filter.ts"
11
13
  import { dual } from "../../Function.ts"
12
14
  import * as Option from "../../Option.ts"
13
15
  import * as Schema from "../../Schema.ts"
@@ -193,11 +195,24 @@ export const into: {
193
195
  Effect.contextWith(
194
196
  (context: Context.Context<WorkflowEngine | WorkflowInstance>) => {
195
197
  const engine = Context.get(context, EngineTag)
196
- const instance = Context.get(context, InstanceTag)
198
+ const parentInstance = Context.get(context, InstanceTag)
199
+ const instance = { ...parentInstance }
197
200
  return Effect.onExit(
198
- effect,
201
+ Effect.provideService(effect, InstanceTag, instance),
199
202
  Effect.fnUntraced(function*(exit) {
200
- if (instance.suspended) return
203
+ if (Exit.isFailure(exit)) {
204
+ const [reasons, interrupts] = Arr.partition(
205
+ exit.cause.reasons,
206
+ Filter.fromPredicate(Cause.isInterruptReason)
207
+ )
208
+ const hasInterruptsOnly = interrupts.length === exit.cause.reasons.length
209
+ if (hasInterruptsOnly && instance.suspended) {
210
+ parentInstance.suspended = true
211
+ return
212
+ } else if (interrupts.length > 0) {
213
+ exit = Exit.failCause(Cause.fromReasons(reasons))
214
+ }
215
+ }
201
216
  yield* engine.deferredDone(self, {
202
217
  workflowName: instance.workflow.name,
203
218
  executionId: instance.executionId,
@@ -244,7 +259,10 @@ export const raceAll = <
244
259
  if (Option.isSome(exit)) {
245
260
  return yield* Effect.flatten(exit.value) as Effect.Effect<any, any, any>
246
261
  }
247
- return yield* into(Effect.raceAll(options.effects), deferred)
262
+ return yield* into(
263
+ Effect.raceAll(options.effects),
264
+ deferred
265
+ )
248
266
  })
249
267
  }
250
268
 
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * @since 4.0.0
3
3
  */
4
+ import * as Arr from "../../Array.ts"
4
5
  import * as Cause from "../../Cause.ts"
5
6
  import * as Context from "../../Context.ts"
6
7
  import * as Data from "../../Data.ts"
7
8
  import * as Effect from "../../Effect.ts"
8
9
  import * as Exit from "../../Exit.ts"
9
10
  import * as Fiber from "../../Fiber.ts"
11
+ import * as Filter from "../../Filter.ts"
10
12
  import { constFalse, constTrue, dual, identity } from "../../Function.ts"
11
13
  import * as Layer from "../../Layer.ts"
12
14
  import * as Option from "../../Option.ts"
@@ -578,13 +580,20 @@ export const intoResult = <A, E, R>(
578
580
  Effect.scoped,
579
581
  Effect.matchCauseEffect({
580
582
  onSuccess: (value) => Effect.succeed(new Complete({ exit: Exit.succeed(value) })),
581
- onFailure: (cause): Effect.Effect<Result<A, E>> =>
582
- instance.suspended
583
+ onFailure: (cause): Effect.Effect<Result<A, E>> => {
584
+ const [reasons, interrupts] = Arr.partition(
585
+ cause.reasons,
586
+ Filter.fromPredicate(Cause.isInterruptReason)
587
+ )
588
+ const hasInterruptsOnly = interrupts.length === cause.reasons.length
589
+ const filtered = reasons.length === 0 ? cause : Cause.fromReasons(reasons)
590
+ return instance.suspended && hasInterruptsOnly
583
591
  ? Effect.succeed(new Suspended({ cause: instance.cause }))
584
- : (!instance.interrupted && Cause.hasInterruptsOnly(cause)) ||
592
+ : (!instance.interrupted && hasInterruptsOnly) ||
585
593
  (!captureDefects && Cause.hasDies(cause))
586
- ? Effect.failCause(cause as Cause.Cause<never>)
587
- : Effect.succeed(new Complete({ exit: Exit.failCause(cause) }))
594
+ ? Effect.failCause(filtered as Cause.Cause<never>)
595
+ : Effect.succeed(new Complete({ exit: Exit.failCause(filtered) }))
596
+ }
588
597
  }),
589
598
  (eff) =>
590
599
  Effect.onExitPrimitive(eff, (exit) => {
@@ -610,11 +619,6 @@ export const wrapActivityResult = <A, E, R>(
610
619
  Effect.contextWith((context: Context.Context<WorkflowInstance>) => {
611
620
  const instance = Context.get(context, InstanceTag)
612
621
  const state = instance.activityState
613
- if (instance.suspended) {
614
- return waitForZero(instance).pipe(
615
- Effect.andThen(suspend(instance))
616
- )
617
- }
618
622
  if (state.count === 0) state.latch.closeUnsafe()
619
623
  state.count++
620
624
  return Effect.onExit(effect, (exit) => {