@graftland/plugin-remote 0.2.0-beta.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/{Bootstrap-MCwivGN1.js → Bootstrap-Dr6sX7el.js} +2 -2
  2. package/dist/{Contract-CcpSIJm4.js → Contract-DL2mHvaT.js} +8 -46
  3. package/dist/Contract.d.ts +50 -53
  4. package/dist/Contract.d.ts.map +1 -1
  5. package/dist/Contract.js +1 -1
  6. package/dist/Contract.js.map +1 -1
  7. package/dist/{Errors-oPsTLY7l.js → Errors-BMKmu5Y7.js} +12 -1
  8. package/dist/Errors.d.ts +12 -0
  9. package/dist/Errors.d.ts.map +1 -1
  10. package/dist/Errors.js +12 -1
  11. package/dist/Errors.js.map +1 -1
  12. package/dist/{Graft-BsYq3F-J.js → Graft-CVyueNOf.js} +26 -19
  13. package/dist/{Packages-B1TPk8pa.js → Packages-JNL34JpS.js} +1 -1
  14. package/dist/{Peer-IJgFK6mD.js → Peer-BT7eAGmh.js} +2 -2
  15. package/dist/Testing.d.ts +4 -4
  16. package/dist/Testing.d.ts.map +1 -1
  17. package/dist/Testing.js +10 -4
  18. package/dist/Testing.js.map +1 -1
  19. package/dist/bin.js +7 -7
  20. package/dist/{childRuntime-DSqtFN9o.js → childRuntime-An0HsIzl.js} +7 -6
  21. package/dist/{cleanup-BPWr-5U9.js → cleanup-CXLa1Wd9.js} +1 -1
  22. package/dist/connectionEnded-DCpFCjMX.js +54 -0
  23. package/dist/{entry-SYsx9VNb.js → entry-B89sepMU.js} +13 -22
  24. package/dist/host/auth/bearer.d.ts +1 -2
  25. package/dist/host/auth/bearer.d.ts.map +1 -1
  26. package/dist/host/auth/bearer.js +1 -1
  27. package/dist/host/auth/bearer.js.map +1 -1
  28. package/dist/host/auth/jwt.d.ts +1 -2
  29. package/dist/host/auth/jwt.d.ts.map +1 -1
  30. package/dist/host/auth/jwt.js +1 -1
  31. package/dist/host/auth/jwt.js.map +1 -1
  32. package/dist/host/auth/mtls.js +2 -2
  33. package/dist/host/auth/none.js +1 -1
  34. package/dist/host/command.d.ts +1 -1
  35. package/dist/host/command.d.ts.map +1 -1
  36. package/dist/host/command.js +3 -3
  37. package/dist/host/command.js.map +1 -1
  38. package/dist/host/local.d.ts +1 -2
  39. package/dist/host/local.d.ts.map +1 -1
  40. package/dist/host/local.js +2 -2
  41. package/dist/host/local.js.map +1 -1
  42. package/dist/host/unix.d.ts +1 -1
  43. package/dist/host/unix.d.ts.map +1 -1
  44. package/dist/host/unix.js +3 -3
  45. package/dist/host/unix.js.map +1 -1
  46. package/dist/host/websocket.d.ts +1 -1
  47. package/dist/host/websocket.d.ts.map +1 -1
  48. package/dist/host/websocket.js +3 -3
  49. package/dist/host/websocket.js.map +1 -1
  50. package/dist/host/worker.d.ts +1 -2
  51. package/dist/host/worker.d.ts.map +1 -1
  52. package/dist/host/worker.js +4 -4
  53. package/dist/host/worker.js.map +1 -1
  54. package/dist/{importer-D7zSgqxq.js → importer-Bk6U_sn4.js} +1 -1
  55. package/dist/index.d.ts +2 -3
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +8 -8
  58. package/dist/index.js.map +1 -1
  59. package/dist/internal/auth/tokenCredentials.d.ts +0 -1
  60. package/dist/internal/auth/tokenCredentials.d.ts.map +1 -1
  61. package/dist/internal/auth/tokenCredentials.js.map +1 -1
  62. package/dist/internal/child.js.map +1 -1
  63. package/dist/internal/childRuntime.js +3 -1
  64. package/dist/internal/childRuntime.js.map +1 -1
  65. package/dist/internal/contract.js +26 -0
  66. package/dist/internal/contract.js.map +1 -0
  67. package/dist/internal/credentials.d.ts +6 -6
  68. package/dist/internal/credentials.d.ts.map +1 -1
  69. package/dist/internal/credentials.js.map +1 -1
  70. package/dist/internal/entry.d.ts +1 -2
  71. package/dist/internal/entry.d.ts.map +1 -1
  72. package/dist/internal/entry.js +3 -13
  73. package/dist/internal/entry.js.map +1 -1
  74. package/dist/internal/execution.js +4 -2
  75. package/dist/internal/execution.js.map +1 -1
  76. package/dist/internal/host.js.map +1 -1
  77. package/dist/internal/port.d.ts +2 -10
  78. package/dist/internal/runner/Framing.d.ts +1 -11
  79. package/dist/internal/services.d.ts +2 -12
  80. package/dist/internal/services.d.ts.map +1 -1
  81. package/dist/internal/services.js.map +1 -1
  82. package/dist/internal/supervisorPlugin.js +1 -1
  83. package/dist/internal/workerMain.js +3 -3
  84. package/dist/{port-Blbh8tms.js → port-DSVUY8Bq.js} +1 -1
  85. package/dist/runner/auth/bearer.js +2 -2
  86. package/dist/runner/auth/jwt.js +3 -3
  87. package/dist/runner/auth/mtls.js +2 -2
  88. package/dist/runner/auth/none.js +1 -1
  89. package/dist/runner/index.js +5 -5
  90. package/dist/runner/stdio.js +2 -2
  91. package/dist/runner/unix.js +3 -3
  92. package/dist/runner/websocket.js +4 -4
  93. package/dist/{socketChannel-KmtzF-9G.js → socketChannel-C_ppdSzz.js} +1 -1
  94. package/dist/{supervisorPlugin-Inb1S5IV.js → supervisorPlugin-CivhM7x5.js} +7 -7
  95. package/dist/{token-v5ne2I0-.js → token-Cc_1CTbE.js} +1 -1
  96. package/dist/{tokenCredentials-WUJm2AKm.js → tokenCredentials-CI6mMRRd.js} +3 -3
  97. package/dist/{websocketServer-MXcCJx0v.js → websocketServer-D2Hk7wsA.js} +2 -2
  98. package/dist/{workerChannel-P82YdNjh.js → workerChannel-cmLc13vm.js} +1 -1
  99. package/package.json +3 -3
  100. package/src/Contract.ts +67 -51
  101. package/src/Errors.ts +15 -0
  102. package/src/Testing.ts +16 -2
  103. package/src/host/auth/bearer.ts +1 -6
  104. package/src/host/auth/jwt.ts +1 -6
  105. package/src/host/command.ts +2 -0
  106. package/src/host/local.ts +5 -9
  107. package/src/host/unix.ts +2 -0
  108. package/src/host/websocket.ts +2 -0
  109. package/src/host/worker.ts +4 -6
  110. package/src/index.ts +3 -1
  111. package/src/internal/auth/tokenCredentials.ts +1 -7
  112. package/src/internal/child.ts +1 -1
  113. package/src/internal/childRuntime.ts +4 -2
  114. package/src/internal/contract.ts +47 -0
  115. package/src/internal/credentials.ts +12 -9
  116. package/src/internal/entry.ts +1 -14
  117. package/src/internal/execution.ts +4 -2
  118. package/src/internal/host.ts +8 -11
  119. package/src/internal/services.ts +1 -19
  120. package/dist/connectionEnded-DUgcobEd.js +0 -9
  121. package/dist/internal/childErrors.d.ts +0 -33
  122. package/dist/internal/childErrors.d.ts.map +0 -1
  123. package/dist/internal/port.d.ts.map +0 -1
  124. package/dist/internal/runner/Framing.d.ts.map +0 -1
