effect 4.0.0-beta.10 → 4.0.0-beta.12
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/dist/Channel.d.ts +7 -7
- package/dist/Config.d.ts +157 -0
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js +56 -1
- package/dist/Config.js.map +1 -1
- package/dist/Effect.d.ts +296 -8
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +72 -0
- package/dist/Effect.js.map +1 -1
- package/dist/ErrorReporter.d.ts +376 -0
- package/dist/ErrorReporter.d.ts.map +1 -0
- package/dist/ErrorReporter.js +246 -0
- package/dist/ErrorReporter.js.map +1 -0
- package/dist/Fiber.d.ts +2 -2
- package/dist/Fiber.d.ts.map +1 -1
- package/dist/Fiber.js.map +1 -1
- package/dist/Graph.d.ts.map +1 -1
- package/dist/Graph.js +3 -6
- package/dist/Graph.js.map +1 -1
- package/dist/LogLevel.d.ts +5 -0
- package/dist/LogLevel.d.ts.map +1 -1
- package/dist/LogLevel.js.map +1 -1
- package/dist/Logger.d.ts +25 -91
- package/dist/Logger.d.ts.map +1 -1
- package/dist/Logger.js +2 -3
- package/dist/Logger.js.map +1 -1
- package/dist/Queue.d.ts.map +1 -1
- package/dist/Queue.js +0 -1
- package/dist/Queue.js.map +1 -1
- package/dist/Random.d.ts +17 -0
- package/dist/Random.d.ts.map +1 -1
- package/dist/Random.js +17 -0
- package/dist/Random.js.map +1 -1
- package/dist/References.d.ts +3 -3
- package/dist/References.d.ts.map +1 -1
- package/dist/Schema.d.ts +3 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +2 -1
- package/dist/SchemaAST.js.map +1 -1
- package/dist/Stream.d.ts +5 -5
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/effect.js +98 -33
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/hashMap.js +2 -2
- package/dist/internal/hashMap.js.map +1 -1
- package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
- package/dist/unstable/ai/LanguageModel.js +86 -14
- package/dist/unstable/ai/LanguageModel.js.map +1 -1
- package/dist/unstable/ai/McpSchema.d.ts +112 -36
- package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
- package/dist/unstable/ai/McpSchema.js +47 -10
- package/dist/unstable/ai/McpSchema.js.map +1 -1
- package/dist/unstable/ai/McpServer.d.ts.map +1 -1
- package/dist/unstable/ai/McpServer.js +33 -6
- package/dist/unstable/ai/McpServer.js.map +1 -1
- package/dist/unstable/ai/Tool.d.ts +16 -0
- package/dist/unstable/ai/Tool.d.ts.map +1 -1
- package/dist/unstable/ai/Tool.js +14 -0
- package/dist/unstable/ai/Tool.js.map +1 -1
- package/dist/unstable/cli/CliOutput.js +37 -6
- package/dist/unstable/cli/CliOutput.js.map +1 -1
- package/dist/unstable/cli/Command.d.ts +199 -7
- package/dist/unstable/cli/Command.d.ts.map +1 -1
- package/dist/unstable/cli/Command.js +116 -6
- package/dist/unstable/cli/Command.js.map +1 -1
- package/dist/unstable/cli/HelpDoc.d.ts +60 -2
- package/dist/unstable/cli/HelpDoc.d.ts.map +1 -1
- package/dist/unstable/cli/internal/command.d.ts +11 -1
- package/dist/unstable/cli/internal/command.d.ts.map +1 -1
- package/dist/unstable/cli/internal/command.js +33 -8
- package/dist/unstable/cli/internal/command.js.map +1 -1
- package/dist/unstable/cli/internal/completions/CommandDescriptor.js +7 -2
- package/dist/unstable/cli/internal/completions/CommandDescriptor.js.map +1 -1
- package/dist/unstable/cli/internal/parser.js +10 -2
- package/dist/unstable/cli/internal/parser.js.map +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.js +2 -2
- package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/unstable/http/Headers.d.ts.map +1 -1
- package/dist/unstable/http/Headers.js +27 -10
- package/dist/unstable/http/Headers.js.map +1 -1
- package/dist/unstable/http/HttpClient.d.ts +28 -4
- package/dist/unstable/http/HttpClient.d.ts.map +1 -1
- package/dist/unstable/http/HttpClient.js.map +1 -1
- package/dist/unstable/http/HttpEffect.d.ts +3 -8
- package/dist/unstable/http/HttpEffect.d.ts.map +1 -1
- package/dist/unstable/http/HttpEffect.js +25 -31
- package/dist/unstable/http/HttpEffect.js.map +1 -1
- package/dist/unstable/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/unstable/http/HttpMiddleware.js +4 -8
- package/dist/unstable/http/HttpMiddleware.js.map +1 -1
- package/dist/unstable/http/HttpServerError.d.ts +14 -27
- package/dist/unstable/http/HttpServerError.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerError.js +37 -44
- package/dist/unstable/http/HttpServerError.js.map +1 -1
- package/dist/unstable/http/HttpServerRespondable.d.ts +2 -2
- package/dist/unstable/http/HttpServerRespondable.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerRespondable.js +5 -5
- package/dist/unstable/http/HttpServerRespondable.js.map +1 -1
- package/dist/unstable/http/HttpServerResponse.d.ts +2 -1
- package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerResponse.js +2 -0
- package/dist/unstable/http/HttpServerResponse.js.map +1 -1
- package/dist/unstable/http/internal/preResponseHandler.d.ts +2 -0
- package/dist/unstable/http/internal/preResponseHandler.d.ts.map +1 -0
- package/dist/unstable/http/internal/preResponseHandler.js +10 -0
- package/dist/unstable/http/internal/preResponseHandler.js.map +1 -0
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.js +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiError.d.ts +11 -0
- package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiError.js +29 -9
- package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
- package/dist/unstable/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpLogger.js +7 -4
- package/dist/unstable/observability/OtlpLogger.js.map +1 -1
- package/dist/unstable/reactivity/Atom.js +1 -1
- package/dist/unstable/reactivity/Atom.js.map +1 -1
- package/dist/unstable/reactivity/AtomRegistry.d.ts +6 -0
- package/dist/unstable/reactivity/AtomRegistry.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomRegistry.js +22 -1
- package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
- package/dist/unstable/rpc/RpcSchema.d.ts +13 -0
- package/dist/unstable/rpc/RpcSchema.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcSchema.js +14 -0
- package/dist/unstable/rpc/RpcSchema.js.map +1 -1
- package/dist/unstable/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcSerialization.js +34 -9
- package/dist/unstable/rpc/RpcSerialization.js.map +1 -1
- package/dist/unstable/rpc/RpcServer.d.ts +0 -7
- package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcServer.js +9 -10
- package/dist/unstable/rpc/RpcServer.js.map +1 -1
- package/dist/unstable/workflow/WorkflowEngine.d.ts +6 -0
- package/dist/unstable/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/unstable/workflow/WorkflowEngine.js +131 -0
- package/dist/unstable/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +1 -1
- package/src/Channel.ts +9 -9
- package/src/Config.ts +171 -9
- package/src/Effect.ts +315 -8
- package/src/ErrorReporter.ts +459 -0
- package/src/Fiber.ts +9 -2
- package/src/Graph.ts +16 -6
- package/src/LogLevel.ts +6 -0
- package/src/Logger.ts +28 -95
- package/src/Queue.ts +0 -1
- package/src/Random.ts +18 -0
- package/src/References.ts +4 -4
- package/src/Schema.ts +1 -1
- package/src/SchemaAST.ts +2 -1
- package/src/Stream.ts +7 -7
- package/src/index.ts +5 -0
- package/src/internal/effect.ts +205 -49
- package/src/internal/hashMap.ts +2 -2
- package/src/unstable/ai/LanguageModel.ts +117 -16
- package/src/unstable/ai/McpSchema.ts +57 -11
- package/src/unstable/ai/McpServer.ts +44 -6
- package/src/unstable/ai/Tool.ts +15 -0
- package/src/unstable/cli/CliOutput.ts +45 -6
- package/src/unstable/cli/Command.ts +298 -11
- package/src/unstable/cli/HelpDoc.ts +68 -2
- package/src/unstable/cli/internal/command.ts +47 -11
- package/src/unstable/cli/internal/completions/CommandDescriptor.ts +7 -2
- package/src/unstable/cli/internal/parser.ts +11 -3
- package/src/unstable/cluster/ClusterWorkflowEngine.ts +2 -2
- package/src/unstable/http/Headers.ts +28 -13
- package/src/unstable/http/HttpClient.ts +45 -10
- package/src/unstable/http/HttpEffect.ts +30 -44
- package/src/unstable/http/HttpMiddleware.ts +4 -14
- package/src/unstable/http/HttpServerError.ts +42 -45
- package/src/unstable/http/HttpServerRespondable.ts +6 -6
- package/src/unstable/http/HttpServerResponse.ts +3 -1
- package/src/unstable/http/internal/preResponseHandler.ts +15 -0
- package/src/unstable/httpapi/HttpApiBuilder.ts +2 -1
- package/src/unstable/httpapi/HttpApiError.ts +30 -9
- package/src/unstable/observability/OtlpLogger.ts +9 -5
- package/src/unstable/reactivity/Atom.ts +1 -1
- package/src/unstable/reactivity/AtomRegistry.ts +29 -1
- package/src/unstable/rpc/RpcSchema.ts +17 -0
- package/src/unstable/rpc/RpcSerialization.ts +44 -9
- package/src/unstable/rpc/RpcServer.ts +14 -19
- package/src/unstable/workflow/WorkflowEngine.ts +178 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Effect from "../../Effect.ts"
|
|
5
|
+
import * as ErrorReporter from "../../ErrorReporter.ts"
|
|
5
6
|
import type * as FileSystem from "../../FileSystem.ts"
|
|
6
7
|
import { dual } from "../../Function.ts"
|
|
7
8
|
import type * as Inspectable from "../../Inspectable.ts"
|
|
@@ -28,7 +29,7 @@ const TypeId = "~effect/http/HttpServerResponse"
|
|
|
28
29
|
* @since 4.0.0
|
|
29
30
|
* @category models
|
|
30
31
|
*/
|
|
31
|
-
export interface HttpServerResponse extends Inspectable.Inspectable, Pipeable {
|
|
32
|
+
export interface HttpServerResponse extends Inspectable.Inspectable, Pipeable, ErrorReporter.Reportable {
|
|
32
33
|
readonly [TypeId]: typeof TypeId
|
|
33
34
|
readonly status: number
|
|
34
35
|
readonly statusText?: string | undefined
|
|
@@ -834,6 +835,7 @@ const Proto: Omit<
|
|
|
834
835
|
> = {
|
|
835
836
|
...PipeInspectableProto,
|
|
836
837
|
[TypeId]: TypeId,
|
|
838
|
+
[ErrorReporter.ignore]: true,
|
|
837
839
|
toJSON(this: HttpServerResponse) {
|
|
838
840
|
return {
|
|
839
841
|
_id: "HttpServerResponse",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as Effect from "../../../Effect.ts"
|
|
2
|
+
import type { PreResponseHandler } from "../HttpEffect.ts"
|
|
3
|
+
import type { HttpServerRequest } from "../HttpServerRequest.ts"
|
|
4
|
+
|
|
5
|
+
/** @internal */
|
|
6
|
+
export const requestPreResponseHandlers = new WeakMap<HttpServerRequest, PreResponseHandler>()
|
|
7
|
+
|
|
8
|
+
/** @internal */
|
|
9
|
+
export const appendPreResponseHandlerUnsafe = (request: HttpServerRequest, handler: PreResponseHandler): void => {
|
|
10
|
+
const prev = requestPreResponseHandlers.get(request)
|
|
11
|
+
const next: PreResponseHandler = prev ?
|
|
12
|
+
(request, response) => Effect.flatMap(prev(request, response), (response) => handler(request, response))
|
|
13
|
+
: handler
|
|
14
|
+
requestPreResponseHandlers.set(request, next)
|
|
15
|
+
}
|
|
@@ -356,7 +356,7 @@ export const securitySetCookie = (
|
|
|
356
356
|
self: HttpApiSecurity.ApiKey,
|
|
357
357
|
value: string | Redacted.Redacted,
|
|
358
358
|
options?: Cookie["options"]
|
|
359
|
-
): Effect.Effect<void> =>
|
|
359
|
+
): Effect.Effect<void, never, HttpServerRequest> =>
|
|
360
360
|
HttpEffect.appendPreResponseHandler((_req, response) =>
|
|
361
361
|
Effect.orDie(
|
|
362
362
|
Response.setCookie(response, self.key, stringOrRedacted(value), {
|
|
@@ -549,6 +549,7 @@ function handlerToRoute(
|
|
|
549
549
|
return Response.isHttpServerResponse(response) ? response : yield* encodeSuccess(response)
|
|
550
550
|
})
|
|
551
551
|
).pipe(
|
|
552
|
+
Effect.withErrorReporting,
|
|
552
553
|
Effect.catch((error) => {
|
|
553
554
|
if (Schema.isSchemaError(error)) {
|
|
554
555
|
error = HttpApiSchemaError.fromSchemaError(error)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
|
+
import * as ErrorReporter from "../../ErrorReporter.ts"
|
|
4
5
|
import * as Schema from "../../Schema.ts"
|
|
5
6
|
import * as HttpApiSchema from "./HttpApiSchema.ts"
|
|
6
7
|
|
|
@@ -21,6 +22,8 @@ export class HttpApiSchemaError extends Schema.ErrorClass<HttpApiSchemaError>("e
|
|
|
21
22
|
static fromSchemaError(error: Schema.SchemaError): HttpApiSchemaError {
|
|
22
23
|
return new HttpApiSchemaError({ message: error.message })
|
|
23
24
|
}
|
|
25
|
+
|
|
26
|
+
override readonly [ErrorReporter.ignore] = true
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
/**
|
|
@@ -32,7 +35,9 @@ export class BadRequest extends Schema.ErrorClass<BadRequest>("effect/HttpApiErr
|
|
|
32
35
|
}, {
|
|
33
36
|
description: "BadRequest",
|
|
34
37
|
httpApiStatus: 400
|
|
35
|
-
}) {
|
|
38
|
+
}) {
|
|
39
|
+
override readonly [ErrorReporter.ignore] = true
|
|
40
|
+
}
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
43
|
* @category NoContent errors
|
|
@@ -51,7 +56,9 @@ export class Unauthorized extends Schema.ErrorClass<Unauthorized>("effect/HttpAp
|
|
|
51
56
|
}, {
|
|
52
57
|
description: "Unauthorized",
|
|
53
58
|
httpApiStatus: 401
|
|
54
|
-
}) {
|
|
59
|
+
}) {
|
|
60
|
+
override readonly [ErrorReporter.ignore] = true
|
|
61
|
+
}
|
|
55
62
|
|
|
56
63
|
/**
|
|
57
64
|
* @category NoContent errors
|
|
@@ -70,7 +77,9 @@ export class Forbidden extends Schema.ErrorClass<Forbidden>("effect/HttpApiError
|
|
|
70
77
|
}, {
|
|
71
78
|
description: "Forbidden",
|
|
72
79
|
httpApiStatus: 403
|
|
73
|
-
}) {
|
|
80
|
+
}) {
|
|
81
|
+
override readonly [ErrorReporter.ignore] = true
|
|
82
|
+
}
|
|
74
83
|
|
|
75
84
|
/**
|
|
76
85
|
* @category NoContent errors
|
|
@@ -89,7 +98,9 @@ export class NotFound extends Schema.ErrorClass<NotFound>("effect/HttpApiError/N
|
|
|
89
98
|
}, {
|
|
90
99
|
description: "NotFound",
|
|
91
100
|
httpApiStatus: 404
|
|
92
|
-
}) {
|
|
101
|
+
}) {
|
|
102
|
+
override readonly [ErrorReporter.ignore] = true
|
|
103
|
+
}
|
|
93
104
|
|
|
94
105
|
/**
|
|
95
106
|
* @category NoContent errors
|
|
@@ -108,7 +119,9 @@ export class MethodNotAllowed extends Schema.ErrorClass<MethodNotAllowed>("effec
|
|
|
108
119
|
}, {
|
|
109
120
|
description: "MethodNotAllowed",
|
|
110
121
|
httpApiStatus: 405
|
|
111
|
-
}) {
|
|
122
|
+
}) {
|
|
123
|
+
override readonly [ErrorReporter.ignore] = true
|
|
124
|
+
}
|
|
112
125
|
|
|
113
126
|
/**
|
|
114
127
|
* @category NoContent errors
|
|
@@ -127,7 +140,9 @@ export class NotAcceptable extends Schema.ErrorClass<NotAcceptable>("effect/Http
|
|
|
127
140
|
}, {
|
|
128
141
|
description: "NotAcceptable",
|
|
129
142
|
httpApiStatus: 406
|
|
130
|
-
}) {
|
|
143
|
+
}) {
|
|
144
|
+
override readonly [ErrorReporter.ignore] = true
|
|
145
|
+
}
|
|
131
146
|
|
|
132
147
|
/**
|
|
133
148
|
* @category NoContent errors
|
|
@@ -146,7 +161,9 @@ export class RequestTimeout extends Schema.ErrorClass<RequestTimeout>("effect/Ht
|
|
|
146
161
|
}, {
|
|
147
162
|
description: "RequestTimeout",
|
|
148
163
|
httpApiStatus: 408
|
|
149
|
-
}) {
|
|
164
|
+
}) {
|
|
165
|
+
override readonly [ErrorReporter.ignore] = true
|
|
166
|
+
}
|
|
150
167
|
|
|
151
168
|
/**
|
|
152
169
|
* @category NoContent errors
|
|
@@ -165,7 +182,9 @@ export class Conflict extends Schema.ErrorClass<Conflict>("effect/HttpApiError/C
|
|
|
165
182
|
}, {
|
|
166
183
|
description: "Conflict",
|
|
167
184
|
httpApiStatus: 409
|
|
168
|
-
}) {
|
|
185
|
+
}) {
|
|
186
|
+
override readonly [ErrorReporter.ignore] = true
|
|
187
|
+
}
|
|
169
188
|
|
|
170
189
|
/**
|
|
171
190
|
* @since 4.0.0
|
|
@@ -184,7 +203,9 @@ export class Gone extends Schema.ErrorClass<Gone>("effect/HttpApiError/Gone")({
|
|
|
184
203
|
}, {
|
|
185
204
|
description: "Gone",
|
|
186
205
|
httpApiStatus: 410
|
|
187
|
-
}) {
|
|
206
|
+
}) {
|
|
207
|
+
override readonly [ErrorReporter.ignore] = true
|
|
208
|
+
}
|
|
188
209
|
|
|
189
210
|
/**
|
|
190
211
|
* @category NoContent errors
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import * as Arr from "../../Array.ts"
|
|
5
5
|
import * as Cause from "../../Cause.ts"
|
|
6
|
+
import { Clock } from "../../Clock.ts"
|
|
6
7
|
import * as Duration from "../../Duration.ts"
|
|
7
8
|
import * as Effect from "../../Effect.ts"
|
|
8
9
|
import type * as Layer from "../../Layer.ts"
|
|
@@ -66,7 +67,8 @@ export const make: (
|
|
|
66
67
|
})
|
|
67
68
|
|
|
68
69
|
const opts = {
|
|
69
|
-
excludeLogSpans: options.excludeLogSpans ?? false
|
|
70
|
+
excludeLogSpans: options.excludeLogSpans ?? false,
|
|
71
|
+
clock: yield* Clock
|
|
70
72
|
}
|
|
71
73
|
return Logger.make((options) => {
|
|
72
74
|
exporter.push(makeLogRecord(options, opts))
|
|
@@ -104,11 +106,13 @@ export interface LogsData {
|
|
|
104
106
|
|
|
105
107
|
// internal
|
|
106
108
|
|
|
107
|
-
const makeLogRecord = (options: Logger.
|
|
109
|
+
const makeLogRecord = (options: Logger.Options<unknown>, opts: {
|
|
108
110
|
readonly excludeLogSpans: boolean
|
|
111
|
+
readonly clock: Clock
|
|
109
112
|
}): ILogRecord => {
|
|
110
|
-
const now =
|
|
111
|
-
const nanosString =
|
|
113
|
+
const now = opts.clock.currentTimeNanosUnsafe()
|
|
114
|
+
const nanosString = now.toString()
|
|
115
|
+
const nowMillis = options.date.getTime()
|
|
112
116
|
|
|
113
117
|
const attributes = OtlpResource.entriesToAttributes(Object.entries(options.fiber.getRef(CurrentLogAnnotations)))
|
|
114
118
|
attributes.push({
|
|
@@ -119,7 +123,7 @@ const makeLogRecord = (options: Logger.Logger.Options<unknown>, opts: {
|
|
|
119
123
|
for (const [label, startTime] of options.fiber.getRef(CurrentLogSpans)) {
|
|
120
124
|
attributes.push({
|
|
121
125
|
key: `logSpan.${label}`,
|
|
122
|
-
value: { stringValue: `${
|
|
126
|
+
value: { stringValue: `${nowMillis - startTime}ms` }
|
|
123
127
|
})
|
|
124
128
|
}
|
|
125
129
|
}
|
|
@@ -2070,7 +2070,7 @@ export const searchParam = <S extends Schema.Codec<any, string> = never>(name: s
|
|
|
2070
2070
|
window.removeEventListener("pushstate", handleUpdate)
|
|
2071
2071
|
})
|
|
2072
2072
|
const value = new URLSearchParams(window.location.search).get(name) || ""
|
|
2073
|
-
return decode ? Exit.
|
|
2073
|
+
return decode ? Exit.getSuccess(decode(value)) : value as any
|
|
2074
2074
|
},
|
|
2075
2075
|
(ctx, value: any) => {
|
|
2076
2076
|
if (typeof window === "undefined") {
|
|
@@ -56,6 +56,8 @@ export interface AtomRegistry {
|
|
|
56
56
|
}) => () => void
|
|
57
57
|
readonly reset: () => void
|
|
58
58
|
readonly dispose: () => void
|
|
59
|
+
onNodeAdded?: ((node: Node<any>) => void) | undefined
|
|
60
|
+
onNodeRemoved?: ((node: Node<any>) => void) | undefined
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
/**
|
|
@@ -65,6 +67,10 @@ export interface AtomRegistry {
|
|
|
65
67
|
export interface Node<A> {
|
|
66
68
|
readonly atom: Atom.Atom<A>
|
|
67
69
|
readonly value: () => A
|
|
70
|
+
parents: Array<Node<any>>
|
|
71
|
+
children: Array<Node<any>>
|
|
72
|
+
listeners: Set<() => void>
|
|
73
|
+
currentState(): "uninitialized" | "stale" | "valid" | "removed"
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
/**
|
|
@@ -290,6 +296,8 @@ class RegistryImpl implements AtomRegistry {
|
|
|
290
296
|
readonly defaultIdleTTL: number | undefined
|
|
291
297
|
readonly scheduler: Scheduler
|
|
292
298
|
readonly schedulerAsync: Scheduler
|
|
299
|
+
onNodeAdded?: ((node: Node<any>) => void) | undefined
|
|
300
|
+
onNodeRemoved?: ((node: Node<any>) => void) | undefined
|
|
293
301
|
|
|
294
302
|
constructor(
|
|
295
303
|
initialValues?: Iterable<readonly [Atom.Atom<any>, any]>,
|
|
@@ -386,6 +394,7 @@ class RegistryImpl implements AtomRegistry {
|
|
|
386
394
|
if (node === undefined) {
|
|
387
395
|
node = this.createNode(atom)
|
|
388
396
|
this.nodes.set(key, node)
|
|
397
|
+
this.onNodeAdded?.(node)
|
|
389
398
|
} else if (this.atomHasTtl(atom)) {
|
|
390
399
|
this.removeNodeTimeout(node)
|
|
391
400
|
}
|
|
@@ -436,6 +445,7 @@ class RegistryImpl implements AtomRegistry {
|
|
|
436
445
|
} else {
|
|
437
446
|
this.nodes.delete(atomKey(node.atom))
|
|
438
447
|
node.remove()
|
|
448
|
+
this.onNodeRemoved?.(node)
|
|
439
449
|
}
|
|
440
450
|
}
|
|
441
451
|
|
|
@@ -450,6 +460,7 @@ class RegistryImpl implements AtomRegistry {
|
|
|
450
460
|
if (idleTTL <= 0) {
|
|
451
461
|
this.nodes.delete(atomKey(node.atom))
|
|
452
462
|
node.remove()
|
|
463
|
+
this.onNodeRemoved?.(node)
|
|
453
464
|
return
|
|
454
465
|
}
|
|
455
466
|
}
|
|
@@ -496,6 +507,7 @@ class RegistryImpl implements AtomRegistry {
|
|
|
496
507
|
}
|
|
497
508
|
this.nodeTimeoutBucket.delete(node)
|
|
498
509
|
this.nodes.delete(atomKey(node.atom))
|
|
510
|
+
this.onNodeRemoved?.(node)
|
|
499
511
|
this.#currentSweepTTL = node.atom.idleTTL ?? this.defaultIdleTTL!
|
|
500
512
|
node.remove()
|
|
501
513
|
this.#currentSweepTTL = null
|
|
@@ -507,7 +519,10 @@ class RegistryImpl implements AtomRegistry {
|
|
|
507
519
|
this.timeoutBuckets.clear()
|
|
508
520
|
this.nodeTimeoutBucket.clear()
|
|
509
521
|
|
|
510
|
-
this.nodes.forEach((node) =>
|
|
522
|
+
this.nodes.forEach((node) => {
|
|
523
|
+
node.remove()
|
|
524
|
+
this.onNodeRemoved?.(node)
|
|
525
|
+
})
|
|
511
526
|
this.nodes.clear()
|
|
512
527
|
}
|
|
513
528
|
|
|
@@ -554,6 +569,19 @@ class NodeImpl<A> {
|
|
|
554
569
|
listeners: Set<() => void> = new Set()
|
|
555
570
|
skipInvalidation = false
|
|
556
571
|
|
|
572
|
+
currentState() {
|
|
573
|
+
switch (this.state) {
|
|
574
|
+
case NodeState.uninitialized:
|
|
575
|
+
return "uninitialized"
|
|
576
|
+
case NodeState.stale:
|
|
577
|
+
return "stale"
|
|
578
|
+
case NodeState.valid:
|
|
579
|
+
return "valid"
|
|
580
|
+
default:
|
|
581
|
+
return "removed"
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
557
585
|
get canBeRemoved(): boolean {
|
|
558
586
|
return !this.atom.keepAlive && this.listeners.size === 0 && this.children.length === 0 && this.state !== 0
|
|
559
587
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
|
+
import * as Cause from "../../Cause.ts"
|
|
5
|
+
import { constUndefined } from "../../Function.ts"
|
|
4
6
|
import * as Predicate from "../../Predicate.ts"
|
|
5
7
|
import * as Schema from "../../Schema.ts"
|
|
6
8
|
import type * as AST from "../../SchemaAST.ts"
|
|
9
|
+
import * as ServiceMap from "../../ServiceMap.ts"
|
|
7
10
|
import * as Stream_ from "../../Stream.ts"
|
|
8
11
|
|
|
9
12
|
const StreamSchemaTypeId = "~effect/rpc/RpcSchema/StreamSchema"
|
|
@@ -58,3 +61,17 @@ const schema = Schema.declare(Stream_.isStream)
|
|
|
58
61
|
export function Stream<A extends Schema.Top, E extends Schema.Top>(success: A, error: E): Stream<A, E> {
|
|
59
62
|
return Schema.make(schema.ast, { [StreamSchemaTypeId]: StreamSchemaTypeId, success, error })
|
|
60
63
|
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @since 4.0.0
|
|
67
|
+
* @category Cause annotations
|
|
68
|
+
*/
|
|
69
|
+
export class ClientAbort extends ServiceMap.Service<ClientAbort, true>()("effect/rpc/RpcSchema/ClientAbort") {
|
|
70
|
+
static annotation = this.serviceMap(true).pipe(
|
|
71
|
+
ServiceMap.add(Cause.StackTrace, {
|
|
72
|
+
name: "ClientAbort",
|
|
73
|
+
stack: constUndefined,
|
|
74
|
+
parent: undefined
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
}
|
|
@@ -107,11 +107,7 @@ export const jsonRpc = (options?: {
|
|
|
107
107
|
return decodeJsonRpcRaw(decoded, batches)
|
|
108
108
|
},
|
|
109
109
|
encode: (response) => {
|
|
110
|
-
|
|
111
|
-
if (response.length === 0) return undefined
|
|
112
|
-
return JSON.stringify(response.map(encodeJsonRpcMessage))
|
|
113
|
-
}
|
|
114
|
-
const encoded = encodeJsonRpcRaw(response as any, batches)
|
|
110
|
+
const encoded = encodeJsonRpcResponse(response as any, batches)
|
|
115
111
|
return encoded && JSON.stringify(encoded)
|
|
116
112
|
}
|
|
117
113
|
}
|
|
@@ -146,10 +142,7 @@ export const ndJsonRpc = (options?: {
|
|
|
146
142
|
return messages
|
|
147
143
|
},
|
|
148
144
|
encode: (response) => {
|
|
149
|
-
|
|
150
|
-
return parser.encode(response.map(encodeJsonRpcMessage))
|
|
151
|
-
}
|
|
152
|
-
const encoded = encodeJsonRpcRaw(response as any, batches)
|
|
145
|
+
const encoded = encodeJsonRpcResponse(response as any, batches)
|
|
153
146
|
return encoded && parser.encode(encoded)
|
|
154
147
|
}
|
|
155
148
|
})
|
|
@@ -171,6 +164,7 @@ function decodeJsonRpcRaw(
|
|
|
171
164
|
const messages: Array<RpcMessage.FromClientEncoded | RpcMessage.FromServerEncoded> = []
|
|
172
165
|
for (let i = 0; i < decoded.length; i++) {
|
|
173
166
|
const message = decodeJsonRpcMessage(decoded[i])
|
|
167
|
+
messages.push(message)
|
|
174
168
|
if (message._tag === "Request") {
|
|
175
169
|
batch.size++
|
|
176
170
|
batches.set(message.id, batch)
|
|
@@ -263,6 +257,47 @@ function encodeJsonRpcRaw(
|
|
|
263
257
|
return encodeJsonRpcMessage(response)
|
|
264
258
|
}
|
|
265
259
|
|
|
260
|
+
function encodeJsonRpcResponse(
|
|
261
|
+
response:
|
|
262
|
+
| RpcMessage.FromServerEncoded
|
|
263
|
+
| RpcMessage.FromClientEncoded
|
|
264
|
+
| Array<RpcMessage.FromServerEncoded | RpcMessage.FromClientEncoded>,
|
|
265
|
+
batches: Map<string, {
|
|
266
|
+
readonly size: number
|
|
267
|
+
readonly responses: Map<string, RpcMessage.FromServerEncoded>
|
|
268
|
+
}>
|
|
269
|
+
) {
|
|
270
|
+
if (Array.isArray(response) === false) {
|
|
271
|
+
return encodeJsonRpcRaw(response, batches)
|
|
272
|
+
}
|
|
273
|
+
if (response.length === 0) {
|
|
274
|
+
return undefined
|
|
275
|
+
}
|
|
276
|
+
const encoded: Array<JsonRpcMessage | Array<JsonRpcMessage>> = []
|
|
277
|
+
for (let i = 0; i < response.length; i++) {
|
|
278
|
+
const current = encodeJsonRpcRaw(response[i], batches)
|
|
279
|
+
if (current !== undefined) {
|
|
280
|
+
encoded.push(current)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (encoded.length === 0) {
|
|
284
|
+
return undefined
|
|
285
|
+
}
|
|
286
|
+
if (encoded.length === 1) {
|
|
287
|
+
return encoded[0]
|
|
288
|
+
}
|
|
289
|
+
const messages: Array<JsonRpcMessage> = []
|
|
290
|
+
for (let i = 0; i < encoded.length; i++) {
|
|
291
|
+
const current = encoded[i]
|
|
292
|
+
if (Array.isArray(current)) {
|
|
293
|
+
messages.push(...current)
|
|
294
|
+
} else {
|
|
295
|
+
messages.push(current)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return messages
|
|
299
|
+
}
|
|
300
|
+
|
|
266
301
|
function encodeJsonRpcMessage(response: RpcMessage.FromServerEncoded | RpcMessage.FromClientEncoded): JsonRpcMessage {
|
|
267
302
|
switch (response._tag) {
|
|
268
303
|
case "Request":
|
|
@@ -8,6 +8,7 @@ import * as Effect from "../../Effect.ts"
|
|
|
8
8
|
import * as Exit from "../../Exit.ts"
|
|
9
9
|
import * as Fiber from "../../Fiber.ts"
|
|
10
10
|
import { constant, constTrue, constVoid, identity } from "../../Function.ts"
|
|
11
|
+
import { reportCauseUnsafe } from "../../internal/effect.ts"
|
|
11
12
|
import * as Latch from "../../Latch.ts"
|
|
12
13
|
import * as Layer from "../../Layer.ts"
|
|
13
14
|
import type * as Option from "../../Option.ts"
|
|
@@ -174,17 +175,16 @@ export const makeNoSerialization: <Rpcs extends Rpc.Any>(
|
|
|
174
175
|
}
|
|
175
176
|
case "Interrupt": {
|
|
176
177
|
const fiber = client.fibers.get(message.requestId)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
})
|
|
178
|
+
if (fiber) {
|
|
179
|
+
fiber.interruptUnsafe(requestFiber.id, RpcSchema.ClientAbort.annotation)
|
|
180
|
+
return Effect.void
|
|
181
|
+
}
|
|
182
|
+
return options.onFromServer({
|
|
183
|
+
_tag: "Exit",
|
|
184
|
+
clientId,
|
|
185
|
+
requestId: message.requestId,
|
|
186
|
+
exit: Exit.interrupt()
|
|
187
|
+
})
|
|
188
188
|
}
|
|
189
189
|
case "Eof": {
|
|
190
190
|
client.ended = true
|
|
@@ -273,6 +273,9 @@ export const makeNoSerialization: <Rpcs extends Rpc.Any>(
|
|
|
273
273
|
requestId: request.id,
|
|
274
274
|
exit
|
|
275
275
|
})
|
|
276
|
+
if (exit._tag === "Failure") {
|
|
277
|
+
reportCauseUnsafe(Fiber.getCurrent()!, exit.cause)
|
|
278
|
+
}
|
|
276
279
|
return close ? Effect.ensuring(write, close) : write
|
|
277
280
|
})
|
|
278
281
|
if (enableTracing) {
|
|
@@ -1278,14 +1281,6 @@ export const layerProtocolWorkerRunner: Layer.Layer<
|
|
|
1278
1281
|
WorkerRunner.WorkerRunnerPlatform
|
|
1279
1282
|
> = Layer.effect(Protocol)(makeProtocolWorkerRunner)
|
|
1280
1283
|
|
|
1281
|
-
/**
|
|
1282
|
-
* Fiber id used to indicate client induced interrupts
|
|
1283
|
-
*
|
|
1284
|
-
* @since 4.0.0
|
|
1285
|
-
* @category Interruption
|
|
1286
|
-
*/
|
|
1287
|
-
export const fiberIdClientInterrupt = -499
|
|
1288
|
-
|
|
1289
1284
|
// internal
|
|
1290
1285
|
|
|
1291
1286
|
const makeSocketProtocol: Effect.Effect<
|
|
@@ -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)
|