effect 4.0.0-beta.10 → 4.0.0-beta.11

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 (122) hide show
  1. package/dist/Channel.d.ts +7 -7
  2. package/dist/Effect.d.ts +217 -8
  3. package/dist/Effect.d.ts.map +1 -1
  4. package/dist/Effect.js +46 -0
  5. package/dist/Effect.js.map +1 -1
  6. package/dist/ErrorReporter.d.ts +376 -0
  7. package/dist/ErrorReporter.d.ts.map +1 -0
  8. package/dist/ErrorReporter.js +246 -0
  9. package/dist/ErrorReporter.js.map +1 -0
  10. package/dist/LogLevel.d.ts +5 -0
  11. package/dist/LogLevel.d.ts.map +1 -1
  12. package/dist/LogLevel.js.map +1 -1
  13. package/dist/Logger.d.ts +25 -91
  14. package/dist/Logger.d.ts.map +1 -1
  15. package/dist/Logger.js +2 -3
  16. package/dist/Logger.js.map +1 -1
  17. package/dist/Queue.d.ts.map +1 -1
  18. package/dist/Queue.js +0 -1
  19. package/dist/Queue.js.map +1 -1
  20. package/dist/References.d.ts +3 -3
  21. package/dist/References.d.ts.map +1 -1
  22. package/dist/SchemaAST.d.ts.map +1 -1
  23. package/dist/SchemaAST.js +2 -1
  24. package/dist/SchemaAST.js.map +1 -1
  25. package/dist/Stream.d.ts +5 -5
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/internal/effect.js +54 -4
  31. package/dist/internal/effect.js.map +1 -1
  32. package/dist/internal/hashMap.js +2 -2
  33. package/dist/internal/hashMap.js.map +1 -1
  34. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  35. package/dist/unstable/ai/LanguageModel.js +41 -0
  36. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  37. package/dist/unstable/cli/CliOutput.js +37 -6
  38. package/dist/unstable/cli/CliOutput.js.map +1 -1
  39. package/dist/unstable/cli/Command.d.ts +199 -7
  40. package/dist/unstable/cli/Command.d.ts.map +1 -1
  41. package/dist/unstable/cli/Command.js +116 -6
  42. package/dist/unstable/cli/Command.js.map +1 -1
  43. package/dist/unstable/cli/HelpDoc.d.ts +60 -2
  44. package/dist/unstable/cli/HelpDoc.d.ts.map +1 -1
  45. package/dist/unstable/cli/internal/command.d.ts +11 -1
  46. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  47. package/dist/unstable/cli/internal/command.js +33 -8
  48. package/dist/unstable/cli/internal/command.js.map +1 -1
  49. package/dist/unstable/cli/internal/completions/CommandDescriptor.js +7 -2
  50. package/dist/unstable/cli/internal/completions/CommandDescriptor.js.map +1 -1
  51. package/dist/unstable/cli/internal/parser.js +10 -2
  52. package/dist/unstable/cli/internal/parser.js.map +1 -1
  53. package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  54. package/dist/unstable/http/Headers.d.ts.map +1 -1
  55. package/dist/unstable/http/Headers.js +27 -10
  56. package/dist/unstable/http/Headers.js.map +1 -1
  57. package/dist/unstable/http/HttpEffect.d.ts.map +1 -1
  58. package/dist/unstable/http/HttpEffect.js +12 -7
  59. package/dist/unstable/http/HttpEffect.js.map +1 -1
  60. package/dist/unstable/http/HttpServerError.d.ts +8 -26
  61. package/dist/unstable/http/HttpServerError.d.ts.map +1 -1
  62. package/dist/unstable/http/HttpServerError.js +11 -27
  63. package/dist/unstable/http/HttpServerError.js.map +1 -1
  64. package/dist/unstable/http/HttpServerRespondable.d.ts +2 -2
  65. package/dist/unstable/http/HttpServerRespondable.d.ts.map +1 -1
  66. package/dist/unstable/http/HttpServerRespondable.js +5 -5
  67. package/dist/unstable/http/HttpServerRespondable.js.map +1 -1
  68. package/dist/unstable/http/HttpServerResponse.d.ts +2 -1
  69. package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
  70. package/dist/unstable/http/HttpServerResponse.js +2 -0
  71. package/dist/unstable/http/HttpServerResponse.js.map +1 -1
  72. package/dist/unstable/httpapi/HttpApiBuilder.js +1 -1
  73. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  74. package/dist/unstable/httpapi/HttpApiError.d.ts +11 -0
  75. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  76. package/dist/unstable/httpapi/HttpApiError.js +29 -9
  77. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  78. package/dist/unstable/observability/OtlpLogger.d.ts.map +1 -1
  79. package/dist/unstable/observability/OtlpLogger.js +7 -4
  80. package/dist/unstable/observability/OtlpLogger.js.map +1 -1
  81. package/dist/unstable/reactivity/AtomRegistry.d.ts +6 -0
  82. package/dist/unstable/reactivity/AtomRegistry.d.ts.map +1 -1
  83. package/dist/unstable/reactivity/AtomRegistry.js +22 -1
  84. package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
  85. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  86. package/dist/unstable/rpc/RpcServer.js +4 -0
  87. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  88. package/dist/unstable/workflow/WorkflowEngine.d.ts +6 -0
  89. package/dist/unstable/workflow/WorkflowEngine.d.ts.map +1 -1
  90. package/dist/unstable/workflow/WorkflowEngine.js +131 -0
  91. package/dist/unstable/workflow/WorkflowEngine.js.map +1 -1
  92. package/package.json +1 -1
  93. package/src/Channel.ts +9 -9
  94. package/src/Effect.ts +235 -8
  95. package/src/ErrorReporter.ts +459 -0
  96. package/src/LogLevel.ts +6 -0
  97. package/src/Logger.ts +28 -95
  98. package/src/Queue.ts +0 -1
  99. package/src/References.ts +4 -4
  100. package/src/SchemaAST.ts +2 -1
  101. package/src/Stream.ts +7 -7
  102. package/src/index.ts +5 -0
  103. package/src/internal/effect.ts +137 -14
  104. package/src/internal/hashMap.ts +2 -2
  105. package/src/unstable/ai/LanguageModel.ts +71 -0
  106. package/src/unstable/cli/CliOutput.ts +45 -6
  107. package/src/unstable/cli/Command.ts +298 -11
  108. package/src/unstable/cli/HelpDoc.ts +68 -2
  109. package/src/unstable/cli/internal/command.ts +47 -11
  110. package/src/unstable/cli/internal/completions/CommandDescriptor.ts +7 -2
  111. package/src/unstable/cli/internal/parser.ts +11 -3
  112. package/src/unstable/http/Headers.ts +28 -13
  113. package/src/unstable/http/HttpEffect.ts +10 -5
  114. package/src/unstable/http/HttpServerError.ts +13 -27
  115. package/src/unstable/http/HttpServerRespondable.ts +6 -6
  116. package/src/unstable/http/HttpServerResponse.ts +3 -1
  117. package/src/unstable/httpapi/HttpApiBuilder.ts +1 -0
  118. package/src/unstable/httpapi/HttpApiError.ts +30 -9
  119. package/src/unstable/observability/OtlpLogger.ts +9 -5
  120. package/src/unstable/reactivity/AtomRegistry.ts +29 -1
  121. package/src/unstable/rpc/RpcServer.ts +4 -0
  122. package/src/unstable/workflow/WorkflowEngine.ts +178 -0