@@ -1,8 +1,8 @@
1
- import { a as provide, l as make } from "../../Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make } from "../../Graft-CVyueNOf.js";
2
2
  import { t as Authenticator } from "../../Auth-BElTC9_X.js";
3
3
  import { t as ConfigDirectory } from "../../ConfigDirectory-BCC6q2R4.js";
4
- import { t as AuthenticationFailed } from "../../Errors-oPsTLY7l.js";
5
- import { r as read } from "../../token-v5ne2I0-.js";
4
+ import { t as AuthenticationFailed } from "../../Errors-BMKmu5Y7.js";
5
+ import { r as read } from "../../token-Cc_1CTbE.js";
6
6
  import { Cause, Duration, Effect, FileSystem, Layer, Option, Path, Schema } from "effect";
7
7
  import { Signature } from "effect/crypto";
8
8
  import { HttpClient } from "effect/http";
@@ -1,7 +1,7 @@
1
- import { a as provide, l as make$1 } from "../../Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make$1 } from "../../Graft-CVyueNOf.js";
2
2
  import { t as Authenticator } from "../../Auth-BElTC9_X.js";
3
3
  import { t as ConfigDirectory } from "../../ConfigDirectory-BCC6q2R4.js";
4
- import { t as AuthenticationFailed } from "../../Errors-oPsTLY7l.js";
4
+ import { t as AuthenticationFailed } from "../../Errors-BMKmu5Y7.js";
5
5
  import { Array, Cause, Effect, FileSystem, Option, Path, Schema, String } from "effect";
6
6
  // packages/remote/src/internal/auth/mtls.ts
