@graftland/plugin-remote 0.3.1 → 0.3.3
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/Auth.d.ts +2 -2
- package/dist/Auth.d.ts.map +1 -1
- package/dist/Auth.js.map +1 -1
- package/dist/{Bootstrap-Dr6sX7el.js → Bootstrap-H9gDsgsC.js} +2 -2
- package/dist/{Contract-DL2mHvaT.js → Contract-DsJtisvL.js} +2 -2
- package/dist/Contract.js +1 -1
- package/dist/{Errors-BMKmu5Y7.js → Errors-DYhsGZcZ.js} +3 -1
- package/dist/Errors.d.ts +7 -0
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js +3 -1
- package/dist/Errors.js.map +1 -1
- package/dist/{FailureGroup-BcH0XOBi.js → FailureGroup-BgT73AaR.js} +14 -4
- package/dist/{Framing-zaYdOJnT.js → Framing-G9eSaeLb.js} +1 -1
- package/dist/{Graft-CVyueNOf.js → Graft-B71CPA2Y.js} +20 -16
- package/dist/{Packages-JNL34JpS.js → Packages-AgoCGotL.js} +23 -26
- package/dist/{Peer-BT7eAGmh.js → Peer-DXeVrGBh.js} +5 -5
- package/dist/{ProcessObservation-DEGrEMfP.js → ProcessObservation-gLgGirYv.js} +1 -1
- package/dist/{ServeLifecycle-CJM0gG5B.js → ServeLifecycle-Bd1FPJ6e.js} +1 -1
- package/dist/Transport.d.ts +2 -2
- package/dist/Transport.d.ts.map +1 -1
- package/dist/Transport.js.map +1 -1
- package/dist/bin.js +48 -47
- package/dist/bin.js.map +1 -1
- package/dist/{childRuntime-An0HsIzl.js → childRuntime-Bm3iSg_N.js} +29 -26
- package/dist/{connectionEnded-DCpFCjMX.js → connectionEnded-BwcxQ7W8.js} +4 -4
- package/dist/{entry-B89sepMU.js → entry-psOpX3Bj.js} +72 -35
- package/dist/host/auth/bearer.d.ts +9 -1
- package/dist/host/auth/bearer.d.ts.map +1 -1
- package/dist/host/auth/bearer.js +1 -1
- package/dist/host/auth/jwt.d.ts +9 -1
- package/dist/host/auth/jwt.d.ts.map +1 -1
- package/dist/host/auth/jwt.js +1 -1
- package/dist/host/auth/mtls.d.ts +8 -1
- package/dist/host/auth/mtls.d.ts.map +1 -1
- package/dist/host/auth/mtls.js +2 -2
- package/dist/host/auth/none.d.ts +3 -1
- package/dist/host/auth/none.js +1 -1
- package/dist/host/command.d.ts +14 -1
- package/dist/host/command.d.ts.map +1 -1
- package/dist/host/command.js +4 -4
- package/dist/host/local.d.ts +2 -1
- package/dist/host/local.d.ts.map +1 -1
- package/dist/host/local.js +3 -3
- package/dist/host/unix.d.ts +6 -1
- package/dist/host/unix.d.ts.map +1 -1
- package/dist/host/unix.js +3 -3
- package/dist/host/websocket.d.ts +10 -1
- package/dist/host/websocket.d.ts.map +1 -1
- package/dist/host/websocket.js +3 -3
- package/dist/host/worker.d.ts +3 -1
- package/dist/host/worker.d.ts.map +1 -1
- package/dist/host/worker.js +4 -5
- package/dist/{importer-Bk6U_sn4.js → importer-Cvf88eAY.js} +5 -8
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/internal/Certificates.js +4 -4
- package/dist/internal/Certificates.js.map +1 -1
- package/dist/internal/FailureGroup.js +3 -2
- package/dist/internal/FailureGroup.js.map +1 -1
- package/dist/internal/assembly.d.ts +2 -1
- package/dist/internal/assembly.js +9 -2
- package/dist/internal/assembly.js.map +1 -1
- package/dist/internal/auth/mtls.js +1 -1
- package/dist/internal/auth/mtls.js.map +1 -1
- package/dist/internal/auth/tokenCredentials.d.ts +2 -1
- package/dist/internal/auth/tokenCredentials.d.ts.map +1 -1
- package/dist/internal/child.js +20 -17
- package/dist/internal/child.js.map +1 -1
- package/dist/internal/childRuntime.js +4 -4
- package/dist/internal/childRuntime.js.map +1 -1
- package/dist/internal/credentials.d.ts +1 -1
- package/dist/internal/directTransport.d.ts +1 -1
- package/dist/internal/entry.d.ts +415 -3
- package/dist/internal/entry.d.ts.map +1 -1
- package/dist/internal/entry.js +1 -1
- package/dist/internal/entry.js.map +1 -1
- package/dist/internal/execution.js +40 -5
- package/dist/internal/execution.js.map +1 -1
- package/dist/internal/host/runner.js +7 -6
- package/dist/internal/host/runner.js.map +1 -1
- package/dist/internal/host.js +5 -5
- package/dist/internal/host.js.map +1 -1
- package/dist/internal/port.js +5 -5
- package/dist/internal/port.js.map +1 -1
- package/dist/internal/release.js +1 -1
- package/dist/internal/release.js.map +1 -1
- package/dist/internal/runner/Connection.d.ts +1 -1
- package/dist/internal/runner/Connection.js +4 -4
- package/dist/internal/runner/Connection.js.map +1 -1
- package/dist/internal/runner/Execution.js +3 -3
- package/dist/internal/runner/Execution.js.map +1 -1
- package/dist/internal/runner/Framing.js +1 -1
- package/dist/internal/runner/Framing.js.map +1 -1
- package/dist/internal/runner/Local.js +1 -1
- package/dist/internal/runner/Local.js.map +1 -1
- package/dist/internal/runner/Lock.js +1 -1
- package/dist/internal/runner/Lock.js.map +1 -1
- package/dist/internal/runner/Packages.d.ts +1 -1
- package/dist/internal/runner/Packages.js +22 -25
- package/dist/internal/runner/Packages.js.map +1 -1
- package/dist/internal/runner/Processes.js +7 -9
- package/dist/internal/runner/Processes.js.map +1 -1
- package/dist/internal/runner/Store.js +3 -3
- package/dist/internal/runner/Store.js.map +1 -1
- package/dist/internal/runner/Supervisor.js +46 -47
- package/dist/internal/runner/Supervisor.js.map +1 -1
- package/dist/internal/runner/accept.js +3 -3
- package/dist/internal/runner/accept.js.map +1 -1
- package/dist/internal/runner/model.js +1 -1
- package/dist/internal/runner/model.js.map +1 -1
- package/dist/internal/serve.js +1 -1
- package/dist/internal/serve.js.map +1 -1
- package/dist/internal/supervisorPlugin.js +1 -1
- package/dist/internal/watchdogMain.js +5 -5
- package/dist/internal/watchdogMain.js.map +1 -1
- package/dist/internal/websocketServer.js +3 -1
- package/dist/internal/websocketServer.js.map +1 -1
- package/dist/internal/workerMain.js +3 -3
- package/dist/{port-DSVUY8Bq.js → port--3x2zJ4D.js} +8 -8
- package/dist/{release-BY4Mlluy.js → release-DfZPuIcK.js} +1 -1
- package/dist/runner/auth/bearer.d.ts +6 -1
- package/dist/runner/auth/bearer.d.ts.map +1 -1
- package/dist/runner/auth/bearer.js +2 -2
- package/dist/runner/auth/jwt.d.ts +29 -2
- package/dist/runner/auth/jwt.d.ts.map +1 -1
- package/dist/runner/auth/jwt.js +4 -4
- package/dist/runner/auth/jwt.js.map +1 -1
- package/dist/runner/auth/mtls.d.ts +6 -1
- package/dist/runner/auth/mtls.d.ts.map +1 -1
- package/dist/runner/auth/mtls.js +3 -3
- package/dist/runner/auth/none.d.ts +7 -1
- package/dist/runner/auth/none.js +1 -1
- package/dist/runner/index.d.ts +310 -1
- package/dist/runner/index.d.ts.map +1 -1
- package/dist/runner/index.js +5 -5
- package/dist/runner/stdio.d.ts +6 -1
- package/dist/runner/stdio.d.ts.map +1 -1
- package/dist/runner/stdio.js +3 -3
- package/dist/runner/unix.d.ts +6 -1
- package/dist/runner/unix.d.ts.map +1 -1
- package/dist/runner/unix.js +3 -3
- package/dist/runner/websocket.d.ts +24 -1
- package/dist/runner/websocket.d.ts.map +1 -1
- package/dist/runner/websocket.js +4 -4
- package/dist/{socketChannel-C_ppdSzz.js → socketChannel-CJvL2DiB.js} +2 -2
- package/dist/{supervisorPlugin-CivhM7x5.js → supervisorPlugin-t6Z6PrhD.js} +72 -76
- package/dist/{token-Cc_1CTbE.js → token-CYBNNlhS.js} +1 -1
- package/dist/{tokenCredentials-CI6mMRRd.js → tokenCredentials-CbCuk-Rt.js} +3 -3
- package/dist/{websocketServer-D2Hk7wsA.js → websocketServer-NQhODlEt.js} +5 -3
- package/dist/{workerChannel-cmLc13vm.js → workerChannel-C8hhBJzA.js} +1 -1
- package/package.json +4 -4
- package/src/Auth.ts +9 -2
- package/src/Errors.ts +8 -0
- package/src/Transport.ts +6 -2
- package/src/bin.ts +28 -30
- package/src/index.ts +5 -3
- package/src/internal/Certificates.ts +10 -13
- package/src/internal/FailureGroup.ts +128 -121
- package/src/internal/assembly.ts +19 -10
- package/src/internal/auth/mtls.ts +19 -20
- package/src/internal/child.ts +248 -239
- package/src/internal/childRuntime.ts +81 -80
- package/src/internal/entry.ts +10 -11
- package/src/internal/execution.ts +69 -12
- package/src/internal/host/runner.ts +153 -153
- package/src/internal/host.ts +116 -120
- package/src/internal/port.ts +100 -103
- package/src/internal/release.ts +3 -2
- package/src/internal/runner/Connection.ts +52 -60
- package/src/internal/runner/Execution.ts +163 -164
- package/src/internal/runner/Framing.ts +9 -10
- package/src/internal/runner/Local.ts +26 -27
- package/src/internal/runner/Lock.ts +23 -25
- package/src/internal/runner/Packages.ts +67 -70
- package/src/internal/runner/Processes.ts +89 -92
- package/src/internal/runner/Store.ts +110 -114
- package/src/internal/runner/Supervisor.ts +392 -405
- package/src/internal/runner/accept.ts +76 -84
- package/src/internal/runner/model.ts +20 -21
- package/src/internal/serve.ts +15 -13
- package/src/internal/watchdogMain.ts +16 -11
- package/src/internal/websocketServer.ts +18 -3
- package/src/runner/auth/jwt.ts +10 -6
- package/dist/cleanup-CXLa1Wd9.js +0 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { make } from "../FailureGroup.js";
|
|
2
2
|
import { connectWith } from "../assembly.js";
|
|
3
|
-
import { defaults } from "../Limits.js";
|
|
4
3
|
import { ProcessExited, TransportError } from "../../Errors.js";
|
|
4
|
+
import { defaults } from "../Limits.js";
|
|
5
5
|
import { cleanupCause } from "../cleanup.js";
|
|
6
6
|
import { make as make$1 } from "../port.js";
|
|
7
7
|
import { make as make$2 } from "../runner/Multiplex.js";
|
|
@@ -11,7 +11,7 @@ import { awaitTermination, childOf } from "../runner/model.js";
|
|
|
11
11
|
import { Cause, Duration, Effect, Exit, Fiber, Option, Ref, Scope } from "effect";
|
|
12
12
|
import { RpcClient } from "effect/rpc";
|
|
13
13
|
// src/internal/host/runner.ts
|
|
14
|
-
const connect = (target, contractModule, options, resources, processScope)
|
|
14
|
+
const connect = Effect.fnUntraced(function* (target, contractModule, options, resources, processScope) {
|
|
15
15
|
const instance = target.instance;
|
|
16
16
|
const margin = Duration.toMillis(target.margin ?? "5 seconds");
|
|
17
17
|
const channel$1 = yield* connectWith(target.explicitAuth).pipe(Scope.provide(processScope));
|
|
@@ -34,7 +34,7 @@ const connect = (target, contractModule, options, resources, processScope) => Ef
|
|
|
34
34
|
const finishStarted = yield* Ref.make(false);
|
|
35
35
|
const terminate = yield* Effect.cached(Effect.gen(function* () {
|
|
36
36
|
yield* Ref.set(finishStarted, true);
|
|
37
|
-
yield* failures.close;
|
|
37
|
+
const closed = yield* Effect.exit(failures.close);
|
|
38
38
|
const result = yield* awaitTermination(record.handle, session.Dispose(record.handle), record.leaseMillis, margin);
|
|
39
39
|
const { code, signal, stderr, cause } = result.exit;
|
|
40
40
|
yield* Effect.logInfo("Remote execution terminated", {
|
|
@@ -47,7 +47,8 @@ const connect = (target, contractModule, options, resources, processScope) => Ef
|
|
|
47
47
|
"remote.generation": record.handle.generation,
|
|
48
48
|
"remote.termination": result.kind
|
|
49
49
|
}));
|
|
50
|
-
|
|
50
|
+
const failure = Exit.isFailure(closed) ? Cause.combine(closed.cause, result.cause) : result.cause;
|
|
51
|
+
if (failure.reasons.length > 0) return yield* Effect.failCause(cleanupCause(failure));
|
|
51
52
|
}));
|
|
52
53
|
yield* Scope.addFinalizer(processScope, Effect.gen(function* () {
|
|
53
54
|
if (!(yield* Ref.get(finishStarted))) yield* terminate.pipe(Effect.catchCause((cause) => Effect.failCause(cleanupCause(cause))));
|
|
@@ -67,7 +68,7 @@ const connect = (target, contractModule, options, resources, processScope) => Ef
|
|
|
67
68
|
}).pipe(Scope.provide(resources));
|
|
68
69
|
const report = (cause) => Cause.hasInterruptsOnly(cause) ? Effect.void : failures.failCause(Cause.map(cause, (error) => TransportError.make({ cause: Cause.fail(error) })));
|
|
69
70
|
yield* failures.await.pipe(Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause) ? Effect.void : peer.fail(TransportError.make({ cause }))), Effect.forkIn(resources));
|
|
70
|
-
yield* failures.run(Fiber.join(renewed).pipe(Effect.catchCause(
|
|
71
|
+
yield* failures.run(Fiber.join(renewed).pipe(Effect.catchCause(Effect.fnUntraced(function* (cause) {
|
|
71
72
|
if (Cause.hasInterruptsOnly(cause)) return;
|
|
72
73
|
const status = yield* Effect.exit(session.Status(record.handle).pipe(Effect.timeout("5 seconds")));
|
|
73
74
|
if (Exit.isSuccess(status) && status.value.phase === "Stopped") {
|
|
@@ -84,7 +85,7 @@ const connect = (target, contractModule, options, resources, processScope) => Ef
|
|
|
84
85
|
resources,
|
|
85
86
|
pid: Option.map(childOf(loaded), (child) => child.pid),
|
|
86
87
|
diagnostics: failures.cause,
|
|
87
|
-
terminate:
|
|
88
|
+
terminate: Effect.fnUntraced(function* () {
|
|
88
89
|
yield* Fiber.interrupt(renewed);
|
|
89
90
|
yield* terminate;
|
|
90
91
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","names":["channel","connectCapability","Multiplex.make","Port.make","Wire.channel","Wire.Session","FailureGroup.make","Packages.verify"],"sources":["../../../src/internal/host/runner.ts"],"sourcesContent":["import * as FailureGroup from \"../FailureGroup\"\nimport {\n\tCause,\n\tEffect,\n\tDuration,\n\tExit,\n\tFiber,\n\tOption,\n\tRef,\n\tScope,\n} from \"effect\"\nimport { RpcClient } from \"effect/rpc\"\nimport { connectWith as connectCapability } from \"../assembly\"\nimport type { ConfiguredRunner, Connected } from \"../runner/Connection\"\nimport { ProcessExited, TransportError } from \"../../Errors\"\nimport { cleanupCause } from \"../cleanup\"\nimport * as Port from \"../port\"\nimport * as Multiplex from \"../runner/Multiplex\"\nimport * as Packages from \"../runner/Packages\"\nimport * as Wire from \"../runner/Wire\"\nimport { awaitTermination, defaults, childOf } from \"../runner/model\"\nexport const connect = (\n\ttarget: ConfiguredRunner,\n\tcontractModule: string,\n\toptions: Port.Options,\n\tresources: Scope.Scope,\n\tprocessScope: Scope.Scope,\n)
|
|
1
|
+
{"version":3,"file":"runner.js","names":["channel","connectCapability","Multiplex.make","Port.make","Wire.channel","Wire.Session","FailureGroup.make","Packages.verify"],"sources":["../../../src/internal/host/runner.ts"],"sourcesContent":["import * as FailureGroup from \"../FailureGroup\"\nimport {\n\tCause,\n\tEffect,\n\tDuration,\n\tExit,\n\tFiber,\n\tOption,\n\tRef,\n\tScope,\n} from \"effect\"\nimport { RpcClient } from \"effect/rpc\"\nimport { connectWith as connectCapability } from \"../assembly\"\nimport type { ConfiguredRunner, Connected } from \"../runner/Connection\"\nimport { ProcessExited, TransportError } from \"../../Errors\"\nimport { cleanupCause } from \"../cleanup\"\nimport * as Port from \"../port\"\nimport * as Multiplex from \"../runner/Multiplex\"\nimport * as Packages from \"../runner/Packages\"\nimport * as Wire from \"../runner/Wire\"\nimport { awaitTermination, defaults, childOf } from \"../runner/model\"\nexport const connect = Effect.fnUntraced(function* (\n\ttarget: ConfiguredRunner,\n\tcontractModule: string,\n\toptions: Port.Options,\n\tresources: Scope.Scope,\n\tprocessScope: Scope.Scope,\n) {\n\tconst instance = target.instance\n\n\tconst margin = Duration.toMillis(target.margin ?? \"5 seconds\")\n\tconst channel = yield* connectCapability(target.explicitAuth).pipe(\n\t\tScope.provide(processScope),\n\t)\n\tconst mux = yield* Multiplex.make(channel).pipe(Scope.provide(resources))\n\tconst control = yield* Port.make(Wire.channel(mux, 0), {\n\t\tsession: \"session-v1\",\n\t\tserve: {},\n\t\tcall: { session: Wire.Session },\n\t}).pipe(Scope.provide(resources))\n\tconst session = yield* RpcClient.make(Wire.Session).pipe(\n\t\tEffect.provideService(\n\t\t\tRpcClient.Protocol,\n\t\t\tcontrol.clientProtocol(\"session\"),\n\t\t),\n\t\tScope.provide(resources),\n\t)\n\tconst expectedGeneration = yield* session.HighWater({ instance })\n\tconst record = yield* session.Open({\n\t\tinstance,\n\t\texpectedGeneration,\n\t\trequestId: options.session,\n\t\tlimits: defaults,\n\t\t...(target.lease === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\tleaseMillis: Duration.toMillis(target.lease),\n\t\t\t\t}),\n\t})\n\tconst failures = yield* FailureGroup.make<TransportError>().pipe(\n\t\tScope.provide(resources),\n\t)\n\tconst finishStarted = yield* Ref.make(false)\n\tconst terminate = yield* Effect.cached(\n\t\tEffect.gen(function* () {\n\t\t\tyield* Ref.set(finishStarted, true)\n\t\t\t// A failed close must not skip Dispose; both outcomes are reported together below.\n\t\t\tconst closed = yield* Effect.exit(failures.close)\n\t\t\tconst result = yield* awaitTermination(\n\t\t\t\trecord.handle,\n\t\t\t\tsession.Dispose(record.handle),\n\t\t\t\trecord.leaseMillis,\n\t\t\t\tmargin,\n\t\t\t)\n\t\t\tconst { code, signal, stderr, cause } = result.exit\n\t\t\tyield* Effect.logInfo(\"Remote execution terminated\", {\n\t\t\t\tcode,\n\t\t\t\t...(signal === null ? {} : { signal }),\n\t\t\t\t...(stderr === undefined || stderr === \"\" ? {} : { stderr }),\n\t\t\t\t...(cause === undefined || cause.reasons.length === 0 ? {} : { cause }),\n\t\t\t}).pipe(\n\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\"remote.instance\": record.handle.key.instance,\n\t\t\t\t\t\"remote.generation\": record.handle.generation,\n\t\t\t\t\t\"remote.termination\": result.kind,\n\t\t\t\t}),\n\t\t\t)\n\t\t\tconst failure = Exit.isFailure(closed)\n\t\t\t\t? Cause.combine(closed.cause, result.cause)\n\t\t\t\t: result.cause\n\t\t\tif (failure.reasons.length > 0)\n\t\t\t\treturn yield* Effect.failCause(cleanupCause(failure))\n\t\t}),\n\t)\n\tyield* Scope.addFinalizer(\n\t\tprocessScope,\n\t\tEffect.gen(function* () {\n\t\t\tif (!(yield* Ref.get(finishStarted)))\n\t\t\t\tyield* terminate.pipe(\n\t\t\t\t\tEffect.catchCause((cause) => Effect.failCause(cleanupCause(cause))),\n\t\t\t\t)\n\t\t}),\n\t)\n\tconst renewed = yield* Effect.forever(\n\t\tEffect.sleep(record.leaseMillis / 3).pipe(\n\t\t\tEffect.andThen(session.Renew(record.handle)),\n\t\t),\n\t).pipe(Effect.forkIn(resources))\n\tconst code = yield* session.Load({\n\t\thandle: record.handle,\n\t\tspecifier: contractModule,\n\t\tdigest: target.expect?.digest !== undefined,\n\t})\n\tyield* Packages.verify(code, target.expect)\n\tconst loaded = yield* session.Status(record.handle)\n\tconst peer = yield* Port.make(Wire.channel(mux, 1), {\n\t\t...options,\n\t\tsession: record.handle.token,\n\t\tlimits: record.limits,\n\t}).pipe(Scope.provide(resources))\n\t// RPC forwarding cancellation is expected; resource cleanup is collected by Connection's scopes.\n\tconst report = (cause: Cause.Cause<unknown>) =>\n\t\tCause.hasInterruptsOnly(cause)\n\t\t\t? Effect.void\n\t\t\t: failures.failCause(\n\t\t\t\t\tCause.map(cause, (error) =>\n\t\t\t\t\t\tTransportError.make({ cause: Cause.fail(error) }),\n\t\t\t\t\t),\n\t\t\t\t)\n\tyield* failures.await.pipe(\n\t\tEffect.catchCause((cause) =>\n\t\t\tCause.hasInterruptsOnly(cause)\n\t\t\t\t? Effect.void\n\t\t\t\t: peer.fail(TransportError.make({ cause })),\n\t\t),\n\t\tEffect.forkIn(resources),\n\t)\n\n\tyield* failures.run(\n\t\tFiber.join(renewed).pipe(\n\t\t\tEffect.catchCause(\n\t\t\t\tEffect.fnUntraced(function* (cause) {\n\t\t\t\t\tif (Cause.hasInterruptsOnly(cause)) return\n\t\t\t\t\tconst status = yield* Effect.exit(\n\t\t\t\t\t\tsession.Status(record.handle).pipe(Effect.timeout(\"5 seconds\")),\n\t\t\t\t\t)\n\t\t\t\t\tif (Exit.isSuccess(status) && status.value.phase === \"Stopped\") {\n\t\t\t\t\t\tconst exit = status.value.termination.exit\n\t\t\t\t\t\tyield* report(\n\t\t\t\t\t\t\tCause.combine(\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t\tCause.fail(\n\t\t\t\t\t\t\t\t\tProcessExited.make({\n\t\t\t\t\t\t\t\t\t\tpid: Option.map(childOf(loaded), (child) => child.pid),\n\t\t\t\t\t\t\t\t\t\texitCode: exit.code,\n\t\t\t\t\t\t\t\t\t\tstderr: exit.stderr ?? \"\",\n\t\t\t\t\t\t\t\t\t\tstatusCause: exit.cause ?? Cause.empty,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t} else\n\t\t\t\t\t\tyield* report(\n\t\t\t\t\t\t\tExit.isFailure(status)\n\t\t\t\t\t\t\t\t? Cause.combine(cause, status.cause)\n\t\t\t\t\t\t\t\t: cause,\n\t\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t)\n\treturn {\n\t\tresources,\n\t\tpid: Option.map(childOf(loaded), (child) => child.pid),\n\t\tdiagnostics: failures.cause,\n\t\tterminate: Effect.fnUntraced(function* () {\n\t\t\t// No renewal may extend a disconnected session while termination waits out its lease.\n\t\t\tyield* Fiber.interrupt(renewed)\n\t\t\tyield* terminate\n\t\t}),\n\t\ttransport: {\n\t\t\t...peer,\n\t\t\tfailure: peer.await,\n\t\t\treport,\n\t\t},\n\t} satisfies Connected\n})\n"],"mappings":"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"}
|
package/dist/internal/host.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Array, Cause, Deferred, Effect, Option, Ref, Scope, Stream } from "effe
|
|
|
7
7
|
import { RpcClient } from "effect/rpc";
|
|
8
8
|
// src/internal/host.ts
|
|
9
9
|
const race = (connection, effect) => Effect.raceFirst(effect, connection.transport.failure);
|
|
10
|
-
const forwardEvents = (contract, client, connection)
|
|
10
|
+
const forwardEvents = Effect.fnUntraced(function* (contract, client, connection) {
|
|
11
11
|
const stopped = yield* Deferred.make();
|
|
12
12
|
const remoteFailure = yield* make();
|
|
13
13
|
return {
|
|
@@ -22,10 +22,10 @@ const forwardEvents = (contract, client, connection) => Effect.gen(function* ()
|
|
|
22
22
|
}))).pipe(Effect.tapCause(connection.transport.report), Effect.forkIn(connection.resources))
|
|
23
23
|
};
|
|
24
24
|
});
|
|
25
|
-
const forwardLogs = (contract, client, connection)
|
|
25
|
+
const forwardLogs = Effect.fnUntraced(function* (contract, client, connection) {
|
|
26
26
|
const logsEnded = yield* Deferred.make();
|
|
27
27
|
const reportedDrops = yield* Ref.make(0);
|
|
28
|
-
yield* race(connection, client.Logs().pipe(Stream.runForEach(
|
|
28
|
+
yield* race(connection, client.Logs().pipe(Stream.runForEach(Effect.fnUntraced(function* (event) {
|
|
29
29
|
const previous = yield* Ref.getAndSet(reportedDrops, event.dropped);
|
|
30
30
|
if (event.dropped > previous) yield* Effect.logWarning("Remote logs were dropped").pipe(Effect.annotateLogs({
|
|
31
31
|
...Option.isSome(connection.pid) ? { "remote.pid": connection.pid.value } : {},
|
|
@@ -46,7 +46,7 @@ const forwardLogs = (contract, client, connection) => Effect.gen(function* () {
|
|
|
46
46
|
})))).pipe(Effect.tapCause(connection.transport.report), Effect.forkIn(connection.resources));
|
|
47
47
|
return logsEnded;
|
|
48
48
|
});
|
|
49
|
-
const initialize =
|
|
49
|
+
const initialize = Effect.fnUntraced(function* (contract) {
|
|
50
50
|
const connection = yield* Connection;
|
|
51
51
|
const client = yield* RpcClient.make(contract.control).pipe(Effect.provideService(RpcClient.Protocol, connection.transport.clientProtocol(endpoint)), Scope.provide(connection.resources));
|
|
52
52
|
for (const service of contract.inject) yield* service.serve(connection.transport).pipe(Effect.tapCause(connection.transport.report), Effect.forkIn(connection.resources));
|
|
@@ -60,7 +60,7 @@ const initialize = (contract) => Effect.gen(function* () {
|
|
|
60
60
|
};
|
|
61
61
|
});
|
|
62
62
|
const load = (active, input) => race(active.connection, Effect.raceFirst(active.client.Load({ input }).pipe(Effect.catchIf((cause) => Cause.isCause(cause), Effect.failCause)), active.remoteFailure.await));
|
|
63
|
-
const dispose =
|
|
63
|
+
const dispose = Effect.fnUntraced(function* (active) {
|
|
64
64
|
const result = yield* race(active.connection, active.client.Dispose().pipe(Effect.catchIf(Cause.isCause, Effect.succeed)));
|
|
65
65
|
const cause = Cause.isCause(result) ? result : Cause.empty;
|
|
66
66
|
yield* race(active.connection, Deferred.await(active.stopped).pipe(Effect.andThen(Deferred.await(active.logsEnded)))).pipe(Effect.onError(() => Effect.failCause(cleanupCause(cause))));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","names":["FailureGroup.make","Control.endpoint"],"sources":["../../src/internal/host.ts"],"sourcesContent":["import * as FailureGroup from \"./FailureGroup\"\nimport * as ContractModule from \"../Contract\"\nimport {\n\tCause,\n\tArray,\n\tDeferred,\n\tEffect,\n\tRef,\n\tOption,\n\tSchema,\n\tScope,\n\tStream,\n} from \"effect\"\nimport { RpcClient, type RpcClientError } from \"effect/rpc\"\nimport { RemoteWithdrawn } from \"../Errors\"\nimport * as Control from \"./control\"\nimport { cleanupCause } from \"./cleanup\"\nimport { Connection } from \"./runner/Connection\"\nimport type { Service } from \"../Contract\"\nimport type { ChildFailure } from \"./childErrors\"\nimport type { prepare } from \"./contract\"\n\ntype ErrorSchema = Schema.Top & {\n\treadonly DecodingServices: never\n\treadonly EncodingServices: never\n}\ntype ControlGroup<E extends ErrorSchema> = ReturnType<\n\ttypeof prepare<Schema.Codec<unknown, Schema.Json>, E>\n>[\"control\"]\ninterface Contract<E extends ErrorSchema> {\n\treadonly control: ControlGroup<E>\n\treadonly inject: ReadonlyArray<Service>\n\treadonly decodeCause: (\n\t\tinput: unknown,\n\t) => Effect.Effect<\n\t\tCause.Cause<E[\"Type\"] | ContractModule.UndeclaredFailure | ChildFailure>,\n\t\tSchema.SchemaError\n\t>\n}\ntype Client<E extends ErrorSchema> = RpcClient.FromGroup<\n\tControlGroup<E>,\n\tRpcClientError.RpcClientError\n>\nconst race = <A, E, R>(\n\tconnection: Connection[\"Service\"],\n\teffect: Effect.Effect<A, E, R>,\n) => Effect.raceFirst(effect, connection.transport.failure)\n\nconst forwardEvents = <E extends ErrorSchema>(\n\tcontract: Contract<E>,\n\tclient: Client<E>,\n\tconnection: Connection[\"Service\"],\n)
|
|
1
|
+
{"version":3,"file":"host.js","names":["FailureGroup.make","Control.endpoint"],"sources":["../../src/internal/host.ts"],"sourcesContent":["import * as FailureGroup from \"./FailureGroup\"\nimport * as ContractModule from \"../Contract\"\nimport {\n\tCause,\n\tArray,\n\tDeferred,\n\tEffect,\n\tRef,\n\tOption,\n\tSchema,\n\tScope,\n\tStream,\n} from \"effect\"\nimport { RpcClient, type RpcClientError } from \"effect/rpc\"\nimport { RemoteWithdrawn } from \"../Errors\"\nimport * as Control from \"./control\"\nimport { cleanupCause } from \"./cleanup\"\nimport { Connection } from \"./runner/Connection\"\nimport type { Service } from \"../Contract\"\nimport type { ChildFailure } from \"./childErrors\"\nimport type { prepare } from \"./contract\"\n\ntype ErrorSchema = Schema.Top & {\n\treadonly DecodingServices: never\n\treadonly EncodingServices: never\n}\ntype ControlGroup<E extends ErrorSchema> = ReturnType<\n\ttypeof prepare<Schema.Codec<unknown, Schema.Json>, E>\n>[\"control\"]\ninterface Contract<E extends ErrorSchema> {\n\treadonly control: ControlGroup<E>\n\treadonly inject: ReadonlyArray<Service>\n\treadonly decodeCause: (\n\t\tinput: unknown,\n\t) => Effect.Effect<\n\t\tCause.Cause<E[\"Type\"] | ContractModule.UndeclaredFailure | ChildFailure>,\n\t\tSchema.SchemaError\n\t>\n}\ntype Client<E extends ErrorSchema> = RpcClient.FromGroup<\n\tControlGroup<E>,\n\tRpcClientError.RpcClientError\n>\nconst race = <A, E, R>(\n\tconnection: Connection[\"Service\"],\n\teffect: Effect.Effect<A, E, R>,\n) => Effect.raceFirst(effect, connection.transport.failure)\n\nconst forwardEvents = Effect.fnUntraced(function* <E extends ErrorSchema>(\n\tcontract: Contract<E>,\n\tclient: Client<E>,\n\tconnection: Connection[\"Service\"],\n) {\n\tconst stopped = yield* Deferred.make<void>()\n\tconst remoteFailure = yield* FailureGroup.make<\n\t\t| E[\"Type\"]\n\t\t| ContractModule.UndeclaredFailure\n\t\t| ChildFailure\n\t\t| RemoteWithdrawn\n\t>()\n\tconst events = yield* race(\n\t\tconnection,\n\t\tclient.Events().pipe(\n\t\t\tStream.runForEach((event) => {\n\t\t\t\tswitch (event._tag) {\n\t\t\t\t\tcase \"Stopped\":\n\t\t\t\t\t\treturn Deferred.succeed(stopped, undefined)\n\t\t\t\t\tcase \"Withdrawing\":\n\t\t\t\t\t\treturn remoteFailure.fail(RemoteWithdrawn.make({}))\n\t\t\t\t\tcase \"Failed\":\n\t\t\t\t\t\treturn contract\n\t\t\t\t\t\t\t.decodeCause(event.cause)\n\t\t\t\t\t\t\t.pipe(Effect.flatMap((cause) => remoteFailure.failCause(cause)))\n\t\t\t\t}\n\t\t\t}),\n\t\t),\n\t).pipe(\n\t\tEffect.tapCause(connection.transport.report),\n\t\tEffect.forkIn(connection.resources),\n\t)\n\treturn { stopped, remoteFailure, events }\n})\nconst forwardLogs = Effect.fnUntraced(function* <E extends ErrorSchema>(\n\tcontract: Contract<E>,\n\tclient: Client<E>,\n\tconnection: Connection[\"Service\"],\n) {\n\tconst logsEnded = yield* Deferred.make<void>()\n\tconst reportedDrops = yield* Ref.make(0)\n\tyield* race(\n\t\tconnection,\n\t\tclient.Logs().pipe(\n\t\t\tStream.runForEach(\n\t\t\t\tEffect.fnUntraced(function* (event) {\n\t\t\t\t\tconst previous = yield* Ref.getAndSet(reportedDrops, event.dropped)\n\t\t\t\t\tif (event.dropped > previous)\n\t\t\t\t\t\tyield* Effect.logWarning(\"Remote logs were dropped\").pipe(\n\t\t\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t\t\t...(Option.isSome(connection.pid)\n\t\t\t\t\t\t\t\t\t? { \"remote.pid\": connection.pid.value }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t\"remote.logs.dropped\": event.dropped - previous,\n\t\t\t\t\t\t\t\t\"remote.logs.droppedTotal\": event.dropped,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\tif (event._tag === \"LogsEnded\") {\n\t\t\t\t\t\tyield* Deferred.succeed(logsEnded, undefined)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tconst entry = event.entry\n\t\t\t\t\tconst cause = yield* contract.decodeCause(entry.cause)\n\t\t\t\t\tyield* Effect.logWithLevel(\n\t\t\t\t\t\tentry.level === \"All\" || entry.level === \"None\"\n\t\t\t\t\t\t\t? \"Info\"\n\t\t\t\t\t\t\t: entry.level,\n\t\t\t\t\t)(\n\t\t\t\t\t\t...(Array.isArray(entry.message) ? entry.message : [entry.message]),\n\t\t\t\t\t\tcause,\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t\t...(Option.isSome(connection.pid)\n\t\t\t\t\t\t\t\t? { \"remote.pid\": connection.pid.value }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(connection.threadId === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { \"remote.threadId\": connection.threadId }),\n\t\t\t\t\t\t\t\"remote.annotations\": entry.annotations,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t).pipe(\n\t\tEffect.tapCause(connection.transport.report),\n\t\tEffect.forkIn(connection.resources),\n\t)\n\treturn logsEnded\n})\nexport const initialize = Effect.fnUntraced(function* <E extends ErrorSchema>(\n\tcontract: Contract<E>,\n) {\n\tconst connection = yield* Connection\n\tconst client = yield* RpcClient.make(contract.control).pipe(\n\t\tEffect.provideService(\n\t\t\tRpcClient.Protocol,\n\t\t\tconnection.transport.clientProtocol(Control.endpoint),\n\t\t),\n\t\tScope.provide(connection.resources),\n\t)\n\tfor (const service of contract.inject)\n\t\tyield* service\n\t\t\t.serve(connection.transport)\n\t\t\t.pipe(\n\t\t\t\tEffect.tapCause(connection.transport.report),\n\t\t\t\tEffect.forkIn(connection.resources),\n\t\t\t)\n\tconst events = yield* forwardEvents(contract, client, connection)\n\tconst logsEnded = yield* forwardLogs(contract, client, connection)\n\treturn { connection, client, ...events, logsEnded }\n})\ntype Active<E extends ErrorSchema> = Effect.Success<\n\tReturnType<typeof initialize<E>>\n>\nexport const load = <E extends ErrorSchema>(\n\tactive: Active<E>,\n\tinput: Schema.Json,\n) =>\n\trace(\n\t\tactive.connection,\n\t\tEffect.raceFirst(\n\t\t\tactive.client\n\t\t\t\t.Load({ input })\n\t\t\t\t.pipe(\n\t\t\t\t\tEffect.catchIf(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t): cause is Cause.Cause<\n\t\t\t\t\t\t\tE[\"Type\"] | ContractModule.UndeclaredFailure | ChildFailure\n\t\t\t\t\t\t> => Cause.isCause(cause),\n\t\t\t\t\t\tEffect.failCause,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\tactive.remoteFailure.await,\n\t\t),\n\t)\nexport const dispose = Effect.fnUntraced(function* <E extends ErrorSchema>(\n\tactive: Active<E>,\n) {\n\tconst result = yield* race(\n\t\tactive.connection,\n\t\tactive.client.Dispose().pipe(Effect.catchIf(Cause.isCause, Effect.succeed)),\n\t)\n\tconst cause = Cause.isCause(result) ? result : Cause.empty\n\t// A remote cleanup failure still permits the bounded event and log tail to drain.\n\tyield* race(\n\t\tactive.connection,\n\t\tDeferred.await(active.stopped).pipe(\n\t\t\tEffect.andThen(Deferred.await(active.logsEnded)),\n\t\t),\n\t).pipe(Effect.onError(() => Effect.failCause(cleanupCause(cause))))\n\treturn cause\n})\n"],"mappings":"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"}
|
package/dist/internal/port.js
CHANGED
|
@@ -52,7 +52,7 @@ const mailbox = (priority) => Queue.dropping(2).pipe(Effect.map((queue) => ({
|
|
|
52
52
|
const deliver = Effect.fnUntraced(function* (requestState, message) {
|
|
53
53
|
if (!(yield* Queue.offer(requestState.queue, message))) return yield* error("RPC request mailbox overflow");
|
|
54
54
|
});
|
|
55
|
-
const initialize =
|
|
55
|
+
const initialize = Effect.fnUntraced(function* (bytes, options) {
|
|
56
56
|
return {
|
|
57
57
|
bytes,
|
|
58
58
|
options,
|
|
@@ -192,7 +192,7 @@ const serverProtocol = (state, endpoint) => {
|
|
|
192
192
|
})).pipe(Effect.catchTag("TransportError", () => Effect.void))
|
|
193
193
|
});
|
|
194
194
|
};
|
|
195
|
-
const next =
|
|
195
|
+
const next = Effect.fnUntraced(function* (state) {
|
|
196
196
|
yield* state.workers.check;
|
|
197
197
|
for (const p of [
|
|
198
198
|
"control",
|
|
@@ -215,7 +215,7 @@ const next = (state) => Effect.tx(Effect.gen(function* () {
|
|
|
215
215
|
}
|
|
216
216
|
if ((yield* TxQueue.isDone(state.queues.control)) && (yield* TxQueue.isDone(state.queues.data)) && (yield* TxQueue.isDone(state.queues.log))) return yield* Cause.done();
|
|
217
217
|
return yield* Effect.txRetry;
|
|
218
|
-
})
|
|
218
|
+
}, Effect.tx);
|
|
219
219
|
const writer = (state) => Stream.fromEffectRepeat(next(state)).pipe(Stream.filterMap(Result.fromOption(() => void 0)), Stream.mapEffect((frame) => Schema.encodeEffect(Schema.fromJsonString(Frame))(frame).pipe(Effect.mapError((cause) => TransportError.make({ cause: Cause.fail(cause) })))), Stream.map((json) => new TextEncoder().encode(json + "\n")), Stream.run(state.bytes.output));
|
|
220
220
|
const read = Effect.fnUntraced(function* (state, raw) {
|
|
221
221
|
const current = yield* Schema.decodeUnknownEffect(Frame)(raw).pipe(Effect.mapError((cause) => TransportError.make({ cause: Cause.fail(cause) })));
|
|
@@ -256,10 +256,10 @@ const reader = (state) => state.bytes.input.pipe(Stream.decodeText(), Stream.spl
|
|
|
256
256
|
/** One RPC client/server per declared endpoint; servers may start after the port. */
|
|
257
257
|
const make = Effect.fnUntraced(function* (bytes, options) {
|
|
258
258
|
const state = yield* initialize(bytes, options);
|
|
259
|
-
yield* state.workers.await.pipe(Effect.catchCause(
|
|
259
|
+
yield* state.workers.await.pipe(Effect.catchCause(Effect.fnUntraced(function* () {
|
|
260
260
|
for (const server of HashMap.values(state.servers)) yield* Queue.offer(server.disconnects, 0);
|
|
261
261
|
yield* Effect.tx(TxRef.set(state.incoming, HashMap.empty()).pipe(Effect.andThen(TxRef.set(state.outgoing, HashMap.empty()))));
|
|
262
|
-
}))
|
|
262
|
+
}, Effect.uninterruptible)), Effect.forkScoped);
|
|
263
263
|
const writing = yield* state.workers.run(writer(state));
|
|
264
264
|
yield* state.workers.run(reader(state));
|
|
265
265
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.js","names":["FailureGroup.make"],"sources":["../../src/internal/port.ts"],"sourcesContent":["import { EndOfStream } from \"./runner/Framing\"\nexport type { Channel } from \"../Transport\"\nimport type { Channel } from \"../Transport\"\nimport {\n\tArray,\n\tCause,\n\tContext,\n\tData,\n\tDeferred,\n\tEffect,\n\tFiber,\n\tHashMap,\n\tOption,\n\tQueue,\n\tRecord,\n\tResult,\n\tSchema,\n\ttype Scope,\n\tStream,\n\tTxQueue,\n\tTxRef,\n} from \"effect\"\nimport {\n\tRpcClient,\n\tRpcClientError,\n\tRpcSerialization,\n\tRpcServer,\n} from \"effect/rpc\"\nimport type { Rpc, RpcGroup, RpcMessage } from \"effect/rpc\"\nimport * as FailureGroup from \"./FailureGroup\"\nimport { TransportError } from \"../Errors\"\nimport { defaults, type Limits } from \"./Limits\"\nexport type Priority = keyof Limits\n\nexport const Priority = Context.Reference<Priority>(\n\t\"@graftland/plugin-remote/internal/port/Priority\",\n\t{ defaultValue: () => \"data\" },\n)\ntype Endpoint = Pick<RpcGroup.RpcGroup<Rpc.Any>, \"requests\">\n\nexport interface Options {\n\treadonly session: string\n\treadonly serve: Readonly<Record<string, Endpoint>>\n\treadonly call: Readonly<Record<string, Endpoint>>\n\t/** Limits are shared across endpoints, separately for each direction.\n\t * Each peer's inbound limits must accommodate the other's outbound limits. */\n\treadonly limits?: Partial<Record<Priority, number>>\n}\nexport interface Port {\n\treadonly clientProtocol: (endpoint: string) => RpcClient.Protocol[\"Service\"]\n\treadonly serverProtocol: (endpoint: string) => RpcServer.Protocol[\"Service\"]\n\treadonly await: Effect.Effect<never, TransportError>\n\treadonly fail: (error: TransportError) => Effect.Effect<void>\n\treadonly end: Effect.Effect<void, TransportError>\n}\nclass RequestKey extends Data.Class<{\n\treadonly endpoint: string\n\treadonly id: string | number\n}> {}\ninterface RequestState<A> {\n\treadonly queue: Queue.Queue<A, Cause.Done>\n\treadonly priority: Priority\n\treadonly sent: boolean\n}\nconst Frame = Schema.Struct({\n\tsession: Schema.String,\n\tendpoint: Schema.String,\n\tdirection: Schema.Literals([\"request\", \"response\"]),\n\tpriority: Schema.Literals([\"control\", \"data\", \"log\"]),\n\tmessage: Schema.Unknown,\n})\ntype Frame = typeof Frame.Type\ninterface Pending {\n\treadonly frame: Frame\n\treadonly request: Option.Option<RequestKey>\n}\nconst Id = Schema.Union([Schema.String, Schema.Finite])\n// Only routing fields belong to this transport. The RPC serialization codec\n// validates payloads, chunks and exits before handlers or callers see them. These\n// protocol callbacks are an opaque handoff, not validation of a complete RpcMessage.\n// EncodedSchema requires binary payloads\n// in Effect 4.1.2 and cannot describe these JSON codec messages.\nconst isRequest = Schema.is(\n\tSchema.Union([\n\t\tSchema.TaggedStruct(\"Request\", { id: Id, tag: Schema.String }),\n\t\tSchema.TaggedStruct(\"Ack\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Interrupt\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Eof\", {}),\n\t]),\n)\nconst isResponse = Schema.is(\n\tSchema.Union([\n\t\tSchema.TaggedStruct(\"Exit\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Chunk\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Defect\", { defect: Schema.Unknown }),\n\t]),\n)\nconst Request = Schema.declare<\n\tExclude<RpcMessage.FromClientEncoded, RpcMessage.Ping>\n>((input): input is Exclude<RpcMessage.FromClientEncoded, RpcMessage.Ping> =>\n\tisRequest(input),\n)\nconst Response = Schema.declare<\n\tExclude<\n\t\tRpcMessage.FromServerEncoded,\n\t\tRpcMessage.Pong | RpcMessage.ClientProtocolError | RpcMessage.RequestEncoded\n\t>\n>(\n\t(\n\t\tinput,\n\t): input is Exclude<\n\t\tRpcMessage.FromServerEncoded,\n\t\tRpcMessage.Pong | RpcMessage.ClientProtocolError | RpcMessage.RequestEncoded\n\t> => isResponse(input),\n)\nconst error = (message: string) =>\n\tTransportError.make({ cause: Cause.die(new Error(message)) })\nconst rpcError = (cause: Cause.Cause<TransportError>) =>\n\tRpcClientError.RpcClientError.make({\n\t\treason: RpcClientError.RpcClientDefect.make({\n\t\t\tmessage: \"Remote connection failed\",\n\t\t\tcause,\n\t\t}),\n\t})\nconst priority = (group: Endpoint, tag: string): Priority => {\n\tconst rpc = group.requests.get(tag)\n\treturn rpc === undefined ? \"data\" : Context.get(rpc.annotations, Priority)\n}\nconst mailbox = <A>(priority: Priority) =>\n\tQueue.dropping<A, Cause.Done>(2).pipe(\n\t\tEffect.map((queue): RequestState<A> => ({ queue, priority, sent: false })),\n\t)\nconst deliver = Effect.fnUntraced(function* <A>(\n\trequestState: RequestState<A>,\n\tmessage: A,\n) {\n\t// One unacknowledged chunk and its terminal Exit may coexist.\n\tif (!(yield* Queue.offer(requestState.queue, message)))\n\t\treturn yield* error(\"RPC request mailbox overflow\")\n})\n\ntype ServerEndpoint = {\n\treadonly group: Endpoint\n\treadonly ready: Deferred.Deferred<\n\t\tParameters<RpcServer.Protocol[\"Service\"][\"run\"]>[0]\n\t>\n\treadonly disconnects: Queue.Queue<number>\n}\ntype ClientEndpoint = {\n\treadonly group: Endpoint\n\treadonly ready: Deferred.Deferred<\n\t\tParameters<RpcClient.Protocol[\"Service\"][\"run\"]>[1]\n\t>\n}\ninterface State {\n\treadonly bytes: Channel\n\treadonly options: Options\n\treadonly limits: Record<Priority, number>\n\treadonly workers: FailureGroup.FailureGroup<TransportError>\n\treadonly incoming: TxRef.TxRef<\n\t\tHashMap.HashMap<RequestKey, RequestState<RpcMessage.FromClientEncoded>>\n\t>\n\treadonly outgoing: TxRef.TxRef<\n\t\tHashMap.HashMap<RequestKey, RequestState<RpcMessage.FromServerEncoded>>\n\t>\n\treadonly queues: Record<Priority, TxQueue.TxQueue<Pending, Cause.Done>>\n\treadonly servers: HashMap.HashMap<string, ServerEndpoint>\n\treadonly clients: HashMap.HashMap<string, ClientEndpoint>\n}\nconst initialize = (bytes: Channel, options: Options) =>\n\tEffect.gen(function* (): Effect.gen.Return<State, never, Scope.Scope> {\n\t\tconst limits = { ...defaults, ...options.limits }\n\t\tconst workers = yield* FailureGroup.make<TransportError>()\n\t\tconst incoming = yield* TxRef.make(\n\t\t\tHashMap.empty<RequestKey, RequestState<RpcMessage.FromClientEncoded>>(),\n\t\t)\n\t\tconst outgoing = yield* TxRef.make(\n\t\t\tHashMap.empty<RequestKey, RequestState<RpcMessage.FromServerEncoded>>(),\n\t\t)\n\t\tconst queues = {\n\t\t\tcontrol: yield* TxQueue.unbounded<Pending, Cause.Done>(),\n\t\t\tdata: yield* TxQueue.unbounded<Pending, Cause.Done>(),\n\t\t\tlog: yield* TxQueue.unbounded<Pending, Cause.Done>(),\n\t\t}\n\t\tconst servers = yield* Effect.forEach(\n\t\t\tRecord.toEntries(options.serve),\n\t\t\tEffect.fnUntraced(function* ([name, group]) {\n\t\t\t\treturn [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tgroup,\n\t\t\t\t\t\tready:\n\t\t\t\t\t\t\tyield* Deferred.make<\n\t\t\t\t\t\t\t\tParameters<RpcServer.Protocol[\"Service\"][\"run\"]>[0]\n\t\t\t\t\t\t\t>(),\n\t\t\t\t\t\tdisconnects: yield* Queue.dropping<number>(1),\n\t\t\t\t\t},\n\t\t\t\t] satisfies readonly [string, unknown]\n\t\t\t}),\n\t\t).pipe(Effect.map(HashMap.fromIterable))\n\t\tconst clients = yield* Effect.forEach(\n\t\t\tRecord.toEntries(options.call),\n\t\t\tEffect.fnUntraced(function* ([name, group]) {\n\t\t\t\treturn [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tgroup,\n\t\t\t\t\t\tready:\n\t\t\t\t\t\t\tyield* Deferred.make<\n\t\t\t\t\t\t\t\tParameters<RpcClient.Protocol[\"Service\"][\"run\"]>[1]\n\t\t\t\t\t\t\t>(),\n\t\t\t\t\t},\n\t\t\t\t] satisfies readonly [string, unknown]\n\t\t\t}),\n\t\t).pipe(Effect.map(HashMap.fromIterable))\n\t\treturn {\n\t\t\tbytes,\n\t\t\toptions,\n\t\t\tlimits,\n\t\t\tworkers,\n\t\t\tincoming,\n\t\t\toutgoing,\n\t\t\tqueues,\n\t\t\tservers,\n\t\t\tclients,\n\t\t}\n\t})\n\nconst admit = Effect.fnUntraced(function* <A>(\n\tstate: State,\n\ttable: TxRef.TxRef<HashMap.HashMap<RequestKey, RequestState<A>>>,\n\tkey: RequestKey,\n\trequestState: RequestState<A>,\n\tdirection: \"incoming\" | \"outgoing\",\n) {\n\tyield* Effect.tx(\n\t\tEffect.gen(function* () {\n\t\t\tyield* state.workers.check\n\t\t\tconst current = yield* TxRef.get(table)\n\t\t\tconst count = Array.filter(\n\t\t\t\tArray.fromIterable(HashMap.values(current)),\n\t\t\t\t(entry) => entry.priority === requestState.priority,\n\t\t\t).length\n\t\t\tif (count >= state.limits[requestState.priority]) {\n\t\t\t\tif (direction === \"outgoing\") return yield* Effect.txRetry\n\t\t\t\treturn yield* error(\n\t\t\t\t\t`RPC admission limit exceeded for ${requestState.priority}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tyield* TxRef.set(table, HashMap.set(current, key, requestState))\n\t\t}),\n\t)\n})\nconst remove = Effect.fnUntraced(function* <A>(\n\ttable: TxRef.TxRef<HashMap.HashMap<RequestKey, RequestState<A>>>,\n\tkey: RequestKey,\n\trequestState: RequestState<A>,\n) {\n\tyield* TxRef.update(table, HashMap.remove(key))\n\tyield* Queue.end(requestState.queue)\n})\nconst enqueue = (\n\tstate: State,\n\tframe: Frame,\n\trequest: Option.Option<RequestKey> = Option.none(),\n) =>\n\tEffect.tx(\n\t\tstate.workers.check.pipe(\n\t\t\tEffect.andThen(\n\t\t\t\tTxQueue.offer(state.queues[frame.priority], { frame, request }).pipe(\n\t\t\t\t\tEffect.flatMap((accepted) =>\n\t\t\t\t\t\taccepted ? Effect.void : error(\"Remote output has ended\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t\tEffect.asVoid,\n\t\t),\n\t)\nconst frame = (\n\tstate: State,\n\tendpoint: string,\n\tdirection: Frame[\"direction\"],\n\tp: Priority,\n\tmessage: unknown,\n): Frame => ({\n\tsession: state.options.session,\n\tendpoint,\n\tdirection,\n\tpriority: p,\n\tmessage,\n})\n// Protocol sends are owned too: interrupting a caller cancels admission or enqueue.\nconst send = Effect.fnUntraced(function* (\n\tstate: State,\n\teffect: Effect.Effect<void, TransportError>,\n) {\n\tconst fiber = yield* state.workers.run(\n\t\tstate.workers.check.pipe(Effect.andThen(effect)),\n\t)\n\tconst result = yield* Fiber.await(fiber).pipe(\n\t\tEffect.onInterrupt(() => Fiber.interrupt(fiber)),\n\t)\n\t// Group teardown interrupts this worker; callers still receive the connection cause.\n\tyield* state.workers.check\n\tyield* result\n})\nconst cancel = Effect.fnUntraced(function* (state: State, key: RequestKey) {\n\tconst canceled = yield* Effect.tx(\n\t\tEffect.gen(function* () {\n\t\t\tconst table = yield* TxRef.get(state.outgoing)\n\t\t\tconst requestState = HashMap.get(table, key)\n\t\t\tif (Option.isNone(requestState))\n\t\t\t\treturn Option.none<RequestState<RpcMessage.FromServerEncoded>>()\n\t\t\tif (requestState.value.sent) {\n\t\t\t\tyield* enqueue(\n\t\t\t\t\tstate,\n\t\t\t\t\tframe(state, key.endpoint, \"request\", \"control\", {\n\t\t\t\t\t\t_tag: \"Interrupt\",\n\t\t\t\t\t\trequestId: key.id,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\treturn Option.none<RequestState<RpcMessage.FromServerEncoded>>()\n\t\t\t}\n\t\t\tyield* TxRef.set(state.outgoing, HashMap.remove(table, key))\n\t\t\treturn requestState\n\t\t}),\n\t)\n\tif (Option.isSome(canceled)) yield* Queue.end(canceled.value.queue)\n})\nconst clientProtocol = (\n\tstate: State,\n\tendpoint: string,\n): RpcClient.Protocol[\"Service\"] => {\n\t// Accessors accept endpoints declared when the port was created.\n\tconst client = Option.getOrThrow(HashMap.get(state.clients, endpoint))\n\treturn RpcClient.Protocol.of({\n\t\tcodecFor: RpcSerialization.json.codecFor,\n\t\tsupportsAck: true,\n\t\tsupportsTransferables: false,\n\t\trun: (_id, receive) =>\n\t\t\tDeferred.succeed(client.ready, receive).pipe(\n\t\t\t\tEffect.andThen(state.workers.await),\n\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\treceive({ _tag: \"ClientProtocolError\", error: rpcError(cause) }),\n\t\t\t\t),\n\t\t\t\tEffect.andThen(Effect.never),\n\t\t\t),\n\t\tsend: (_id, message) =>\n\t\t\tsend(\n\t\t\t\tstate,\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tif (message._tag === \"Request\") {\n\t\t\t\t\t\tif (message.discard === true || message.isNotification === true)\n\t\t\t\t\t\t\treturn yield* error(\n\t\t\t\t\t\t\t\t\"Discard and notification requests are not supported\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\tconst key = new RequestKey({ endpoint, id: message.id })\n\t\t\t\t\t\tconst requestState = yield* mailbox<RpcMessage.FromServerEncoded>(\n\t\t\t\t\t\t\tpriority(client.group, message.tag),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tyield* admit(state, state.outgoing, key, requestState, \"outgoing\")\n\t\t\t\t\t\tyield* state.workers.run(\n\t\t\t\t\t\t\tStream.fromQueue(requestState.queue).pipe(\n\t\t\t\t\t\t\t\tStream.runForEach(\n\t\t\t\t\t\t\t\t\tEffect.fnUntraced(function* (response) {\n\t\t\t\t\t\t\t\t\t\tconst receive = yield* Deferred.await(client.ready)\n\t\t\t\t\t\t\t\t\t\tif (response._tag === \"Exit\")\n\t\t\t\t\t\t\t\t\t\t\tyield* remove(state.outgoing, key, requestState)\n\t\t\t\t\t\t\t\t\t\tyield* receive(response)\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(state, endpoint, \"request\", requestState.priority, message),\n\t\t\t\t\t\t\tOption.some(key),\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (message._tag === \"Interrupt\") {\n\t\t\t\t\t\tyield* cancel(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tnew RequestKey({ endpoint, id: message.requestId }),\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (message._tag === \"Ack\") {\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(state, endpoint, \"request\", \"control\", message),\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t).pipe(Effect.mapError((failure) => rpcError(Cause.fail(failure)))),\n\t})\n}\nconst serverProtocol = (\n\tstate: State,\n\tendpoint: string,\n): RpcServer.Protocol[\"Service\"] => {\n\t// Accessors accept endpoints declared when the port was created.\n\tconst server = Option.getOrThrow(HashMap.get(state.servers, endpoint))\n\treturn RpcServer.Protocol.of({\n\t\tcodecFor: RpcSerialization.json.codecFor,\n\t\tsupportsAck: true,\n\t\tsupportsTransferables: false,\n\t\tsupportsSpanPropagation: false,\n\t\tsupportsNotifications: false,\n\t\tclientIds: Effect.succeed(new Set([0])),\n\t\tinitialMessage: Effect.succeedNone,\n\t\tdisconnects: server.disconnects,\n\t\tend: () => Effect.void,\n\t\trun: (receive) =>\n\t\t\tDeferred.succeed(server.ready, receive).pipe(\n\t\t\t\tEffect.andThen(Effect.never),\n\t\t\t),\n\t\tsend: (_id, message) =>\n\t\t\tsend(\n\t\t\t\tstate,\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tif (message._tag === \"Chunk\" || message._tag === \"Exit\") {\n\t\t\t\t\t\tconst key = new RequestKey({ endpoint, id: message.requestId })\n\t\t\t\t\t\tconst requestState = yield* TxRef.get(state.incoming).pipe(\n\t\t\t\t\t\t\tEffect.map(HashMap.get(key)),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (Option.isNone(requestState)) return\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(\n\t\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\t\tendpoint,\n\t\t\t\t\t\t\t\t\"response\",\n\t\t\t\t\t\t\t\tmessage._tag === \"Exit\"\n\t\t\t\t\t\t\t\t\t? \"control\"\n\t\t\t\t\t\t\t\t\t: requestState.value.priority,\n\t\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (message._tag === \"Exit\")\n\t\t\t\t\t\t\tyield* remove(state.incoming, key, requestState.value)\n\t\t\t\t\t} else\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(state, endpoint, \"response\", \"control\", message),\n\t\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t).pipe(\n\t\t\t\t// Disconnect already carries this cause to the server; late sends need no second failure.\n\t\t\t\tEffect.catchTag(\"TransportError\", () => Effect.void),\n\t\t\t),\n\t})\n}\nconst next = (state: State) =>\n\tEffect.tx(\n\t\tEffect.gen(function* () {\n\t\t\tyield* state.workers.check\n\t\t\tfor (const p of [\n\t\t\t\t\"control\",\n\t\t\t\t\"data\",\n\t\t\t\t\"log\",\n\t\t\t] satisfies ReadonlyArray<Priority>) {\n\t\t\t\tconst pending = yield* TxQueue.poll(state.queues[p])\n\t\t\t\tif (Option.isNone(pending)) continue\n\t\t\t\tconst { frame, request } = pending.value\n\t\t\t\tif (Option.isSome(request)) {\n\t\t\t\t\tconst table = yield* TxRef.get(state.outgoing)\n\t\t\t\t\tconst requestState = HashMap.get(table, request.value)\n\t\t\t\t\tif (Option.isNone(requestState)) return Option.none<Frame>()\n\t\t\t\t\tyield* TxRef.set(\n\t\t\t\t\t\tstate.outgoing,\n\t\t\t\t\t\tHashMap.set(table, request.value, {\n\t\t\t\t\t\t\t...requestState.value,\n\t\t\t\t\t\t\tsent: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn Option.some(frame)\n\t\t\t}\n\t\t\tif (\n\t\t\t\t(yield* TxQueue.isDone(state.queues.control)) &&\n\t\t\t\t(yield* TxQueue.isDone(state.queues.data)) &&\n\t\t\t\t(yield* TxQueue.isDone(state.queues.log))\n\t\t\t)\n\t\t\t\treturn yield* Cause.done()\n\t\t\treturn yield* Effect.txRetry\n\t\t}),\n\t)\nconst writer = (state: State) =>\n\tStream.fromEffectRepeat(next(state)).pipe(\n\t\tStream.filterMap(Result.fromOption(() => undefined)),\n\t\tStream.mapEffect((frame) =>\n\t\t\tSchema.encodeEffect(Schema.fromJsonString(Frame))(frame).pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t\tStream.map((json) => new TextEncoder().encode(json + \"\\n\")),\n\t\tStream.run(state.bytes.output),\n\t)\nconst read = Effect.fnUntraced(function* (state: State, raw: unknown) {\n\tconst current = yield* Schema.decodeUnknownEffect(Frame)(raw).pipe(\n\t\tEffect.mapError((cause) =>\n\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t),\n\t)\n\tif (current.session !== state.options.session) return\n\tif (current.direction === \"request\") {\n\t\tconst server = HashMap.get(state.servers, current.endpoint)\n\t\tif (Option.isNone(server))\n\t\t\treturn yield* error(`Unknown RPC server endpoint: ${current.endpoint}`)\n\t\tconst message = yield* Schema.decodeUnknownEffect(Request)(\n\t\t\tcurrent.message,\n\t\t).pipe(\n\t\t\tEffect.mapError((cause) =>\n\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t),\n\t\t)\n\t\tif (message._tag === \"Eof\")\n\t\t\treturn yield* TransportError.make({\n\t\t\t\tcause: Cause.fail(EndOfStream.make({})),\n\t\t\t})\n\t\tconst key = new RequestKey({\n\t\t\tendpoint: current.endpoint,\n\t\t\tid: message._tag === \"Request\" ? message.id : message.requestId,\n\t\t})\n\t\tif (message._tag === \"Request\") {\n\t\t\tconst p = priority(server.value.group, message.tag)\n\t\t\tconst requestState = yield* mailbox<RpcMessage.FromClientEncoded>(p)\n\t\t\tyield* admit(state, state.incoming, key, requestState, \"incoming\")\n\t\t\tyield* state.workers.run(\n\t\t\t\tStream.fromQueue(requestState.queue).pipe(\n\t\t\t\t\tStream.runForEach(\n\t\t\t\t\t\tEffect.fnUntraced(function* (request) {\n\t\t\t\t\t\t\tconst receive = yield* Deferred.await(server.value.ready)\n\t\t\t\t\t\t\tyield* receive(0, request)\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t\tyield* deliver(requestState, message)\n\t\t} else {\n\t\t\tconst requestState = yield* TxRef.get(state.incoming).pipe(\n\t\t\t\tEffect.map(HashMap.get(key)),\n\t\t\t)\n\t\t\tif (Option.isSome(requestState))\n\t\t\t\tyield* deliver(requestState.value, message)\n\t\t}\n\t} else {\n\t\tconst message = yield* Schema.decodeUnknownEffect(Response)(\n\t\t\tcurrent.message,\n\t\t).pipe(\n\t\t\tEffect.mapError((cause) =>\n\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t),\n\t\t)\n\t\tif (message._tag === \"Defect\")\n\t\t\treturn yield* TransportError.make({ cause: Cause.die(message.defect) })\n\t\tconst key = new RequestKey({\n\t\t\tendpoint: current.endpoint,\n\t\t\tid: message.requestId,\n\t\t})\n\t\tconst requestState = yield* TxRef.get(state.outgoing).pipe(\n\t\t\tEffect.map(HashMap.get(key)),\n\t\t)\n\t\tif (Option.isSome(requestState)) yield* deliver(requestState.value, message)\n\t}\n})\nconst reader = (state: State) =>\n\tstate.bytes.input.pipe(\n\t\tStream.decodeText(),\n\t\tStream.splitLines,\n\t\tStream.filter((line) => line.length > 0),\n\t\tStream.mapEffect((line) =>\n\t\t\tSchema.decodeEffect(Schema.fromJsonString(Schema.Unknown))(line).pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t\tStream.runForEach((raw) => read(state, raw)),\n\t\tEffect.andThen(\n\t\t\tEffect.fail(\n\t\t\t\tTransportError.make({ cause: Cause.fail(EndOfStream.make({})) }),\n\t\t\t),\n\t\t),\n\t)\n\n/** One RPC client/server per declared endpoint; servers may start after the port. */\nexport const make = Effect.fnUntraced(function* (\n\tbytes: Channel,\n\toptions: Options,\n): Effect.fn.Return<Port, never, import(\"effect\").Scope.Scope> {\n\tconst state = yield* initialize(bytes, options)\n\t// The same failure remains observable through Port.await and client requests.\n\t// This observer only publishes disconnects, even while the owner closes its scope.\n\tyield* state.workers.await.pipe(\n\t\tEffect.catchCause(() =>\n\t\t\tEffect.uninterruptible(\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tfor (const server of HashMap.values(state.servers))\n\t\t\t\t\t\tyield* Queue.offer(server.disconnects, 0)\n\t\t\t\t\tyield* Effect.tx(\n\t\t\t\t\t\tTxRef.set(state.incoming, HashMap.empty()).pipe(\n\t\t\t\t\t\t\tEffect.andThen(TxRef.set(state.outgoing, HashMap.empty())),\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t\tEffect.forkScoped,\n\t)\n\tconst writing = yield* state.workers.run(writer(state))\n\tyield* state.workers.run(reader(state))\n\treturn {\n\t\tclientProtocol: (endpoint) => clientProtocol(state, endpoint),\n\t\tserverProtocol: (endpoint) => serverProtocol(state, endpoint),\n\t\tawait: state.workers.await,\n\t\tfail: state.workers.fail,\n\t\tend: Effect.tx(\n\t\t\tEffect.forEach(Record.values(state.queues), TxQueue.end, {\n\t\t\t\tdiscard: true,\n\t\t\t}),\n\t\t).pipe(Effect.andThen(Fiber.join(writing))),\n\t}\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"port.js","names":["FailureGroup.make"],"sources":["../../src/internal/port.ts"],"sourcesContent":["import { EndOfStream } from \"./runner/Framing\"\nexport type { Channel } from \"../Transport\"\nimport type { Channel } from \"../Transport\"\nimport {\n\tArray,\n\tCause,\n\tContext,\n\tData,\n\tDeferred,\n\tEffect,\n\tFiber,\n\tHashMap,\n\tOption,\n\tQueue,\n\tRecord,\n\tResult,\n\tSchema,\n\ttype Scope,\n\tStream,\n\tTxQueue,\n\tTxRef,\n} from \"effect\"\nimport {\n\tRpcClient,\n\tRpcClientError,\n\tRpcSerialization,\n\tRpcServer,\n} from \"effect/rpc\"\nimport type { Rpc, RpcGroup, RpcMessage } from \"effect/rpc\"\nimport * as FailureGroup from \"./FailureGroup\"\nimport { TransportError } from \"../Errors\"\nimport { defaults, type Limits } from \"./Limits\"\nexport type Priority = keyof Limits\n\nexport const Priority = Context.Reference<Priority>(\n\t\"@graftland/plugin-remote/internal/port/Priority\",\n\t{ defaultValue: () => \"data\" },\n)\ntype Endpoint = Pick<RpcGroup.RpcGroup<Rpc.Any>, \"requests\">\n\nexport interface Options {\n\treadonly session: string\n\treadonly serve: Readonly<Record<string, Endpoint>>\n\treadonly call: Readonly<Record<string, Endpoint>>\n\t/** Limits are shared across endpoints, separately for each direction.\n\t * Each peer's inbound limits must accommodate the other's outbound limits. */\n\treadonly limits?: Partial<Record<Priority, number>>\n}\nexport interface Port {\n\treadonly clientProtocol: (endpoint: string) => RpcClient.Protocol[\"Service\"]\n\treadonly serverProtocol: (endpoint: string) => RpcServer.Protocol[\"Service\"]\n\treadonly await: Effect.Effect<never, TransportError>\n\treadonly fail: (error: TransportError) => Effect.Effect<void>\n\treadonly end: Effect.Effect<void, TransportError>\n}\nclass RequestKey extends Data.Class<{\n\treadonly endpoint: string\n\treadonly id: string | number\n}> {}\ninterface RequestState<A> {\n\treadonly queue: Queue.Queue<A, Cause.Done>\n\treadonly priority: Priority\n\treadonly sent: boolean\n}\nconst Frame = Schema.Struct({\n\tsession: Schema.String,\n\tendpoint: Schema.String,\n\tdirection: Schema.Literals([\"request\", \"response\"]),\n\tpriority: Schema.Literals([\"control\", \"data\", \"log\"]),\n\tmessage: Schema.Unknown,\n})\ntype Frame = typeof Frame.Type\ninterface Pending {\n\treadonly frame: Frame\n\treadonly request: Option.Option<RequestKey>\n}\nconst Id = Schema.Union([Schema.String, Schema.Finite])\n// Only routing fields belong to this transport. The RPC serialization codec\n// validates payloads, chunks and exits before handlers or callers see them. These\n// protocol callbacks are an opaque handoff, not validation of a complete RpcMessage.\n// EncodedSchema requires binary payloads\n// in Effect 4.1.2 and cannot describe these JSON codec messages.\nconst isRequest = Schema.is(\n\tSchema.Union([\n\t\tSchema.TaggedStruct(\"Request\", { id: Id, tag: Schema.String }),\n\t\tSchema.TaggedStruct(\"Ack\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Interrupt\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Eof\", {}),\n\t]),\n)\nconst isResponse = Schema.is(\n\tSchema.Union([\n\t\tSchema.TaggedStruct(\"Exit\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Chunk\", { requestId: Id }),\n\t\tSchema.TaggedStruct(\"Defect\", { defect: Schema.Unknown }),\n\t]),\n)\nconst Request = Schema.declare<\n\tExclude<RpcMessage.FromClientEncoded, RpcMessage.Ping>\n>((input): input is Exclude<RpcMessage.FromClientEncoded, RpcMessage.Ping> =>\n\tisRequest(input),\n)\nconst Response = Schema.declare<\n\tExclude<\n\t\tRpcMessage.FromServerEncoded,\n\t\tRpcMessage.Pong | RpcMessage.ClientProtocolError | RpcMessage.RequestEncoded\n\t>\n>(\n\t(\n\t\tinput,\n\t): input is Exclude<\n\t\tRpcMessage.FromServerEncoded,\n\t\tRpcMessage.Pong | RpcMessage.ClientProtocolError | RpcMessage.RequestEncoded\n\t> => isResponse(input),\n)\nconst error = (message: string) =>\n\tTransportError.make({ cause: Cause.die(new Error(message)) })\nconst rpcError = (cause: Cause.Cause<TransportError>) =>\n\tRpcClientError.RpcClientError.make({\n\t\treason: RpcClientError.RpcClientDefect.make({\n\t\t\tmessage: \"Remote connection failed\",\n\t\t\tcause,\n\t\t}),\n\t})\nconst priority = (group: Endpoint, tag: string): Priority => {\n\tconst rpc = group.requests.get(tag)\n\treturn rpc === undefined ? \"data\" : Context.get(rpc.annotations, Priority)\n}\nconst mailbox = <A>(priority: Priority) =>\n\tQueue.dropping<A, Cause.Done>(2).pipe(\n\t\tEffect.map((queue): RequestState<A> => ({ queue, priority, sent: false })),\n\t)\nconst deliver = Effect.fnUntraced(function* <A>(\n\trequestState: RequestState<A>,\n\tmessage: A,\n) {\n\t// One unacknowledged chunk and its terminal Exit may coexist.\n\tif (!(yield* Queue.offer(requestState.queue, message)))\n\t\treturn yield* error(\"RPC request mailbox overflow\")\n})\n\ntype ServerEndpoint = {\n\treadonly group: Endpoint\n\treadonly ready: Deferred.Deferred<\n\t\tParameters<RpcServer.Protocol[\"Service\"][\"run\"]>[0]\n\t>\n\treadonly disconnects: Queue.Queue<number>\n}\ntype ClientEndpoint = {\n\treadonly group: Endpoint\n\treadonly ready: Deferred.Deferred<\n\t\tParameters<RpcClient.Protocol[\"Service\"][\"run\"]>[1]\n\t>\n}\ninterface State {\n\treadonly bytes: Channel\n\treadonly options: Options\n\treadonly limits: Record<Priority, number>\n\treadonly workers: FailureGroup.FailureGroup<TransportError>\n\treadonly incoming: TxRef.TxRef<\n\t\tHashMap.HashMap<RequestKey, RequestState<RpcMessage.FromClientEncoded>>\n\t>\n\treadonly outgoing: TxRef.TxRef<\n\t\tHashMap.HashMap<RequestKey, RequestState<RpcMessage.FromServerEncoded>>\n\t>\n\treadonly queues: Record<Priority, TxQueue.TxQueue<Pending, Cause.Done>>\n\treadonly servers: HashMap.HashMap<string, ServerEndpoint>\n\treadonly clients: HashMap.HashMap<string, ClientEndpoint>\n}\nconst initialize = Effect.fnUntraced(function* (\n\tbytes: Channel,\n\toptions: Options,\n): Effect.fn.Return<State, never, Scope.Scope> {\n\tconst limits = { ...defaults, ...options.limits }\n\tconst workers = yield* FailureGroup.make<TransportError>()\n\tconst incoming = yield* TxRef.make(\n\t\tHashMap.empty<RequestKey, RequestState<RpcMessage.FromClientEncoded>>(),\n\t)\n\tconst outgoing = yield* TxRef.make(\n\t\tHashMap.empty<RequestKey, RequestState<RpcMessage.FromServerEncoded>>(),\n\t)\n\tconst queues = {\n\t\tcontrol: yield* TxQueue.unbounded<Pending, Cause.Done>(),\n\t\tdata: yield* TxQueue.unbounded<Pending, Cause.Done>(),\n\t\tlog: yield* TxQueue.unbounded<Pending, Cause.Done>(),\n\t}\n\tconst servers = yield* Effect.forEach(\n\t\tRecord.toEntries(options.serve),\n\t\tEffect.fnUntraced(function* ([name, group]) {\n\t\t\treturn [\n\t\t\t\tname,\n\t\t\t\t{\n\t\t\t\t\tgroup,\n\t\t\t\t\tready:\n\t\t\t\t\t\tyield* Deferred.make<\n\t\t\t\t\t\t\tParameters<RpcServer.Protocol[\"Service\"][\"run\"]>[0]\n\t\t\t\t\t\t>(),\n\t\t\t\t\tdisconnects: yield* Queue.dropping<number>(1),\n\t\t\t\t},\n\t\t\t] satisfies readonly [string, unknown]\n\t\t}),\n\t).pipe(Effect.map(HashMap.fromIterable))\n\tconst clients = yield* Effect.forEach(\n\t\tRecord.toEntries(options.call),\n\t\tEffect.fnUntraced(function* ([name, group]) {\n\t\t\treturn [\n\t\t\t\tname,\n\t\t\t\t{\n\t\t\t\t\tgroup,\n\t\t\t\t\tready:\n\t\t\t\t\t\tyield* Deferred.make<\n\t\t\t\t\t\t\tParameters<RpcClient.Protocol[\"Service\"][\"run\"]>[1]\n\t\t\t\t\t\t>(),\n\t\t\t\t},\n\t\t\t] satisfies readonly [string, unknown]\n\t\t}),\n\t).pipe(Effect.map(HashMap.fromIterable))\n\treturn {\n\t\tbytes,\n\t\toptions,\n\t\tlimits,\n\t\tworkers,\n\t\tincoming,\n\t\toutgoing,\n\t\tqueues,\n\t\tservers,\n\t\tclients,\n\t}\n})\n\nconst admit = Effect.fnUntraced(function* <A>(\n\tstate: State,\n\ttable: TxRef.TxRef<HashMap.HashMap<RequestKey, RequestState<A>>>,\n\tkey: RequestKey,\n\trequestState: RequestState<A>,\n\tdirection: \"incoming\" | \"outgoing\",\n) {\n\tyield* Effect.tx(\n\t\tEffect.gen(function* () {\n\t\t\tyield* state.workers.check\n\t\t\tconst current = yield* TxRef.get(table)\n\t\t\tconst count = Array.filter(\n\t\t\t\tArray.fromIterable(HashMap.values(current)),\n\t\t\t\t(entry) => entry.priority === requestState.priority,\n\t\t\t).length\n\t\t\tif (count >= state.limits[requestState.priority]) {\n\t\t\t\tif (direction === \"outgoing\") return yield* Effect.txRetry\n\t\t\t\treturn yield* error(\n\t\t\t\t\t`RPC admission limit exceeded for ${requestState.priority}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tyield* TxRef.set(table, HashMap.set(current, key, requestState))\n\t\t}),\n\t)\n})\nconst remove = Effect.fnUntraced(function* <A>(\n\ttable: TxRef.TxRef<HashMap.HashMap<RequestKey, RequestState<A>>>,\n\tkey: RequestKey,\n\trequestState: RequestState<A>,\n) {\n\tyield* TxRef.update(table, HashMap.remove(key))\n\tyield* Queue.end(requestState.queue)\n})\nconst enqueue = (\n\tstate: State,\n\tframe: Frame,\n\trequest: Option.Option<RequestKey> = Option.none(),\n) =>\n\tEffect.tx(\n\t\tstate.workers.check.pipe(\n\t\t\tEffect.andThen(\n\t\t\t\tTxQueue.offer(state.queues[frame.priority], { frame, request }).pipe(\n\t\t\t\t\tEffect.flatMap((accepted) =>\n\t\t\t\t\t\taccepted ? Effect.void : error(\"Remote output has ended\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t\tEffect.asVoid,\n\t\t),\n\t)\nconst frame = (\n\tstate: State,\n\tendpoint: string,\n\tdirection: Frame[\"direction\"],\n\tp: Priority,\n\tmessage: unknown,\n): Frame => ({\n\tsession: state.options.session,\n\tendpoint,\n\tdirection,\n\tpriority: p,\n\tmessage,\n})\n// Protocol sends are owned too: interrupting a caller cancels admission or enqueue.\nconst send = Effect.fnUntraced(function* (\n\tstate: State,\n\teffect: Effect.Effect<void, TransportError>,\n) {\n\tconst fiber = yield* state.workers.run(\n\t\tstate.workers.check.pipe(Effect.andThen(effect)),\n\t)\n\tconst result = yield* Fiber.await(fiber).pipe(\n\t\tEffect.onInterrupt(() => Fiber.interrupt(fiber)),\n\t)\n\t// Group teardown interrupts this worker; callers still receive the connection cause.\n\tyield* state.workers.check\n\tyield* result\n})\nconst cancel = Effect.fnUntraced(function* (state: State, key: RequestKey) {\n\tconst canceled = yield* Effect.tx(\n\t\tEffect.gen(function* () {\n\t\t\tconst table = yield* TxRef.get(state.outgoing)\n\t\t\tconst requestState = HashMap.get(table, key)\n\t\t\tif (Option.isNone(requestState))\n\t\t\t\treturn Option.none<RequestState<RpcMessage.FromServerEncoded>>()\n\t\t\tif (requestState.value.sent) {\n\t\t\t\tyield* enqueue(\n\t\t\t\t\tstate,\n\t\t\t\t\tframe(state, key.endpoint, \"request\", \"control\", {\n\t\t\t\t\t\t_tag: \"Interrupt\",\n\t\t\t\t\t\trequestId: key.id,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\treturn Option.none<RequestState<RpcMessage.FromServerEncoded>>()\n\t\t\t}\n\t\t\tyield* TxRef.set(state.outgoing, HashMap.remove(table, key))\n\t\t\treturn requestState\n\t\t}),\n\t)\n\tif (Option.isSome(canceled)) yield* Queue.end(canceled.value.queue)\n})\nconst clientProtocol = (\n\tstate: State,\n\tendpoint: string,\n): RpcClient.Protocol[\"Service\"] => {\n\t// Accessors accept endpoints declared when the port was created.\n\tconst client = Option.getOrThrow(HashMap.get(state.clients, endpoint))\n\treturn RpcClient.Protocol.of({\n\t\tcodecFor: RpcSerialization.json.codecFor,\n\t\tsupportsAck: true,\n\t\tsupportsTransferables: false,\n\t\trun: (_id, receive) =>\n\t\t\tDeferred.succeed(client.ready, receive).pipe(\n\t\t\t\tEffect.andThen(state.workers.await),\n\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\treceive({ _tag: \"ClientProtocolError\", error: rpcError(cause) }),\n\t\t\t\t),\n\t\t\t\tEffect.andThen(Effect.never),\n\t\t\t),\n\t\tsend: (_id, message) =>\n\t\t\tsend(\n\t\t\t\tstate,\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tif (message._tag === \"Request\") {\n\t\t\t\t\t\tif (message.discard === true || message.isNotification === true)\n\t\t\t\t\t\t\treturn yield* error(\n\t\t\t\t\t\t\t\t\"Discard and notification requests are not supported\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\tconst key = new RequestKey({ endpoint, id: message.id })\n\t\t\t\t\t\tconst requestState = yield* mailbox<RpcMessage.FromServerEncoded>(\n\t\t\t\t\t\t\tpriority(client.group, message.tag),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tyield* admit(state, state.outgoing, key, requestState, \"outgoing\")\n\t\t\t\t\t\tyield* state.workers.run(\n\t\t\t\t\t\t\tStream.fromQueue(requestState.queue).pipe(\n\t\t\t\t\t\t\t\tStream.runForEach(\n\t\t\t\t\t\t\t\t\tEffect.fnUntraced(function* (response) {\n\t\t\t\t\t\t\t\t\t\tconst receive = yield* Deferred.await(client.ready)\n\t\t\t\t\t\t\t\t\t\tif (response._tag === \"Exit\")\n\t\t\t\t\t\t\t\t\t\t\tyield* remove(state.outgoing, key, requestState)\n\t\t\t\t\t\t\t\t\t\tyield* receive(response)\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(state, endpoint, \"request\", requestState.priority, message),\n\t\t\t\t\t\t\tOption.some(key),\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (message._tag === \"Interrupt\") {\n\t\t\t\t\t\tyield* cancel(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tnew RequestKey({ endpoint, id: message.requestId }),\n\t\t\t\t\t\t)\n\t\t\t\t\t} else if (message._tag === \"Ack\") {\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(state, endpoint, \"request\", \"control\", message),\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t).pipe(Effect.mapError((failure) => rpcError(Cause.fail(failure)))),\n\t})\n}\nconst serverProtocol = (\n\tstate: State,\n\tendpoint: string,\n): RpcServer.Protocol[\"Service\"] => {\n\t// Accessors accept endpoints declared when the port was created.\n\tconst server = Option.getOrThrow(HashMap.get(state.servers, endpoint))\n\treturn RpcServer.Protocol.of({\n\t\tcodecFor: RpcSerialization.json.codecFor,\n\t\tsupportsAck: true,\n\t\tsupportsTransferables: false,\n\t\tsupportsSpanPropagation: false,\n\t\tsupportsNotifications: false,\n\t\tclientIds: Effect.succeed(new Set([0])),\n\t\tinitialMessage: Effect.succeedNone,\n\t\tdisconnects: server.disconnects,\n\t\tend: () => Effect.void,\n\t\trun: (receive) =>\n\t\t\tDeferred.succeed(server.ready, receive).pipe(\n\t\t\t\tEffect.andThen(Effect.never),\n\t\t\t),\n\t\tsend: (_id, message) =>\n\t\t\tsend(\n\t\t\t\tstate,\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tif (message._tag === \"Chunk\" || message._tag === \"Exit\") {\n\t\t\t\t\t\tconst key = new RequestKey({ endpoint, id: message.requestId })\n\t\t\t\t\t\tconst requestState = yield* TxRef.get(state.incoming).pipe(\n\t\t\t\t\t\t\tEffect.map(HashMap.get(key)),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (Option.isNone(requestState)) return\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(\n\t\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\t\tendpoint,\n\t\t\t\t\t\t\t\t\"response\",\n\t\t\t\t\t\t\t\tmessage._tag === \"Exit\"\n\t\t\t\t\t\t\t\t\t? \"control\"\n\t\t\t\t\t\t\t\t\t: requestState.value.priority,\n\t\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (message._tag === \"Exit\")\n\t\t\t\t\t\t\tyield* remove(state.incoming, key, requestState.value)\n\t\t\t\t\t} else\n\t\t\t\t\t\tyield* enqueue(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\tframe(state, endpoint, \"response\", \"control\", message),\n\t\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t).pipe(\n\t\t\t\t// Disconnect already carries this cause to the server; late sends need no second failure.\n\t\t\t\tEffect.catchTag(\"TransportError\", () => Effect.void),\n\t\t\t),\n\t})\n}\nconst next = Effect.fnUntraced(function* (state: State) {\n\tyield* state.workers.check\n\tfor (const p of [\n\t\t\"control\",\n\t\t\"data\",\n\t\t\"log\",\n\t] satisfies ReadonlyArray<Priority>) {\n\t\tconst pending = yield* TxQueue.poll(state.queues[p])\n\t\tif (Option.isNone(pending)) continue\n\t\tconst { frame, request } = pending.value\n\t\tif (Option.isSome(request)) {\n\t\t\tconst table = yield* TxRef.get(state.outgoing)\n\t\t\tconst requestState = HashMap.get(table, request.value)\n\t\t\tif (Option.isNone(requestState)) return Option.none<Frame>()\n\t\t\tyield* TxRef.set(\n\t\t\t\tstate.outgoing,\n\t\t\t\tHashMap.set(table, request.value, {\n\t\t\t\t\t...requestState.value,\n\t\t\t\t\tsent: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn Option.some(frame)\n\t}\n\tif (\n\t\t(yield* TxQueue.isDone(state.queues.control)) &&\n\t\t(yield* TxQueue.isDone(state.queues.data)) &&\n\t\t(yield* TxQueue.isDone(state.queues.log))\n\t)\n\t\treturn yield* Cause.done()\n\treturn yield* Effect.txRetry\n}, Effect.tx)\nconst writer = (state: State) =>\n\tStream.fromEffectRepeat(next(state)).pipe(\n\t\tStream.filterMap(Result.fromOption(() => undefined)),\n\t\tStream.mapEffect((frame) =>\n\t\t\tSchema.encodeEffect(Schema.fromJsonString(Frame))(frame).pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t\tStream.map((json) => new TextEncoder().encode(json + \"\\n\")),\n\t\tStream.run(state.bytes.output),\n\t)\nconst read = Effect.fnUntraced(function* (state: State, raw: unknown) {\n\tconst current = yield* Schema.decodeUnknownEffect(Frame)(raw).pipe(\n\t\tEffect.mapError((cause) =>\n\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t),\n\t)\n\tif (current.session !== state.options.session) return\n\tif (current.direction === \"request\") {\n\t\tconst server = HashMap.get(state.servers, current.endpoint)\n\t\tif (Option.isNone(server))\n\t\t\treturn yield* error(`Unknown RPC server endpoint: ${current.endpoint}`)\n\t\tconst message = yield* Schema.decodeUnknownEffect(Request)(\n\t\t\tcurrent.message,\n\t\t).pipe(\n\t\t\tEffect.mapError((cause) =>\n\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t),\n\t\t)\n\t\tif (message._tag === \"Eof\")\n\t\t\treturn yield* TransportError.make({\n\t\t\t\tcause: Cause.fail(EndOfStream.make({})),\n\t\t\t})\n\t\tconst key = new RequestKey({\n\t\t\tendpoint: current.endpoint,\n\t\t\tid: message._tag === \"Request\" ? message.id : message.requestId,\n\t\t})\n\t\tif (message._tag === \"Request\") {\n\t\t\tconst p = priority(server.value.group, message.tag)\n\t\t\tconst requestState = yield* mailbox<RpcMessage.FromClientEncoded>(p)\n\t\t\tyield* admit(state, state.incoming, key, requestState, \"incoming\")\n\t\t\tyield* state.workers.run(\n\t\t\t\tStream.fromQueue(requestState.queue).pipe(\n\t\t\t\t\tStream.runForEach(\n\t\t\t\t\t\tEffect.fnUntraced(function* (request) {\n\t\t\t\t\t\t\tconst receive = yield* Deferred.await(server.value.ready)\n\t\t\t\t\t\t\tyield* receive(0, request)\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t\tyield* deliver(requestState, message)\n\t\t} else {\n\t\t\tconst requestState = yield* TxRef.get(state.incoming).pipe(\n\t\t\t\tEffect.map(HashMap.get(key)),\n\t\t\t)\n\t\t\tif (Option.isSome(requestState))\n\t\t\t\tyield* deliver(requestState.value, message)\n\t\t}\n\t} else {\n\t\tconst message = yield* Schema.decodeUnknownEffect(Response)(\n\t\t\tcurrent.message,\n\t\t).pipe(\n\t\t\tEffect.mapError((cause) =>\n\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t),\n\t\t)\n\t\tif (message._tag === \"Defect\")\n\t\t\treturn yield* TransportError.make({ cause: Cause.die(message.defect) })\n\t\tconst key = new RequestKey({\n\t\t\tendpoint: current.endpoint,\n\t\t\tid: message.requestId,\n\t\t})\n\t\tconst requestState = yield* TxRef.get(state.outgoing).pipe(\n\t\t\tEffect.map(HashMap.get(key)),\n\t\t)\n\t\tif (Option.isSome(requestState)) yield* deliver(requestState.value, message)\n\t}\n})\nconst reader = (state: State) =>\n\tstate.bytes.input.pipe(\n\t\tStream.decodeText(),\n\t\tStream.splitLines,\n\t\tStream.filter((line) => line.length > 0),\n\t\tStream.mapEffect((line) =>\n\t\t\tSchema.decodeEffect(Schema.fromJsonString(Schema.Unknown))(line).pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\tTransportError.make({ cause: Cause.fail(cause) }),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t\tStream.runForEach((raw) => read(state, raw)),\n\t\tEffect.andThen(\n\t\t\tEffect.fail(\n\t\t\t\tTransportError.make({ cause: Cause.fail(EndOfStream.make({})) }),\n\t\t\t),\n\t\t),\n\t)\n\n/** One RPC client/server per declared endpoint; servers may start after the port. */\nexport const make = Effect.fnUntraced(function* (\n\tbytes: Channel,\n\toptions: Options,\n): Effect.fn.Return<Port, never, import(\"effect\").Scope.Scope> {\n\tconst state = yield* initialize(bytes, options)\n\t// The same failure remains observable through Port.await and client requests.\n\t// This observer only publishes disconnects, even while the owner closes its scope.\n\tyield* state.workers.await.pipe(\n\t\tEffect.catchCause(\n\t\t\tEffect.fnUntraced(function* () {\n\t\t\t\tfor (const server of HashMap.values(state.servers))\n\t\t\t\t\tyield* Queue.offer(server.disconnects, 0)\n\t\t\t\tyield* Effect.tx(\n\t\t\t\t\tTxRef.set(state.incoming, HashMap.empty()).pipe(\n\t\t\t\t\t\tEffect.andThen(TxRef.set(state.outgoing, HashMap.empty())),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}, Effect.uninterruptible),\n\t\t),\n\t\tEffect.forkScoped,\n\t)\n\tconst writing = yield* state.workers.run(writer(state))\n\tyield* state.workers.run(reader(state))\n\treturn {\n\t\tclientProtocol: (endpoint) => clientProtocol(state, endpoint),\n\t\tserverProtocol: (endpoint) => serverProtocol(state, endpoint),\n\t\tawait: state.workers.await,\n\t\tfail: state.workers.fail,\n\t\tend: Effect.tx(\n\t\t\tEffect.forEach(Record.values(state.queues), TxQueue.end, {\n\t\t\t\tdiscard: true,\n\t\t\t}),\n\t\t).pipe(Effect.andThen(Fiber.join(writing))),\n\t}\n})\n"],"mappings":"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"}
|
package/dist/internal/release.js
CHANGED
|
@@ -7,7 +7,7 @@ var ReleaseInterrupted = class extends Schema.TaggedError()("ReleaseInterrupted"
|
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
9
|
/** Keep a known release failure distinguishable from cancellation through enclosing scopes. */
|
|
10
|
-
const close = (scope, exit) => Effect.uninterruptible(Scope.close(scope, exit).pipe(Effect.catchCauseIf(Cause.hasInterruptsOnly,
|
|
10
|
+
const close = (scope, exit) => Effect.uninterruptible(Scope.close(scope, exit).pipe(Effect.catchCauseIf(Cause.hasInterruptsOnly, Effect.fnUntraced(function* (cause) {
|
|
11
11
|
const pending = yield* Effect.exit(Effect.interruptible(Effect.void));
|
|
12
12
|
const [cancelled, interrupted] = Array.partition(cause.reasons, (reason) => Exit.isFailure(pending) && Array.some(pending.cause.reasons, (external) => reason._tag === "Interrupt" && external._tag === "Interrupt" && reason.fiberId === external.fiberId) ? Result.succeed(reason) : Result.fail(reason));
|
|
13
13
|
if (interrupted.length === 0) return yield* Effect.failCause(cause);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.js","names":[],"sources":["../../src/internal/release.ts"],"sourcesContent":["import { Array, Cause, Effect, Exit, Result, Schema, Scope } from \"effect\"\n\n/** Resource release was interrupted, rather than successfully cancelled. */\nexport class ReleaseInterrupted extends Schema.TaggedError<\n\tReleaseInterrupted,\n\t{ readonly brand: unique symbol }\n>()(\"ReleaseInterrupted\", {\n\tcause: Schema.Cause(Schema.Never, Schema.Unknown),\n}) {\n\toverride get message() {\n\t\treturn \"Resource release was interrupted\"\n\t}\n}\n\n/** Keep a known release failure distinguishable from cancellation through enclosing scopes. */\nexport const close = (\n\tscope: Scope.Closeable,\n\texit: Exit.Exit<unknown, unknown>,\n) =>\n\tEffect.uninterruptible(\n\t\tScope.close(scope, exit).pipe(\n\t\t\tEffect.catchCauseIf(
|
|
1
|
+
{"version":3,"file":"release.js","names":[],"sources":["../../src/internal/release.ts"],"sourcesContent":["import { Array, Cause, Effect, Exit, Result, Schema, Scope } from \"effect\"\n\n/** Resource release was interrupted, rather than successfully cancelled. */\nexport class ReleaseInterrupted extends Schema.TaggedError<\n\tReleaseInterrupted,\n\t{ readonly brand: unique symbol }\n>()(\"ReleaseInterrupted\", {\n\tcause: Schema.Cause(Schema.Never, Schema.Unknown),\n}) {\n\toverride get message() {\n\t\treturn \"Resource release was interrupted\"\n\t}\n}\n\n/** Keep a known release failure distinguishable from cancellation through enclosing scopes. */\nexport const close = (\n\tscope: Scope.Closeable,\n\texit: Exit.Exit<unknown, unknown>,\n) =>\n\tEffect.uninterruptible(\n\t\tScope.close(scope, exit).pipe(\n\t\t\tEffect.catchCauseIf(\n\t\t\t\tCause.hasInterruptsOnly,\n\t\t\t\tEffect.fnUntraced(function* (cause) {\n\t\t\t\t\t// Re-entering interruptibility observes pending external cancellation without producing a self-interrupt.\n\t\t\t\t\t// Read it after release so cancellation arriving during a finalizer is included too.\n\t\t\t\t\tconst pending = yield* Effect.exit(Effect.interruptible(Effect.void))\n\t\t\t\t\tconst [cancelled, interrupted] = Array.partition(\n\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\tExit.isFailure(pending) &&\n\t\t\t\t\t\t\tArray.some(\n\t\t\t\t\t\t\t\tpending.cause.reasons,\n\t\t\t\t\t\t\t\t(external) =>\n\t\t\t\t\t\t\t\t\treason._tag === \"Interrupt\" &&\n\t\t\t\t\t\t\t\t\texternal._tag === \"Interrupt\" &&\n\t\t\t\t\t\t\t\t\treason.fiberId === external.fiberId,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t? Result.succeed(reason)\n\t\t\t\t\t\t\t\t: Result.fail(reason),\n\t\t\t\t\t)\n\t\t\t\t\tif (interrupted.length === 0) return yield* Effect.failCause(cause)\n\t\t\t\t\treturn yield* Effect.failCause(\n\t\t\t\t\t\tCause.combine(\n\t\t\t\t\t\t\tCause.fromReasons(cancelled),\n\t\t\t\t\t\t\tCause.die(\n\t\t\t\t\t\t\t\tReleaseInterrupted.make({\n\t\t\t\t\t\t\t\t\tcause: Cause.fromReasons(interrupted),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t)\n\nexport const scoped = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n\tEffect.uninterruptibleMask((restore) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst scope = yield* Scope.make()\n\t\t\tconst body = yield* Effect.exit(restore(Scope.provide(scope)(effect)))\n\t\t\tconst closed = yield* Effect.exit(close(scope, body))\n\t\t\tif (Exit.isFailure(closed))\n\t\t\t\treturn yield* Effect.failCause(\n\t\t\t\t\tExit.isFailure(body)\n\t\t\t\t\t\t? Cause.combine(body.cause, closed.cause)\n\t\t\t\t\t\t: closed.cause,\n\t\t\t\t)\n\t\t\treturn yield* body\n\t\t}),\n\t)\n"],"mappings":";;;AAGA,IAAa,qBAAb,cAAwC,OAAO,YAG7C,CAAC,CAAC,sBAAsB,EACzB,OAAO,OAAO,MAAM,OAAO,OAAO,OAAO,OAAO,EACjD,CAAC,CAAC,CAAC;CACF,IAAa,UAAU;EACtB,OAAO;CACR;AACD;;AAGA,MAAa,SACZ,OACA,SAEA,OAAO,gBACN,MAAM,MAAM,OAAO,IAAI,CAAC,CAAC,KACxB,OAAO,aACN,MAAM,mBACN,OAAO,WAAW,WAAW,OAAO;CAGnC,MAAM,UAAU,OAAO,OAAO,KAAK,OAAO,cAAc,OAAO,IAAI,CAAC;CACpE,MAAM,CAAC,WAAW,eAAe,MAAM,UACtC,MAAM,UACL,WACA,KAAK,UAAU,OAAO,KACtB,MAAM,KACL,QAAQ,MAAM,UACb,aACA,OAAO,SAAS,eAChB,SAAS,SAAS,eAClB,OAAO,YAAY,SAAS,OAC9B,IACG,OAAO,QAAQ,MAAM,IACrB,OAAO,KAAK,MAAM,CACvB;CACA,IAAI,YAAY,WAAW,GAAG,OAAO,OAAO,OAAO,UAAU,KAAK;CAClE,OAAO,OAAO,OAAO,UACpB,MAAM,QACL,MAAM,YAAY,SAAS,GAC3B,MAAM,IACL,mBAAmB,KAAK,EACvB,OAAO,MAAM,YAAY,WAAW,EACrC,CAAC,CACF,CACD,CACD;AACD,CAAC,CACF,CACD,CACD;AAED,MAAa,UAAmB,WAC/B,OAAO,qBAAqB,YAC3B,OAAO,IAAI,aAAa;CACvB,MAAM,QAAQ,OAAO,MAAM,KAAK;CAChC,MAAM,OAAO,OAAO,OAAO,KAAK,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;CACrE,MAAM,SAAS,OAAO,OAAO,KAAK,MAAM,OAAO,IAAI,CAAC;CACpD,IAAI,KAAK,UAAU,MAAM,GACxB,OAAO,OAAO,OAAO,UACpB,KAAK,UAAU,IAAI,IAChB,MAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,IACtC,OAAO,KACX;CACD,OAAO,OAAO;AACf,CAAC,CACF"}
|
|
@@ -7,5 +7,5 @@ import "../directTransport.js";
|
|
|
7
7
|
import "./Packages.js";
|
|
8
8
|
import "../port.js";
|
|
9
9
|
import "./Wire.js";
|
|
10
|
-
import { Cause, Context, Duration, Effect, Option, Schema, Scope } from "effect";
|
|
10
|
+
import { Cause, Context, Duration, Effect, Option, PlatformError, Schema, Scope } from "effect";
|
|
11
11
|
import { RpcClientError } from "effect/rpc";
|
|
@@ -24,17 +24,17 @@ const finish = (causes) => {
|
|
|
24
24
|
const scopes = Effect.acquireRelease(Effect.all({
|
|
25
25
|
resources: Scope.make(),
|
|
26
26
|
process: Scope.make()
|
|
27
|
-
}),
|
|
27
|
+
}), Effect.fnUntraced(function* (scopes, exit) {
|
|
28
28
|
const process = yield* Effect.exit(close(scopes.process, exit));
|
|
29
29
|
const resources = yield* Effect.exit(close(scopes.resources, exit));
|
|
30
30
|
yield* finish([reason(process), reason(resources)]);
|
|
31
31
|
}));
|
|
32
32
|
/** Setup supplies a concrete control lifecycle; release never reads a later-installed effect. */
|
|
33
|
-
const acquire = (target, contractModule, options, setup, dispose, timeout)
|
|
33
|
+
const acquire = Effect.fnUntraced(function* (target, contractModule, options, setup, dispose, timeout) {
|
|
34
34
|
const owned = yield* scopes;
|
|
35
35
|
const connection = yield* Effect.acquireRelease(Effect.gen(function* () {
|
|
36
36
|
return target._tag === "Local" || target._tag === "Worker" ? yield* Local(target, contractModule, options, owned.resources, owned.process).pipe(Effect.map(connected)) : yield* connect(target, contractModule, options, owned.resources, owned.process);
|
|
37
|
-
}).pipe(Effect.interruptible),
|
|
37
|
+
}).pipe(Effect.interruptible), Effect.fnUntraced(function* (connection, exit) {
|
|
38
38
|
const process = yield* Effect.exit(close(owned.process, exit));
|
|
39
39
|
yield* connection.diagnostics;
|
|
40
40
|
const resources = yield* Effect.exit(close(owned.resources, exit));
|
|
@@ -45,7 +45,7 @@ const acquire = (target, contractModule, options, setup, dispose, timeout) => Ef
|
|
|
45
45
|
diagnostics
|
|
46
46
|
]);
|
|
47
47
|
}));
|
|
48
|
-
return yield* Effect.acquireRelease(setup.pipe(Effect.provideService(Connection, connection)),
|
|
48
|
+
return yield* Effect.acquireRelease(setup.pipe(Effect.provideService(Connection, connection)), Effect.fnUntraced(function* (value) {
|
|
49
49
|
const graceful = yield* dispose(value).pipe(Effect.interruptible, Effect.timeout(timeout), Effect.exit);
|
|
50
50
|
const terminated = yield* Effect.exit(connection.terminate(Exit.isSuccess(graceful)));
|
|
51
51
|
yield* finish([Exit.isSuccess(graceful) ? graceful.value : graceful.cause, reason(terminated)]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Connection.js","names":["LocalProcess.connect","Release.close","RunnerConnection.connect"],"sources":["../../../src/internal/runner/Connection.ts"],"sourcesContent":["import {\n\tLocalTransport,\n\tWorkerTransport,\n\ttype Execution,\n} from \"../directTransport\"\nimport * as RunnerConnection from \"../host/runner\"\nimport {\n\tArray,\n\tCause,\n\tContext,\n\tEffect,\n\tDuration,\n\tExit,\n\tOption,\n\tScope,\n} from \"effect\"\nimport * as Release from \"../release\"\nimport type { RpcClientError } from \"effect/rpc\"\nimport type { Schema, PlatformError } from \"effect\"\nimport type { RemoteTerminationUnconfirmed } from \"./model\"\nimport type { Expected } from \"./Packages\"\n\nimport {\n\tLocalTerminationTimeout,\n\tProcessExited,\n\tTransportError,\n} from \"../../Errors\"\nimport { cleanupCause } from \"../cleanup\"\nimport * as Port from \"../port\"\nimport * as LocalProcess from \"./Local\"\nimport * as Wire from \"./Wire\"\n\nexport interface LocalTarget {\n\treadonly _tag: \"Local\"\n\treadonly command?: readonly [string, ...string[]]\n}\nexport interface WorkerTarget {\n\treadonly _tag: \"Worker\"\n\treadonly execArgv?: ReadonlyArray<string>\n}\n\nexport interface ConfiguredRunner {\n\treadonly instance: string\n\treadonly lease?: Duration.Input\n\treadonly margin?: Duration.Input\n\treadonly expect?: Expected\n\treadonly _tag: \"Connector\"\n\treadonly explicitAuth?: boolean\n}\nexport type Target = LocalTarget | WorkerTarget | ConfiguredRunner\n\ntype Peer = Port.Port\nexport interface Connected {\n\treadonly resources: Scope.Scope\n\treadonly pid: Option.Option<number>\n\treadonly threadId?: number\n\treadonly diagnostics: Effect.Effect<Cause.Cause<unknown>>\n\treadonly terminate: (\n\t\tgraceful: boolean,\n\t) => Effect.Effect<\n\t\tvoid,\n\t\t| ProcessExited\n\t\t| LocalTerminationTimeout\n\t\t| TransportError\n\t\t| Schema.SchemaError\n\t\t| Wire.SessionError\n\t\t| RemoteTerminationUnconfirmed\n\t\t| RpcClientError.RpcClientError\n\t>\n\treadonly transport: {\n\t\treadonly clientProtocol: Peer[\"clientProtocol\"]\n\t\treadonly serverProtocol: Peer[\"serverProtocol\"]\n\t\treadonly failure: Effect.Effect<never, ProcessExited | TransportError>\n\t\treadonly report: (cause: Cause.Cause<unknown>) => Effect.Effect<void>\n\t}\n}\nexport class Connection extends Context.Service<Connection, Connected>()(\n\t\"@graftland/plugin-remote/internal/runner/Connection\",\n) {}\nconst connected = Connection.of\n\nconst Local = Effect.fnUntraced(function* (\n\ttarget: LocalTarget | WorkerTarget,\n\tcontractModule: string,\n\toptions: Port.Options,\n\tresources: Scope.Scope,\n\tprocessScope: Scope.Scope,\n) {\n\tconst transport = yield* target._tag === \"Local\"\n\t\t? LocalTransport\n\t\t: WorkerTransport\n\tconst started: Effect.Effect<\n\t\tExecution,\n\t\tPlatformError.PlatformError | TransportError,\n\t\tScope.Scope\n\t> = transport.start({ ...target, contractModule, session: options.session })\n\tconst execution = yield* started.pipe(Scope.provide(processScope))\n\treturn yield* LocalProcess.connect(execution, options).pipe(\n\t\tScope.provide(resources),\n\t)\n})\n\nconst reason = <A, E>(exit: Exit.Exit<A, E>) =>\n\tExit.isFailure(exit) ? exit.cause : Cause.empty\nconst finish = (causes: ReadonlyArray<Cause.Cause<unknown>>) => {\n\tconst cause = Array.reduce(causes, Cause.empty, Cause.combine)\n\treturn cause.reasons.length === 0\n\t\t? Effect.void\n\t\t: Effect.failCause(cleanupCause(cause))\n}\n\n/** Close partially acquired resources too; the normal release observes exit before stopping readers. */\nconst scopes = Effect.acquireRelease(\n\tEffect.all({ resources: Scope.make(), process: Scope.make() }),\n\
|
|
1
|
+
{"version":3,"file":"Connection.js","names":["LocalProcess.connect","Release.close","RunnerConnection.connect"],"sources":["../../../src/internal/runner/Connection.ts"],"sourcesContent":["import {\n\tLocalTransport,\n\tWorkerTransport,\n\ttype Execution,\n} from \"../directTransport\"\nimport * as RunnerConnection from \"../host/runner\"\nimport {\n\tArray,\n\tCause,\n\tContext,\n\tEffect,\n\tDuration,\n\tExit,\n\tOption,\n\tScope,\n} from \"effect\"\nimport * as Release from \"../release\"\nimport type { RpcClientError } from \"effect/rpc\"\nimport type { Schema, PlatformError } from \"effect\"\nimport type { RemoteTerminationUnconfirmed } from \"./model\"\nimport type { Expected } from \"./Packages\"\n\nimport {\n\tLocalTerminationTimeout,\n\tProcessExited,\n\tTransportError,\n} from \"../../Errors\"\nimport { cleanupCause } from \"../cleanup\"\nimport * as Port from \"../port\"\nimport * as LocalProcess from \"./Local\"\nimport * as Wire from \"./Wire\"\n\nexport interface LocalTarget {\n\treadonly _tag: \"Local\"\n\treadonly command?: readonly [string, ...string[]]\n}\nexport interface WorkerTarget {\n\treadonly _tag: \"Worker\"\n\treadonly execArgv?: ReadonlyArray<string>\n}\n\nexport interface ConfiguredRunner {\n\treadonly instance: string\n\treadonly lease?: Duration.Input\n\treadonly margin?: Duration.Input\n\treadonly expect?: Expected\n\treadonly _tag: \"Connector\"\n\treadonly explicitAuth?: boolean\n}\nexport type Target = LocalTarget | WorkerTarget | ConfiguredRunner\n\ntype Peer = Port.Port\nexport interface Connected {\n\treadonly resources: Scope.Scope\n\treadonly pid: Option.Option<number>\n\treadonly threadId?: number\n\treadonly diagnostics: Effect.Effect<Cause.Cause<unknown>>\n\treadonly terminate: (\n\t\tgraceful: boolean,\n\t) => Effect.Effect<\n\t\tvoid,\n\t\t| ProcessExited\n\t\t| LocalTerminationTimeout\n\t\t| TransportError\n\t\t| Schema.SchemaError\n\t\t| Wire.SessionError\n\t\t| RemoteTerminationUnconfirmed\n\t\t| RpcClientError.RpcClientError\n\t>\n\treadonly transport: {\n\t\treadonly clientProtocol: Peer[\"clientProtocol\"]\n\t\treadonly serverProtocol: Peer[\"serverProtocol\"]\n\t\treadonly failure: Effect.Effect<never, ProcessExited | TransportError>\n\t\treadonly report: (cause: Cause.Cause<unknown>) => Effect.Effect<void>\n\t}\n}\nexport class Connection extends Context.Service<Connection, Connected>()(\n\t\"@graftland/plugin-remote/internal/runner/Connection\",\n) {}\nconst connected = Connection.of\n\nconst Local = Effect.fnUntraced(function* (\n\ttarget: LocalTarget | WorkerTarget,\n\tcontractModule: string,\n\toptions: Port.Options,\n\tresources: Scope.Scope,\n\tprocessScope: Scope.Scope,\n) {\n\tconst transport = yield* target._tag === \"Local\"\n\t\t? LocalTransport\n\t\t: WorkerTransport\n\tconst started: Effect.Effect<\n\t\tExecution,\n\t\tPlatformError.PlatformError | TransportError,\n\t\tScope.Scope\n\t> = transport.start({ ...target, contractModule, session: options.session })\n\tconst execution = yield* started.pipe(Scope.provide(processScope))\n\treturn yield* LocalProcess.connect(execution, options).pipe(\n\t\tScope.provide(resources),\n\t)\n})\n\nconst reason = <A, E>(exit: Exit.Exit<A, E>) =>\n\tExit.isFailure(exit) ? exit.cause : Cause.empty\nconst finish = (causes: ReadonlyArray<Cause.Cause<unknown>>) => {\n\tconst cause = Array.reduce(causes, Cause.empty, Cause.combine)\n\treturn cause.reasons.length === 0\n\t\t? Effect.void\n\t\t: Effect.failCause(cleanupCause(cause))\n}\n\n/** Close partially acquired resources too; the normal release observes exit before stopping readers. */\nconst scopes = Effect.acquireRelease(\n\tEffect.all({ resources: Scope.make(), process: Scope.make() }),\n\tEffect.fnUntraced(function* (scopes, exit) {\n\t\tconst process = yield* Effect.exit(Release.close(scopes.process, exit))\n\t\tconst resources = yield* Effect.exit(Release.close(scopes.resources, exit))\n\t\tyield* finish([reason(process), reason(resources)])\n\t}),\n)\n\n/** Setup supplies a concrete control lifecycle; release never reads a later-installed effect. */\nexport const acquire = Effect.fnUntraced(function* <A, E, R, D, DR>(\n\ttarget: Target,\n\tcontractModule: string,\n\toptions: Port.Options,\n\tsetup: Effect.Effect<A, E, R | Connection>,\n\tdispose: (value: A) => Effect.Effect<Cause.Cause<unknown>, D, DR>,\n\ttimeout: Duration.Input,\n) {\n\tconst owned = yield* scopes\n\tconst connection = yield* Effect.acquireRelease(\n\t\tEffect.gen(function* () {\n\t\t\treturn target._tag === \"Local\" || target._tag === \"Worker\"\n\t\t\t\t? yield* Local(\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tcontractModule,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\towned.resources,\n\t\t\t\t\t\towned.process,\n\t\t\t\t\t).pipe(Effect.map(connected))\n\t\t\t\t: yield* RunnerConnection.connect(\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tcontractModule,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\towned.resources,\n\t\t\t\t\t\towned.process,\n\t\t\t\t\t)\n\t\t}).pipe(Effect.interruptible),\n\t\tEffect.fnUntraced(function* (connection, exit) {\n\t\t\tconst process = yield* Effect.exit(Release.close(owned.process, exit))\n\t\t\t// Wait for exit while readers are alive; collect their final cause after resources close.\n\t\t\tyield* connection.diagnostics\n\t\t\tconst resources = yield* Effect.exit(Release.close(owned.resources, exit))\n\t\t\tconst diagnostics = yield* connection.diagnostics\n\t\t\tyield* finish([reason(process), reason(resources), diagnostics])\n\t\t}),\n\t)\n\treturn yield* Effect.acquireRelease(\n\t\tsetup.pipe(Effect.provideService(Connection, connection)),\n\t\tEffect.fnUntraced(function* (value) {\n\t\t\tconst graceful = yield* dispose(value).pipe(\n\t\t\t\tEffect.interruptible,\n\t\t\t\tEffect.timeout(timeout),\n\t\t\t\tEffect.exit,\n\t\t\t)\n\t\t\tconst terminated = yield* Effect.exit(\n\t\t\t\tconnection.terminate(Exit.isSuccess(graceful)),\n\t\t\t)\n\t\t\tyield* finish([\n\t\t\t\tExit.isSuccess(graceful) ? graceful.value : graceful.cause,\n\t\t\t\treason(terminated),\n\t\t\t])\n\t\t}),\n\t)\n})\n"],"mappings":";;;;;;;AA4EA,IAAa,aAAb,cAAgC,QAAQ,QAA+B,CAAC,CACvE,qDACD,CAAC,CAAC,CAAC;AACH,MAAM,YAAY,WAAW;AAE7B,MAAM,QAAQ,OAAO,WAAW,WAC/B,QACA,gBACA,SACA,WACA,cACC;CASD,MAAM,YAAY,QADd,OAPqB,OAAO,SAAS,UACtC,iBACA,gBAAA,CAKW,MAAM;EAAE,GAAG;EAAQ;EAAgB,SAAS,QAAQ;CAAQ,CAC3C,CAAC,CAAC,KAAK,MAAM,QAAQ,YAAY,CAAC;CACjE,OAAO,OAAOA,UAAqB,WAAW,OAAO,CAAC,CAAC,KACtD,MAAM,QAAQ,SAAS,CACxB;AACD,CAAC;AAED,MAAM,UAAgB,SACrB,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,MAAM;AAC3C,MAAM,UAAU,WAAgD;CAC/D,MAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM,OAAO,MAAM,OAAO;CAC7D,OAAO,MAAM,QAAQ,WAAW,IAC7B,OAAO,OACP,OAAO,UAAU,aAAa,KAAK,CAAC;AACxC;;AAGA,MAAM,SAAS,OAAO,eACrB,OAAO,IAAI;CAAE,WAAW,MAAM,KAAK;CAAG,SAAS,MAAM,KAAK;AAAE,CAAC,GAC7D,OAAO,WAAW,WAAW,QAAQ,MAAM;CAC1C,MAAM,UAAU,OAAO,OAAO,KAAKC,MAAc,OAAO,SAAS,IAAI,CAAC;CACtE,MAAM,YAAY,OAAO,OAAO,KAAKA,MAAc,OAAO,WAAW,IAAI,CAAC;CAC1E,OAAO,OAAO,CAAC,OAAO,OAAO,GAAG,OAAO,SAAS,CAAC,CAAC;AACnD,CAAC,CACF;;AAGA,MAAa,UAAU,OAAO,WAAW,WACxC,QACA,gBACA,SACA,OACA,SACA,SACC;CACD,MAAM,QAAQ,OAAO;CACrB,MAAM,aAAa,OAAO,OAAO,eAChC,OAAO,IAAI,aAAa;EACvB,OAAO,OAAO,SAAS,WAAW,OAAO,SAAS,WAC/C,OAAO,MACP,QACA,gBACA,SACA,MAAM,WACN,MAAM,OACP,CAAC,CAAC,KAAK,OAAO,IAAI,SAAS,CAAC,IAC3B,OAAOC,QACP,QACA,gBACA,SACA,MAAM,WACN,MAAM,OACP;CACH,CAAC,CAAC,CAAC,KAAK,OAAO,aAAa,GAC5B,OAAO,WAAW,WAAW,YAAY,MAAM;EAC9C,MAAM,UAAU,OAAO,OAAO,KAAKD,MAAc,MAAM,SAAS,IAAI,CAAC;EAErE,OAAO,WAAW;EAClB,MAAM,YAAY,OAAO,OAAO,KAAKA,MAAc,MAAM,WAAW,IAAI,CAAC;EACzE,MAAM,cAAc,OAAO,WAAW;EACtC,OAAO,OAAO;GAAC,OAAO,OAAO;GAAG,OAAO,SAAS;GAAG;EAAW,CAAC;CAChE,CAAC,CACF;CACA,OAAO,OAAO,OAAO,eACpB,MAAM,KAAK,OAAO,eAAe,YAAY,UAAU,CAAC,GACxD,OAAO,WAAW,WAAW,OAAO;EACnC,MAAM,WAAW,OAAO,QAAQ,KAAK,CAAC,CAAC,KACtC,OAAO,eACP,OAAO,QAAQ,OAAO,GACtB,OAAO,IACR;EACA,MAAM,aAAa,OAAO,OAAO,KAChC,WAAW,UAAU,KAAK,UAAU,QAAQ,CAAC,CAC9C;EACA,OAAO,OAAO,CACb,KAAK,UAAU,QAAQ,IAAI,SAAS,QAAQ,SAAS,OACrD,OAAO,UAAU,CAClB,CAAC;CACF,CAAC,CACF;AACD,CAAC"}
|
|
@@ -12,7 +12,7 @@ import { Array, Cause, Context, Effect, FileSystem, HashMap, HashSet, Layer, Pat
|
|
|
12
12
|
import { ChildProcess, ChildProcessSpawner } from "effect/process";
|
|
13
13
|
// src/internal/runner/Execution.ts
|
|
14
14
|
var Channels = class extends Context.Service()("@graftland/plugin-remote/internal/runner/Execution/Channels") {};
|
|
15
|
-
const make =
|
|
15
|
+
const make = Effect.fnUntraced(function* (root) {
|
|
16
16
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
17
17
|
const fs = yield* FileSystem.FileSystem;
|
|
18
18
|
const path = yield* Path.Path;
|
|
@@ -22,7 +22,7 @@ const make = (root) => Effect.gen(function* () {
|
|
|
22
22
|
return {
|
|
23
23
|
driver: Execution.of({
|
|
24
24
|
recover: (child) => recover(child).pipe(Effect.provideContext(platform)),
|
|
25
|
-
spawn: (handle, request, limits)
|
|
25
|
+
spawn: Effect.fnUntraced(function* (handle, request, limits) {
|
|
26
26
|
const resolved = yield* resolve(root, request.specifier, request.digest);
|
|
27
27
|
const argv = yield* command();
|
|
28
28
|
const child = yield* spawner.spawn(ChildProcess.make(argv[0], [
|
|
@@ -88,7 +88,7 @@ const make = (root) => Effect.gen(function* () {
|
|
|
88
88
|
millis
|
|
89
89
|
})
|
|
90
90
|
};
|
|
91
|
-
}
|
|
91
|
+
}, Effect.provideContext(platform), Effect.catchTags({
|
|
92
92
|
PlatformError: (error) => Effect.fail(ExecutionError.make({
|
|
93
93
|
detail: "Starting the child failed",
|
|
94
94
|
cause: Cause.fail(error)
|