@@ -4,7 +4,10 @@
4
4
  import type * as Cause from "../../Cause.ts"
5
5
  import * as Effect from "../../Effect.ts"
6
6
  import * as Exit from "../../Exit.ts"
7
+ import * as Fiber from "../../Fiber.ts"
8
+ import * as FiberMap from "../../FiberMap.ts"
7
9
  import * as Latch from "../../Latch.ts"
10
+ import * as Layer from "../../Layer.ts"
8
11
  import * as Option from "../../Option.ts"
9
12
  import * as Schedule from "../../Schedule.ts"
10
13
  import * as Schema from "../../Schema.ts"
@@ -498,4 +501,179 @@ const defaultRetrySchedule = Schedule.exponential(200, 1.5).pipe(
498
501
  Schedule.either(Schedule.spaced(30000))
499
502
  )
500
503
 
504
+ /**
505
+ * @since 4.0.0
506
+ * @category Layers
507
+ */
508
+ export const layer: Layer.Layer<WorkflowEngine> = Layer.effect(WorkflowEngine)(
509
+ Effect.gen(function*() {
510
+ const scope = yield* Effect.scope
511
+
512
+ const workflows = new Map<string, {
513
+ readonly workflow: Workflow.Any
514
+ readonly execute: (
515
+ payload: object,
516
+ executionId: string
517
+ ) => Effect.Effect<unknown, unknown, WorkflowInstance | WorkflowEngine>
518
+ readonly scope: Scope.Scope
519
+ }>()
520
+
521
+ type ExecutionState = {
522
+ readonly payload: object
523
+ readonly execute: (
524
+ payload: object,
525
+ executionId: string
526
+ ) => Effect.Effect<unknown, unknown, WorkflowInstance | WorkflowEngine>
527
+ readonly parent: string | undefined
528
+ instance: WorkflowInstance["Service"]
529
+ fiber: Fiber.Fiber<Workflow.Result<unknown, unknown>> | undefined
530
+ }
531
+ const executions = new Map<string, ExecutionState>()
532
+
533
+ type ActivityState = {
534
+ exit: Exit.Exit<Workflow.Result<unknown, unknown>> | undefined
535
+ }
536
+ const activities = new Map<string, ActivityState>()
537
+
538
+ const resume = Effect.fnUntraced(function*(executionId: string): Effect.fn.Return<void> {
539
+ const state = executions.get(executionId)
540
+ if (!state) return
541
+ const exit = state.fiber?.pollUnsafe()
542
+ if (exit && exit._tag === "Success" && exit.value._tag === "Complete") {
543
+ return
544
+ } else if (state.fiber && !exit) {
545
+ return
546
+ }
547
+
548
+ const entry = workflows.get(state.instance.workflow.name)!
549
+ const instance = WorkflowInstance.initial(state.instance.workflow, state.instance.executionId)
550
+ instance.interrupted = state.instance.interrupted
551
+ state.instance = instance
552
+ state.fiber = yield* state.execute(state.payload, state.instance.executionId).pipe(
553
+ Effect.onExit(() => {
554
+ if (!instance.interrupted) {
555
+ return Effect.void
556
+ }
557
+ instance.suspended = false
558
+ return Effect.withFiber((fiber) => Effect.interruptible(Fiber.interrupt(fiber)))
559
+ }),
560
+ Workflow.intoResult,
561
+ Effect.provideService(WorkflowInstance, instance),
562
+ Effect.provideService(WorkflowEngine, engine),
563
+ Effect.tap((result) => {
564
+ if (!state.parent || result._tag !== "Complete") {
565
+ return Effect.void
566
+ }
567
+ return Effect.forkIn(resume(state.parent), scope)
568
+ }),
569
+ Effect.forkIn(entry.scope)
570
+ )
571
+ })
572
+
573
+ const deferredResults = new Map<string, Exit.Exit<any, any>>()
574
+
575
+ const clocks = yield* FiberMap.make<string>()
576
+
577
+ const engine = makeUnsafe({
578
+ register: Effect.fnUntraced(function*(workflow, execute) {
579
+ workflows.set(workflow.name, {
580
+ workflow,
581
+ execute,
582
+ scope: yield* Effect.scope
583
+ })
584
+ }),
585
+ execute: Effect.fnUntraced(function*(workflow, options) {
586
+ const entry = workflows.get(workflow.name)
587
+ if (!entry) {
588
+ return yield* Effect.orDie(Effect.fail(`Workflow ${workflow.name} is not registered`))
589
+ }
590
+
591
+ let state = executions.get(options.executionId)
592
+ if (!state) {
593
+ state = {
594
+ payload: options.payload,
595
+ execute: entry.execute,
596
+ instance: WorkflowInstance.initial(workflow, options.executionId),
597
+ fiber: undefined,
598
+ parent: options.parent?.executionId
599
+ }
600
+ executions.set(options.executionId, state)
601
+ yield* resume(options.executionId)
602
+ }
603
+ if (options.discard) return
604
+ return (yield* Fiber.join(state.fiber!)) as any
605
+ }),
606
+ interrupt: Effect.fnUntraced(function*(_workflow, executionId) {
607
+ const state = executions.get(executionId)
608
+ if (!state) return
609
+ state.instance.interrupted = true
610
+ yield* resume(executionId)
611
+ }),
612
+ resume(_workflow, executionId) {
613
+ return resume(executionId)
614
+ },
615
+ activityExecute: Effect.fnUntraced(function*(activity, attempt) {
616
+ const instance = yield* WorkflowInstance
617
+ const activityId = `${instance.executionId}/${activity.name}/${attempt}`
618
+ let state = activities.get(activityId)
619
+ if (state) {
620
+ const exit = state.exit
621
+ if (exit && exit._tag === "Success" && exit.value._tag === "Suspended") {
622
+ state.exit = undefined
623
+ } else if (exit) {
624
+ return yield* exit
625
+ }
626
+ } else {
627
+ state = { exit: undefined }
628
+ activities.set(activityId, state)
629
+ }
630
+ const activityInstance = WorkflowInstance.initial(instance.workflow, instance.executionId)
631
+ activityInstance.interrupted = instance.interrupted
632
+ return yield* activity.executeEncoded.pipe(
633
+ Workflow.intoResult,
634
+ Effect.provideService(WorkflowInstance, activityInstance),
635
+ Effect.onExit((exit) => {
636
+ state.exit = exit
637
+ return Effect.void
638
+ })
639
+ )
640
+ }),
641
+ poll: (_workflow, executionId) =>
642
+ Effect.suspend(() => {
643
+ const state = executions.get(executionId)
644
+ if (!state) {
645
+ return Effect.succeed(undefined)
646
+ }
647
+ const exit = state.fiber?.pollUnsafe()
648
+ return exit ?? Effect.succeed(undefined)
649
+ }),
650
+ deferredResult: Effect.fnUntraced(function*(deferred) {
651
+ const instance = yield* WorkflowInstance
652
+ const id = `${instance.executionId}/${deferred.name}`
653
+ return deferredResults.get(id)
654
+ }),
655
+ deferredDone: (options) =>
656
+ Effect.suspend(() => {
657
+ const id = `${options.executionId}/${options.deferredName}`
658
+ if (deferredResults.has(id)) return Effect.void
659
+ deferredResults.set(id, options.exit)
660
+ return resume(options.executionId)
661
+ }),
662
+ scheduleClock: (workflow, options) =>
663
+ engine.deferredDone(options.clock.deferred, {
664
+ workflowName: workflow.name,
665
+ executionId: options.executionId,
666
+ deferredName: options.clock.deferred.name,
667
+ exit: Exit.void
668
+ }).pipe(
669
+ Effect.delay(options.clock.duration),
670
+ FiberMap.run(clocks, `${options.executionId}/${options.clock.name}`, { onlyIfMissing: true }),
671
+ Effect.asVoid
672
+ )
673
+ })
674
+
675
+ return engine
676
+ })
677
+ )
678
+
501
679
  const toJsonExit = Exit.map((value: any) => value ?? null)