7
7
  const uriValue = (field) => {
@@ -1,4 +1,4 @@
1
- import { a as provide, l as make } from "../../Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make } from "../../Graft-CVyueNOf.js";
2
2
  import { t as Authenticator } from "../../Auth-BElTC9_X.js";
3
3
  import { Effect, Schema } from "effect";
4
4
  // packages/remote/src/runner/auth/none.ts
@@ -1,8 +1,8 @@
1
- import { i as plugin, l as make, o as fork } from "../Graft-BsYq3F-J.js";
2
- import { r as ModuleResolver } from "../importer-D7zSgqxq.js";
3
- import { c as directAuth, d as follow, h as runnerTransport, i as resolve, l as makeListenerConsumer, m as runnerAuthentication, o as CapabilityCombinationError, p as Runner, s as CapabilityFailed, t as boundary, u as runner } from "../entry-SYsx9VNb.js";
4
- import { i as Supervisor } from "../Packages-B1TPk8pa.js";
5
- import { n as supervisorPlugin_default, t as Config$1 } from "../supervisorPlugin-Inb1S5IV.js";
1
+ import { i as plugin, l as make, o as fork } from "../Graft-CVyueNOf.js";
2
+ import { r as ModuleResolver } from "../importer-Bk6U_sn4.js";
3
+ import { c as directAuth, d as follow, h as runnerTransport, i as resolve, l as makeListenerConsumer, m as runnerAuthentication, o as CapabilityCombinationError, p as Runner, s as CapabilityFailed, t as boundary, u as runner } from "../entry-B89sepMU.js";
4
+ import { i as Supervisor } from "../Packages-JNL34JpS.js";
5
+ import { n as supervisorPlugin_default, t as Config$1 } from "../supervisorPlugin-CivhM7x5.js";
6
6
  import { Array, Deferred, Effect, HashSet, Option, Path, Schema, Stream } from "effect";
7
7
  import { SecureRandom } from "effect/crypto";
8
8
  // packages/remote/src/internal/listenerStartup.ts
@@ -1,6 +1,6 @@
1
- import { a as provide, l as make } from "../Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make } from "../Graft-CVyueNOf.js";
2
2
  import { n as Listener } from "../Transport-DULzpsgR.js";
3
- import { c as TransportError } from "../Errors-oPsTLY7l.js";
3
+ import { l as TransportError } from "../Errors-BMKmu5Y7.js";
4
4
  import { r as scoped } from "../release-BY4Mlluy.js";
5
5
  import { Cause, Deferred, Effect, Exit, Option, Schema, Sink, Stdio, Stream } from "effect";
6
6
  // packages/remote/src/runner/stdio.ts
@@ -1,8 +1,8 @@
1
- import { a as provide, l as make } from "../Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make } from "../Graft-CVyueNOf.js";
2
2
  import { t as ConfigDirectory } from "../ConfigDirectory-BCC6q2R4.js";
3
3
  import { n as Listener } from "../Transport-DULzpsgR.js";
4
- import { c as TransportError } from "../Errors-oPsTLY7l.js";
5
- import { t as bind } from "../websocketServer-MXcCJx0v.js";
4
+ import { l as TransportError } from "../Errors-BMKmu5Y7.js";
5
+ import { t as bind } from "../websocketServer-D2Hk7wsA.js";
6
6
  import { Cause, Console, Effect, Option, Path, Schema } from "effect";
7
7
  import { createServer } from "node:http";
8
8
  // packages/remote/src/runner/unix.ts
@@ -1,9 +1,9 @@
1
- import { a as provide, l as make } from "../Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make } from "../Graft-CVyueNOf.js";
2
2
  import { t as ConfigDirectory } from "../ConfigDirectory-BCC6q2R4.js";
3
- import { n as Url, o as properties } from "../socketChannel-KmtzF-9G.js";
3
+ import { n as Url, o as properties } from "../socketChannel-C_ppdSzz.js";
4
4
  import { n as Listener } from "../Transport-DULzpsgR.js";
5
- import { c as TransportError } from "../Errors-oPsTLY7l.js";
6
- import { t as bind } from "../websocketServer-MXcCJx0v.js";
5
+ import { l as TransportError } from "../Errors-BMKmu5Y7.js";
6
+ import { t as bind } from "../websocketServer-D2Hk7wsA.js";
7
7
  import { Cause, Console, Effect, FileSystem, Option, Path, Schema, String } from "effect";
8
8
  import { createSecureServer } from "node:http2";
9
9
  import { createServer } from "node:http";
@@ -1,5 +1,5 @@
1
1
  import { i as __toESM, r as __require, t as __commonJSMin } from "./rolldown-runtime-DYf_mQCB.js";
2
- import { c as TransportError } from "./Errors-oPsTLY7l.js";
2
+ import { l as TransportError } from "./Errors-BMKmu5Y7.js";
3
3
  import { a as isCompleteFrame, i as encode, n as FrameError, o as maxPayload, r as decoder } from "./Framing-zaYdOJnT.js";
4
4
  import { Array as Array$1, Cause, Effect, Exit, Layer, Redacted, Schema, Sink, Stream } from "effect";
5
5
  import { Socket } from "effect/socket";
@@ -1,16 +1,16 @@
1
- import { a as provide, l as make$2, o as fork, u as optional } from "./Graft-BsYq3F-J.js";
2
- import { a as PositiveDuration, i as Supervisor$1, t as resolve } from "./Packages-B1TPk8pa.js";
1
+ import { a as provide, l as make$2, o as fork, u as optional } from "./Graft-CVyueNOf.js";
2
+ import { a as PositiveDuration, i as Supervisor$1, t as resolve } from "./Packages-JNL34JpS.js";
3
3
  import { t as ConfigDirectory } from "./ConfigDirectory-BCC6q2R4.js";
4
- import { C as negotiate, E as make$3, S as keyOf, T as stoppingRecord, _ as StateStorageError, a as ExecutionError, d as SessionAccessDenied, f as SessionConflict, g as StateDirectoryLocked, h as StaleSession, i as Execution, m as SessionStopped, n as Session$1, o as Key, p as SessionRecord, r as channel, s as LeaseExpired, t as Peer, u as RunnerClosing, v as Store, w as stoppedRecord, x as childOf, y as TerminationUnconfirmed } from "./Peer-IJgFK6mD.js";
4
+ import { C as negotiate, E as make$3, S as keyOf, T as stoppingRecord, _ as StateStorageError, a as ExecutionError, d as SessionAccessDenied, f as SessionConflict, g as StateDirectoryLocked, h as StaleSession, i as Execution, m as SessionStopped, n as Session$1, o as Key, p as SessionRecord, r as channel, s as LeaseExpired, t as Peer, u as RunnerClosing, v as Store, w as stoppedRecord, x as childOf, y as TerminationUnconfirmed } from "./Peer-BT7eAGmh.js";
5
5
  import { t as observe } from "./ProcessObservation-DEGrEMfP.js";
6
6
  import { t as make$4 } from "./FailureGroup-BcH0XOBi.js";
7
7
  import { t as CommandJson } from "./WatchdogProtocol-BZmVxrBP.js";
8
- import { c as TransportError } from "./Errors-oPsTLY7l.js";
9
- import { t as Bootstrap } from "./Bootstrap-MCwivGN1.js";
8
+ import { l as TransportError } from "./Errors-BMKmu5Y7.js";
9
+ import { t as Bootstrap } from "./Bootstrap-Dr6sX7el.js";
10
10
  import { t as command } from "./command-9zrHdbwT.js";
11
11
  import { n as close } from "./release-BY4Mlluy.js";
12
- import { n as cleanupCause } from "./cleanup-BPWr-5U9.js";
13
- import { n as make$5, o as defaults } from "./port-Blbh8tms.js";
12
+ import { n as cleanupCause } from "./cleanup-CXLa1Wd9.js";
13
+ import { n as make$5, o as defaults } from "./port-DSVUY8Bq.js";
14
14
  import { i as resources, t as ServeLifecycle } from "./ServeLifecycle-CJM0gG5B.js";
15
15
  import { Array, Cause, Clock, Context, Data, Deferred, Duration, Effect, Equal, Exit, FiberHandle, FiberSet, FileSystem, HashMap, HashSet, Layer, Option, Path, Queue, RcMap, Ref, Result, Schedule, Schema, Scope, Semaphore, Sink, Stream, String, SynchronizedRef } from "effect";
16
16
  import process from "node:process";
@@ -1,4 +1,4 @@
1
- import { t as AuthenticationFailed } from "./Errors-oPsTLY7l.js";
1
+ import { t as AuthenticationFailed } from "./Errors-BMKmu5Y7.js";
2
2
  import { Effect, Option, Redacted } from "effect";
3
3
  // packages/remote/src/internal/auth/token.ts
4
4
  const invalid = () => AuthenticationFailed.make({
@@ -1,8 +1,8 @@
1
- import { a as provide, l as make } from "./Graft-BsYq3F-J.js";
1
+ import { a as provide, l as make } from "./Graft-CVyueNOf.js";
2
2
  import { t as ConfigDirectory } from "./ConfigDirectory-BCC6q2R4.js";
3
3
  import { n as Credentials } from "./Auth-BElTC9_X.js";
4
- import { n as CredentialsError } from "./Errors-oPsTLY7l.js";
5
- import { n as prepare } from "./token-v5ne2I0-.js";
4
+ import { n as CredentialsError } from "./Errors-BMKmu5Y7.js";
5
+ import { n as prepare } from "./token-Cc_1CTbE.js";
6
6
  import { Cause, Effect, FileSystem, Option, Path, Redacted, Schema } from "effect";
7
7
  // packages/remote/src/internal/auth/tokenCredentials.ts
8
8
  const Config$1 = Schema.Struct({ token: Schema.Union([Schema.RedactedFromValue(Schema.String), Schema.Struct({ file: Schema.String })]) });
@@ -1,5 +1,5 @@
1
- import { c as TransportError } from "./Errors-oPsTLY7l.js";
2
- import { a as payloadLimit, s as protocol, t as fromSocket } from "./socketChannel-KmtzF-9G.js";
1
+ import { l as TransportError } from "./Errors-BMKmu5Y7.js";
2
+ import { a as payloadLimit, s as protocol, t as fromSocket } from "./socketChannel-C_ppdSzz.js";
3
3
  import { Array, Cause, Deferred, Effect, Option, Redacted, Scope, String } from "effect";
4
4
  import { NodeHttpServer, NodeHttpServerRequest } from "@effect/platform-node";
5
5
  import { HttpServerRequest, HttpServerResponse } from "effect/http";
@@ -1,4 +1,4 @@
1
- import { c as TransportError } from "./Errors-oPsTLY7l.js";
1
+ import { l as TransportError } from "./Errors-BMKmu5Y7.js";
2
2
  import { Cause, Effect, FiberSet, Queue, Schema, Sink, Stream } from "effect";
3
3
  // packages/remote/src/internal/workerBootstrap.ts
4
4
  const Bootstrap = Schema.Struct({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graftland/plugin-remote",
3
- "version": "0.2.0-beta.2",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Local and authenticated network execution for Graft plugins",
6
6
  "license": "Apache-2.0",
@@ -49,9 +49,9 @@
49
49
  "effect": "4.1.*"
50
50
  },
51
51
  "dependencies": {
52
- "@graftland/graft": "0.2.0-beta.2",
52
+ "@graftland/graft": "0.3.1",
53
53
  "@effect/platform-node": "4.1.2",
54
- "@graftland/loader": "0.2.0-beta.2",
54
+ "@graftland/loader": "0.3.1",
55
55
  "pkijs": "4.0.1",
56
56
  "asn1js": "4.0.0",
57
57
  "ws": "8.22.1"
package/src/Contract.ts CHANGED
@@ -1,38 +1,79 @@
1
- import { ChildFailure } from "./internal/childErrors"
2
- export { ChildFailure }
3
- import { Array, Cause, Predicate, Schema } from "effect"
4
-
5
- import type { Service } from "./internal/services"
1
+ import { Array, Predicate, Schema } from "effect"
2
+ import type { Context, Effect, Scope } from "effect"
3
+ import type { Graft } from "@graftland/graft"
4
+ import type { Rpc, RpcClient, RpcGroup, RpcServer } from "effect/rpc"
6
5
  import * as Control from "./internal/control"
7
6
  export { service } from "./internal/services"
8
7
 
9
8
  const TypeId = "~@graftland/plugin-remote/Contract"
10
9
 
11
- /** An undeclared failure still crosses the boundary, with its diagnostic value. */
12
- export class UndeclaredFailure extends Schema.TaggedError<
13
- UndeclaredFailure,
14
- { readonly brand: unique symbol }
15
- >()("UndeclaredFailure", { original: Schema.Defect({ includeStack: true }) }) {}
10
+ /** RPC types stay inside the descriptor; Graft supplies its dynamic activation context. */
11
+ export interface Service<R = never, ClientR = never> {
12
+ readonly key: Context.Key<unknown, unknown>
13
+ readonly group: Pick<RpcGroup.RpcGroup<Rpc.Any>, "requests">
14
+ readonly serve: (port: {
15
+ readonly serverProtocol: (endpoint: string) => RpcServer.Protocol["Service"]
16
+ }) => Effect.Effect<never, never, R>
17
+ readonly publish: (port: {
18
+ readonly clientProtocol: (endpoint: string) => RpcClient.Protocol["Service"]
19
+ }) => Effect.Effect<
20
+ void,
21
+ Graft.ServiceConflict,
22
+ Graft.Graft | Scope.Scope | ClientR
23
+ >
24
+ }
16
25
 
17
- /** Pure metadata shared by the host and the executable runner bootstrap. */
18
- export const make = <
19
- S extends Schema.Top & {
20
- readonly Encoded: Schema.Json
21
- readonly DecodingServices: never
22
- readonly EncodingServices: never
23
- },
24
- E extends Schema.Top & {
25
- readonly DecodingServices: never
26
- readonly EncodingServices: never
27
- },
28
- >(options: {
26
+ /** A self-contained configuration schema that encodes as JSON. */
27
+ export type ConfigSchema = Schema.Top & {
28
+ readonly Encoded: Schema.Json
29
+ readonly DecodingServices: never
30
+ readonly EncodingServices: never
31
+ }
32
+ /** A self-contained schema for declared failures. */
33
+ export type ErrorSchema = Schema.Top & {
34
+ readonly DecodingServices: never
35
+ readonly EncodingServices: never
36
+ }
37
+
38
+ /** The shared configuration and service declarations for one remote plugin. */
39
+ export interface Contract<
40
+ S extends ConfigSchema,
41
+ E extends ErrorSchema = typeof Schema.Never,
42
+ > {
29
43
  readonly name: string
30
44
  readonly config: S
31
45
  readonly error: E
32
46
  readonly module: string
47
+ readonly inject: ReadonlyArray<Service>
48
+ readonly provides: ReadonlyArray<Service>
49
+ readonly [TypeId]: typeof TypeId
50
+ }
51
+ /** Configuration accepted by make; omitted errors default to Never. */
52
+ export interface Options<S extends ConfigSchema, E extends ErrorSchema> {
53
+ readonly name: string
54
+ readonly config: S
55
+ readonly error?: E
56
+ readonly module: string
33
57
  readonly inject?: ReadonlyArray<Service>
34
58
  readonly provides?: ReadonlyArray<Service>
35
- }) => {
59
+ }
60
+
61
+ /** An undeclared failure still crosses the boundary, with its diagnostic value. */
62
+ export class UndeclaredFailure extends Schema.TaggedError<
63
+ UndeclaredFailure,
64
+ { readonly brand: unique symbol }
65
+ >()("UndeclaredFailure", { original: Schema.Defect({ includeStack: true }) }) {}
66
+
67
+ /** Pure metadata shared by the host and the executable runner bootstrap. */
68
+ export function make<S extends ConfigSchema, E extends ErrorSchema>(
69
+ options: Options<S, E> & { readonly error: E },
70
+ ): Contract<S, E>
71
+ export function make<S extends ConfigSchema>(
72
+ options: Options<S, typeof Schema.Never>,
73
+ ): Contract<S>
74
+ export function make<S extends ConfigSchema, E extends ErrorSchema>(
75
+ options: Options<S, E>,
76
+ ): Contract<S, E | typeof Schema.Never> {
36
77
  // Keys are runtime strings; tuple types cannot distinguish independently created keys.
37
78
  const keys = Array.map(
38
79
  [...(options.inject ?? []), ...(options.provides ?? [])],
@@ -45,42 +86,17 @@ export const make = <
45
86
  throw new Error(
46
87
  "Service keys must be unique within a remote contract and must not use the control endpoint",
47
88
  )
48
- const failure = Schema.Union([options.error, UndeclaredFailure, ChildFailure])
49
- const codec = Schema.toCodecJson(
50
- Schema.Cause(failure, Schema.Defect({ includeStack: true })),
51
- )
52
- const declared = Schema.is(failure)
53
- const normalizeCause = (cause: Cause.Cause<unknown>) =>
54
- Cause.map(cause, (error) =>
55
- declared(error) ? error : UndeclaredFailure.make({ original: error }),
56
- )
89
+
57
90
  return {
58
91
  ...options,
59
- control: Control.make(codec),
60
- normalizeCause,
92
+ error: options.error ?? Schema.Never,
61
93
  inject: options.inject ?? [],
62
94
  provides: options.provides ?? [],
63
95
  [TypeId]: TypeId,
64
- encodeCause: (cause: Cause.Cause<unknown>) =>
65
- normalizeCause(cause).pipe(Schema.encodeEffect(codec)),
66
- decodeCause: Schema.decodeUnknownEffect(codec),
67
96
  }
68
97
  }
69
98
 
70
- /** The shared config, error codecs, and service declarations for one remote plugin. */
71
- export type Contract<
72
- S extends Schema.Top & {
73
- readonly Encoded: Schema.Json
74
- readonly DecodingServices: never
75
- readonly EncodingServices: never
76
- },
77
- E extends Schema.Top & {
78
- readonly DecodingServices: never
79
- readonly EncodingServices: never
80
- },
81
- > = ReturnType<typeof make<S, E>>
82
-
83
- /** Dynamic imports retain the control server and cause normalization; hosts retain the declared error type. */
99
+ /** A contract whose schemas are discovered through a dynamic import. */
84
100
  export type RunnerContract = Contract<
85
101
  Schema.Codec<unknown, Schema.Json>,
86
102
  Schema.Codec<unknown>
package/src/Errors.ts CHANGED
@@ -80,3 +80,18 @@ export class AuthenticationFailed extends Schema.TaggedError<
80
80
  challenge: Schema.optionalKey(Schema.String),
81
81
  cause: Schema.optionalKey(Schema.Cause(Schema.Unknown, Schema.Unknown)),
82
82
  }) {}
83
+
84
+ /** A remote entry could not be resolved or configured at the indicated field. */
85
+ export class RemoteEntryError extends Schema.TaggedError<
86
+ RemoteEntryError,
87
+ { readonly brand: unique symbol }
88
+ >()("RemoteEntryError", {
89
+ entry: Schema.Option(Schema.String),
90
+ directory: Schema.Option(Schema.String),
91
+ field: Schema.String,
92
+ cause: Schema.Cause(Schema.Unknown, Schema.Unknown),
93
+ }) {
94
+ override get message() {
95
+ return `Remote entry ${Option.getOrElse(this.entry, () => "<programmatic>")} failed at ${this.field}`
96
+ }
97
+ }
package/src/Testing.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Plugin } from "@graftland/graft"
2
2
  import {
3
3
  Array,
4
+ Cause,
4
5
  Equivalence,
5
6
  Deferred,
6
7
  Effect,
@@ -9,13 +10,17 @@ import {
9
10
  String,
10
11
  Schema,
11
12
  } from "effect"
13
+ import type { TransportError } from "./Errors"
12
14
  import type { Channel } from "./Transport"
13
15
  import * as Framing from "./internal/runner/Framing"
14
16
 
15
17
  export class ConformanceError extends Schema.TaggedError<
16
18
  ConformanceError,
17
19
  { readonly brand: unique symbol }
18
- >()("ConformanceError", { message: Schema.String }) {}
20
+ >()("ConformanceError", {
21
+ message: Schema.String,
22
+ cause: Schema.optionalKey(Schema.Cause(Schema.Unknown, Schema.Unknown)),
23
+ }) {}
19
24
  const check = (condition: boolean, message: string) =>
20
25
  condition ? Effect.void : Effect.fail(ConformanceError.make({ message }))
21
26
  export interface Capabilities {
@@ -88,7 +93,16 @@ export const transport = <E, R>(
88
93
  ),
89
94
  "The channel changed byte order across split or coalesced chunks",
90
95
  )
91
- }),
96
+ }).pipe(
97
+ Effect.mapError((error): E | ConformanceError | TransportError =>
98
+ Schema.is(Framing.FrameError)(error)
99
+ ? ConformanceError.make({
100
+ message: error.message,
101
+ cause: Cause.fail(error),
102
+ })
103
+ : error,
104
+ ),
105
+ ),
92
106
  eof: Effect.gen(function* () {
93
107
  const channel = yield* connect
94
108
  yield* Stream.empty.pipe(Stream.run(channel.output))
@@ -1,10 +1,5 @@
1
- import type { Graft, Plugin } from "@graftland/graft"
2
1
  import { Config, plugin } from "../../internal/auth/tokenCredentials"
3
2
  export { Config }
4
3
 
5
- const capability: Plugin.Plugin<
6
- typeof Config.Type,
7
- typeof Config.Encoded,
8
- Graft.ServiceConflict
9
- > = plugin("remote-bearer-credentials")
4
+ const capability = plugin("remote-bearer-credentials")
10
5
  export default capability
@@ -1,10 +1,5 @@
1
- import type { Graft, Plugin } from "@graftland/graft"
2
1
  import { Config, plugin } from "../../internal/auth/tokenCredentials"
3
2
  export { Config }
4
3
 
5
- const capability: Plugin.Plugin<
6
- typeof Config.Type,
7
- typeof Config.Encoded,
8
- Graft.ServiceConflict
9
- > = plugin("remote-jwt-credentials")
4
+ const capability = plugin("remote-jwt-credentials")
10
5
  export default capability
@@ -1,3 +1,5 @@
1
+ /** Options for the command connector. */
2
+ export type { CommandOptions as Options } from "../internal/transportOptions"
1
3
  import type { CommandOptions } from "../internal/transportOptions"
2
4
  import { Plugin, Graft } from "@graftland/graft"
3
5
  import {
package/src/host/local.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Plugin, type Graft } from "@graftland/graft"
1
+ import { Plugin } from "@graftland/graft"
2
2
  import { Array, Effect, Scope } from "effect"
3
3
  import { ChildProcess, ChildProcessSpawner } from "effect/process"
4
4
  import { LocalTransport } from "../internal/directTransport"
@@ -29,13 +29,9 @@ const make = Effect.map(ChildProcessSpawner.ChildProcessSpawner, (spawner) =>
29
29
  }),
30
30
  }),
31
31
  )
32
- const plugin: Plugin.Plugin<void, void, Graft.ServiceConflict> = Plugin.service(
33
- LocalTransport,
34
- make,
35
- {
36
- name: "remote-local-transport",
37
- inject: [ChildProcessSpawner.ChildProcessSpawner],
38
- },
39
- )
32
+ const plugin = Plugin.service(LocalTransport, make, {
33
+ name: "remote-local-transport",
34
+ inject: [ChildProcessSpawner.ChildProcessSpawner],
35
+ })
40
36
 
41
37
  export default plugin
package/src/host/unix.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /** Options for the unix connector. */
2
+ export type { UnixOptions as Options } from "../internal/transportOptions"
1
3
  import type { UnixOptions } from "../internal/transportOptions"
2
4
  import { Plugin, Graft } from "@graftland/graft"
3
5
  import { ConfigDirectory } from "@graftland/loader"
@@ -1,3 +1,5 @@
1
+ /** Options for the websocket connector. */
2
+ export type { WebsocketOptions as Options } from "../internal/transportOptions"
1
3
  import type { WebsocketOptions } from "../internal/transportOptions"
2
4
  import { Plugin, Graft } from "@graftland/graft"
3
5
  import { Cause, Effect, FileSystem, Option, Path, Schema } from "effect"
@@ -1,4 +1,4 @@
1
- import { Plugin, type Graft } from "@graftland/graft"
1
+ import { Plugin } from "@graftland/graft"
2
2
  import { Cause, Deferred, Effect, FiberSet, Option, Schema } from "effect"
3
3
  import { Worker } from "node:worker_threads"
4
4
  import { WorkerTransport } from "../internal/directTransport"
@@ -82,9 +82,7 @@ const start: typeof WorkerTransport.Service.start = Effect.fnUntraced(
82
82
  }
83
83
  },
84
84
  )
85
- const plugin: Plugin.Plugin<void, void, Graft.ServiceConflict> = Plugin.service(
86
- WorkerTransport,
87
- Effect.succeed({ start }),
88
- { name: "remote-thread-transport" },
89
- )
85
+ const plugin = Plugin.service(WorkerTransport, Effect.succeed({ start }), {
86
+ name: "remote-thread-transport",
87
+ })
90
88
  export default plugin
package/src/index.ts CHANGED
@@ -16,9 +16,11 @@ export { Contract }
16
16
  export { Instance } from "./Instance"
17
17
  export { RemoteTerminationUnconfirmed } from "./internal/runner/model"
18
18
  export { RemoteError, RemoteWithdrawn, MissingInstance } from "./Errors"
19
- export { UndeclaredFailure, ChildFailure } from "./Contract"
19
+ export { UndeclaredFailure } from "./Contract"
20
20
  export type {
21
21
  Connect,
22
+ Authentication,
23
+ Token as CredentialToken,
22
24
  Source as CredentialSource,
23
25
  } from "./internal/credentials"
24
26
 
@@ -19,13 +19,7 @@ export const Config = Schema.Struct({
19
19
  Schema.Struct({ file: Schema.String }),
20
20
  ]),
21
21
  })
22
- export const plugin = (
23
- name: string,
24
- ): Plugin.Plugin<
25
- typeof Config.Type,
26
- typeof Config.Encoded,
27
- Graft.ServiceConflict
28
- > =>
22
+ export const plugin = (name: string) =>
29
23
  Plugin.make({
30
24
  name,
31
25
  config: Config,
@@ -20,7 +20,7 @@ import {
20
20
  SynchronizedRef,
21
21
  } from "effect"
22
22
  import type { Schema } from "effect"
23
- import { type RunnerContract } from "../Contract"
23
+ import { type RunnerContract } from "./contract"
24
24
  import { Instance, type Identity } from "../Instance"
25
25
  import type * as Port from "./port"
26
26
  import type { Event, Log, LogEvent } from "./control"
@@ -5,6 +5,7 @@ import { Effect, Logger, Option } from "effect"
5
5
  import { RpcServer } from "effect/rpc"
6
6
  import { fromModule, type RunnerContract } from "../Contract"
7
7
  import * as Port from "./port"
8
+ import { prepare, type RunnerContract as PreparedContract } from "./contract"
8
9
  import * as Services from "./services"
9
10
  import * as Child from "./child"
10
11
  import * as Multiplex from "./runner/Multiplex"
@@ -25,7 +26,7 @@ export const load = (specifier: string) =>
25
26
  })
26
27
 
27
28
  const connect = (
28
- contract: RunnerContract,
29
+ contract: PreparedContract,
29
30
  channel: Port.Channel,
30
31
  session: string,
31
32
  bootstrap: Bootstrap | undefined,
@@ -49,7 +50,7 @@ const connect = (
49
50
 
50
51
  /** One execution unit; the executable supplies the platform and Graft services. */
51
52
  export const run = (
52
- contract: RunnerContract,
53
+ descriptor: RunnerContract,
53
54
  channel: Port.Channel,
54
55
  session = "local",
55
56
  bootstrap?: Bootstrap,
@@ -57,6 +58,7 @@ export const run = (
57
58
  ): Effect.Effect<void, ExecutionError, Graft.Graft> =>
58
59
  Effect.scoped(
59
60
  Effect.gen(function* () {
61
+ const contract = prepare(descriptor)
60
62
  const telemetry = yield* Child.telemetry(contract)
61
63
  const loggers = yield* Logger.CurrentLoggers
62
64
  yield* Effect.gen(function* () {
@@ -0,0 +1,47 @@
1
+ import { Cause, Schema } from "effect"
2
+ import * as Contract from "../Contract"
3
+ import { ChildFailure } from "./childErrors"
4
+ import * as Control from "./control"
5
+
6
+ /** Control RPCs and child failures belong to the execution protocol, not the public descriptor. */
7
+ export const prepare = <
8
+ S extends Schema.Top & {
9
+ readonly Encoded: Schema.Json
10
+ readonly DecodingServices: never
11
+ readonly EncodingServices: never
12
+ },
13
+ E extends Schema.Top & {
14
+ readonly DecodingServices: never
15
+ readonly EncodingServices: never
16
+ },
17
+ >(
18
+ contract: Contract.Contract<S, E>,
19
+ ) => {
20
+ const failure = Schema.Union([
21
+ contract.error,
22
+ Contract.UndeclaredFailure,
23
+ ChildFailure,
24
+ ])
25
+ const codec = Schema.toCodecJson(
26
+ Schema.Cause(failure, Schema.Defect({ includeStack: true })),
27
+ )
28
+ const declared = Schema.is(failure)
29
+ const normalizeCause = (cause: Cause.Cause<unknown>) =>
30
+ Cause.map(cause, (error) =>
31
+ declared(error)
32
+ ? error
33
+ : Contract.UndeclaredFailure.make({ original: error }),
34
+ )
35
+ return {
36
+ ...contract,
37
+ control: Control.make(codec),
38
+ normalizeCause,
39
+ encodeCause: (cause: Cause.Cause<unknown>) =>
40
+ normalizeCause(cause).pipe(Schema.encodeEffect(codec)),
41
+ decodeCause: Schema.decodeUnknownEffect(codec),
42
+ }
43
+ }
44
+
45
+ export type RunnerContract = ReturnType<
46
+ typeof prepare<Schema.Codec<unknown, Schema.Json>, Schema.Codec<unknown>>
47
+ >