@graftland/plugin-remote 0.0.0-stage → 0.2.0-beta.2

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 (380) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +76 -2
  3. package/README.zh-CN.md +71 -0
  4. package/README.zh-TW.md +71 -0
  5. package/dist/Auth-BElTC9_X.js +6 -0
  6. package/dist/Auth.d.ts +49 -0
  7. package/dist/Auth.d.ts.map +1 -0
  8. package/dist/Auth.js +8 -0
  9. package/dist/Auth.js.map +1 -0
  10. package/dist/Bootstrap-MCwivGN1.js +9 -0
  11. package/dist/ConfigDirectory-BCC6q2R4.js +5 -0
  12. package/dist/Contract-CcpSIJm4.js +121 -0
  13. package/dist/Contract.d.ts +71 -0
  14. package/dist/Contract.d.ts.map +1 -0
  15. package/dist/Contract.js +1 -0
  16. package/dist/Contract.js.map +1 -0
  17. package/dist/Errors-oPsTLY7l.js +45 -0
  18. package/dist/Errors.d.ts +67 -0
  19. package/dist/Errors.d.ts.map +1 -0
  20. package/dist/Errors.js +47 -0
  21. package/dist/Errors.js.map +1 -0
  22. package/dist/FailureGroup-BcH0XOBi.js +53 -0
  23. package/dist/Framing-zaYdOJnT.js +61 -0
  24. package/dist/Graft-BsYq3F-J.js +985 -0
  25. package/dist/Instance.d.ts +7 -0
  26. package/dist/Instance.d.ts.map +1 -0
  27. package/dist/Instance.js +14 -0
  28. package/dist/Instance.js.map +1 -0
  29. package/dist/Packages-B1TPk8pa.js +111 -0
  30. package/dist/Peer-IJgFK6mD.js +342 -0
  31. package/dist/ProcessObservation-DEGrEMfP.js +38 -0
  32. package/dist/ServeLifecycle-CJM0gG5B.js +24 -0
  33. package/dist/Testing.d.ts +26 -0
  34. package/dist/Testing.d.ts.map +1 -0
  35. package/dist/Testing.js +69 -0
  36. package/dist/Testing.js.map +1 -0
  37. package/dist/Transport-DULzpsgR.js +6 -0
  38. package/dist/Transport.d.ts +39 -0
  39. package/dist/Transport.d.ts.map +1 -0
  40. package/dist/Transport.js +8 -0
  41. package/dist/Transport.js.map +1 -0
  42. package/dist/WatchdogProtocol-BZmVxrBP.js +17 -0
  43. package/dist/_virtual/_rolldown/runtime.js +12 -0
  44. package/dist/bin.d.ts +1 -0
  45. package/dist/bin.js +28275 -0
  46. package/dist/bin.js.map +1 -0
  47. package/dist/childRuntime-DSqtFN9o.js +188 -0
  48. package/dist/cleanup-BPWr-5U9.js +13 -0
  49. package/dist/command-9zrHdbwT.js +7 -0
  50. package/dist/connectionEnded-DUgcobEd.js +9 -0
  51. package/dist/directTransport-DrexuPSm.js +5 -0
  52. package/dist/entry-SYsx9VNb.js +708 -0
  53. package/dist/host/auth/bearer.d.ts +5 -0
  54. package/dist/host/auth/bearer.d.ts.map +1 -0
  55. package/dist/host/auth/bearer.js +4 -0
  56. package/dist/host/auth/bearer.js.map +1 -0
  57. package/dist/host/auth/jwt.d.ts +5 -0
  58. package/dist/host/auth/jwt.d.ts.map +1 -0
  59. package/dist/host/auth/jwt.js +4 -0
  60. package/dist/host/auth/jwt.js.map +1 -0
  61. package/dist/host/auth/mtls.d.ts +8 -0
  62. package/dist/host/auth/mtls.d.ts.map +1 -0
  63. package/dist/host/auth/mtls.js +34 -0
  64. package/dist/host/auth/mtls.js.map +1 -0
  65. package/dist/host/auth/none.d.ts +3 -0
  66. package/dist/host/auth/none.d.ts.map +1 -0
  67. package/dist/host/auth/none.js +13 -0
  68. package/dist/host/auth/none.js.map +1 -0
  69. package/dist/host/command.d.ts +22 -0
  70. package/dist/host/command.d.ts.map +1 -0
  71. package/dist/host/command.js +61 -0
  72. package/dist/host/command.js.map +1 -0
  73. package/dist/host/local.d.ts +4 -0
  74. package/dist/host/local.d.ts.map +1 -0
  75. package/dist/host/local.js +52 -0
  76. package/dist/host/local.js.map +1 -0
  77. package/dist/host/unix.d.ts +11 -0
  78. package/dist/host/unix.d.ts.map +1 -0
  79. package/dist/host/unix.js +39 -0
  80. package/dist/host/unix.js.map +1 -0
  81. package/dist/host/websocket.d.ts +13 -0
  82. package/dist/host/websocket.d.ts.map +1 -0
  83. package/dist/host/websocket.js +36 -0
  84. package/dist/host/websocket.js.map +1 -0
  85. package/dist/host/worker.d.ts +4 -0
  86. package/dist/host/worker.d.ts.map +1 -0
  87. package/dist/host/worker.js +52 -0
  88. package/dist/host/worker.js.map +1 -0
  89. package/dist/importer-D7zSgqxq.js +347 -0
  90. package/dist/index.d.ts +29 -0
  91. package/dist/index.d.ts.map +1 -0
  92. package/dist/index.js +86 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/internal/Certificates.js +182 -0
  95. package/dist/internal/Certificates.js.map +1 -0
  96. package/dist/internal/FailureGroup.js +55 -0
  97. package/dist/internal/FailureGroup.js.map +1 -0
  98. package/dist/internal/Limits.d.ts +1 -0
  99. package/dist/internal/Limits.js +17 -0
  100. package/dist/internal/Limits.js.map +1 -0
  101. package/dist/internal/Peer.js +6 -0
  102. package/dist/internal/Peer.js.map +1 -0
  103. package/dist/internal/ServeLifecycle.js +26 -0
  104. package/dist/internal/ServeLifecycle.js.map +1 -0
  105. package/dist/internal/Supervisor.js +7 -0
  106. package/dist/internal/Supervisor.js.map +1 -0
  107. package/dist/internal/assembly.d.ts +5 -0
  108. package/dist/internal/assembly.js +138 -0
  109. package/dist/internal/assembly.js.map +1 -0
  110. package/dist/internal/auth/mtls.js +23 -0
  111. package/dist/internal/auth/mtls.js.map +1 -0
  112. package/dist/internal/auth/token.js +19 -0
  113. package/dist/internal/auth/token.js.map +1 -0
  114. package/dist/internal/auth/tokenCredentials.d.ts +8 -0
  115. package/dist/internal/auth/tokenCredentials.d.ts.map +1 -0
  116. package/dist/internal/auth/tokenCredentials.js +33 -0
  117. package/dist/internal/auth/tokenCredentials.js.map +1 -0
  118. package/dist/internal/child.js +125 -0
  119. package/dist/internal/child.js.map +1 -0
  120. package/dist/internal/childErrors.d.ts +33 -0
  121. package/dist/internal/childErrors.d.ts.map +1 -0
  122. package/dist/internal/childErrors.js +29 -0
  123. package/dist/internal/childErrors.js.map +1 -0
  124. package/dist/internal/childRuntime.js +59 -0
  125. package/dist/internal/childRuntime.js.map +1 -0
  126. package/dist/internal/cleanup.js +15 -0
  127. package/dist/internal/cleanup.js.map +1 -0
  128. package/dist/internal/config.js +6 -0
  129. package/dist/internal/config.js.map +1 -0
  130. package/dist/internal/control.js +42 -0
  131. package/dist/internal/control.js.map +1 -0
  132. package/dist/internal/credentials.d.ts +44 -0
  133. package/dist/internal/credentials.d.ts.map +1 -0
  134. package/dist/internal/credentials.js +54 -0
  135. package/dist/internal/credentials.js.map +1 -0
  136. package/dist/internal/directTransport.d.ts +3 -0
  137. package/dist/internal/directTransport.js +7 -0
  138. package/dist/internal/directTransport.js.map +1 -0
  139. package/dist/internal/entry.d.ts +9 -0
  140. package/dist/internal/entry.d.ts.map +1 -0
  141. package/dist/internal/entry.js +144 -0
  142. package/dist/internal/entry.js.map +1 -0
  143. package/dist/internal/entryConfig.d.ts +202 -0
  144. package/dist/internal/entryConfig.d.ts.map +1 -0
  145. package/dist/internal/entryConfig.js +176 -0
  146. package/dist/internal/entryConfig.js.map +1 -0
  147. package/dist/internal/execution.d.ts +5 -0
  148. package/dist/internal/execution.js +43 -0
  149. package/dist/internal/execution.js.map +1 -0
  150. package/dist/internal/follow.js +11 -0
  151. package/dist/internal/follow.js.map +1 -0
  152. package/dist/internal/forkTree.js +7 -0
  153. package/dist/internal/forkTree.js.map +1 -0
  154. package/dist/internal/host/local.js +28 -0
  155. package/dist/internal/host/local.js.map +1 -0
  156. package/dist/internal/host/runner.js +100 -0
  157. package/dist/internal/host/runner.js.map +1 -0
  158. package/dist/internal/host.js +71 -0
  159. package/dist/internal/host.js.map +1 -0
  160. package/dist/internal/importer.js +18 -0
  161. package/dist/internal/importer.js.map +1 -0
  162. package/dist/internal/listenerStartup.js +17 -0
  163. package/dist/internal/listenerStartup.js.map +1 -0
  164. package/dist/internal/loadModule.js +20 -0
  165. package/dist/internal/loadModule.js.map +1 -0
  166. package/dist/internal/platform.js +9 -0
  167. package/dist/internal/platform.js.map +1 -0
  168. package/dist/internal/port.d.ts +13 -0
  169. package/dist/internal/port.d.ts.map +1 -0
  170. package/dist/internal/port.js +275 -0
  171. package/dist/internal/port.js.map +1 -0
  172. package/dist/internal/release.js +25 -0
  173. package/dist/internal/release.js.map +1 -0
  174. package/dist/internal/runner/Bootstrap.js +11 -0
  175. package/dist/internal/runner/Bootstrap.js.map +1 -0
  176. package/dist/internal/runner/Connection.d.ts +11 -0
  177. package/dist/internal/runner/Connection.js +56 -0
  178. package/dist/internal/runner/Connection.js.map +1 -0
  179. package/dist/internal/runner/Execution.js +115 -0
  180. package/dist/internal/runner/Execution.js.map +1 -0
  181. package/dist/internal/runner/Framing.d.ts +11 -0
  182. package/dist/internal/runner/Framing.d.ts.map +1 -0
  183. package/dist/internal/runner/Framing.js +63 -0
  184. package/dist/internal/runner/Framing.js.map +1 -0
  185. package/dist/internal/runner/Local.js +46 -0
  186. package/dist/internal/runner/Local.js.map +1 -0
  187. package/dist/internal/runner/Lock.js +25 -0
  188. package/dist/internal/runner/Lock.js.map +1 -0
  189. package/dist/internal/runner/Multiplex.d.ts +5 -0
  190. package/dist/internal/runner/Multiplex.js +49 -0
  191. package/dist/internal/runner/Multiplex.js.map +1 -0
  192. package/dist/internal/runner/Packages.d.ts +3 -0
  193. package/dist/internal/runner/Packages.js +108 -0
  194. package/dist/internal/runner/Packages.js.map +1 -0
  195. package/dist/internal/runner/ProcessObservation.js +40 -0
  196. package/dist/internal/runner/ProcessObservation.js.map +1 -0
  197. package/dist/internal/runner/Processes.js +83 -0
  198. package/dist/internal/runner/Processes.js.map +1 -0
  199. package/dist/internal/runner/Retention.js +13 -0
  200. package/dist/internal/runner/Retention.js.map +1 -0
  201. package/dist/internal/runner/Store.js +78 -0
  202. package/dist/internal/runner/Store.js.map +1 -0
  203. package/dist/internal/runner/Supervisor.js +375 -0
  204. package/dist/internal/runner/Supervisor.js.map +1 -0
  205. package/dist/internal/runner/Watchdog.js +47 -0
  206. package/dist/internal/runner/Watchdog.js.map +1 -0
  207. package/dist/internal/runner/WatchdogProtocol.js +19 -0
  208. package/dist/internal/runner/WatchdogProtocol.js.map +1 -0
  209. package/dist/internal/runner/Wire.d.ts +5 -0
  210. package/dist/internal/runner/Wire.js +64 -0
  211. package/dist/internal/runner/Wire.js.map +1 -0
  212. package/dist/internal/runner/accept.js +57 -0
  213. package/dist/internal/runner/accept.js.map +1 -0
  214. package/dist/internal/runner/command.js +9 -0
  215. package/dist/internal/runner/command.js.map +1 -0
  216. package/dist/internal/runner/connectionEnded.js +11 -0
  217. package/dist/internal/runner/connectionEnded.js.map +1 -0
  218. package/dist/internal/runner/model.d.ts +17 -0
  219. package/dist/internal/runner/model.d.ts.map +1 -0
  220. package/dist/internal/runner/model.js +231 -0
  221. package/dist/internal/runner/model.js.map +1 -0
  222. package/dist/internal/serve.js +60 -0
  223. package/dist/internal/serve.js.map +1 -0
  224. package/dist/internal/services.d.ts +18 -0
  225. package/dist/internal/services.d.ts.map +1 -0
  226. package/dist/internal/services.js +22 -0
  227. package/dist/internal/services.js.map +1 -0
  228. package/dist/internal/socketChannel.js +24 -0
  229. package/dist/internal/socketChannel.js.map +1 -0
  230. package/dist/internal/stdioChannel.js +23 -0
  231. package/dist/internal/stdioChannel.js.map +1 -0
  232. package/dist/internal/supervisorPlugin.js +1 -0
  233. package/dist/internal/supervisorPlugin.js.map +1 -0
  234. package/dist/internal/transportOptions.d.ts +18 -0
  235. package/dist/internal/transportOptions.d.ts.map +1 -0
  236. package/dist/internal/watchdogMain.d.ts +1 -0
  237. package/dist/internal/watchdogMain.js +55 -0
  238. package/dist/internal/watchdogMain.js.map +1 -0
  239. package/dist/internal/websocket.js +46 -0
  240. package/dist/internal/websocket.js.map +1 -0
  241. package/dist/internal/websocketServer.js +61 -0
  242. package/dist/internal/websocketServer.js.map +1 -0
  243. package/dist/internal/workerBootstrap.js +9 -0
  244. package/dist/internal/workerBootstrap.js.map +1 -0
  245. package/dist/internal/workerChannel.js +24 -0
  246. package/dist/internal/workerChannel.js.map +1 -0
  247. package/dist/internal/workerMain.d.ts +1 -0
  248. package/dist/internal/workerMain.js +18 -0
  249. package/dist/internal/workerMain.js.map +1 -0
  250. package/dist/port-Blbh8tms.js +285 -0
  251. package/dist/release-BY4Mlluy.js +23 -0
  252. package/dist/rolldown-runtime-DYf_mQCB.js +34 -0
  253. package/dist/runner/auth/bearer.d.ts +7 -0
  254. package/dist/runner/auth/bearer.d.ts.map +1 -0
  255. package/dist/runner/auth/bearer.js +42 -0
  256. package/dist/runner/auth/bearer.js.map +1 -0
  257. package/dist/runner/auth/jwt.d.ts +19 -0
  258. package/dist/runner/auth/jwt.d.ts.map +1 -0
  259. package/dist/runner/auth/jwt.js +65 -0
  260. package/dist/runner/auth/jwt.js.map +1 -0
  261. package/dist/runner/auth/mtls.d.ts +11 -0
  262. package/dist/runner/auth/mtls.d.ts.map +1 -0
  263. package/dist/runner/auth/mtls.js +48 -0
  264. package/dist/runner/auth/mtls.js.map +1 -0
  265. package/dist/runner/auth/none.d.ts +3 -0
  266. package/dist/runner/auth/none.d.ts.map +1 -0
  267. package/dist/runner/auth/none.js +13 -0
  268. package/dist/runner/auth/none.js.map +1 -0
  269. package/dist/runner/index.d.ts +3 -0
  270. package/dist/runner/index.d.ts.map +1 -0
  271. package/dist/runner/index.js +71 -0
  272. package/dist/runner/index.js.map +1 -0
  273. package/dist/runner/stdio.d.ts +7 -0
  274. package/dist/runner/stdio.d.ts.map +1 -0
  275. package/dist/runner/stdio.js +39 -0
  276. package/dist/runner/stdio.js.map +1 -0
  277. package/dist/runner/unix.d.ts +7 -0
  278. package/dist/runner/unix.d.ts.map +1 -0
  279. package/dist/runner/unix.js +42 -0
  280. package/dist/runner/unix.js.map +1 -0
  281. package/dist/runner/websocket.d.ts +28 -0
  282. package/dist/runner/websocket.d.ts.map +1 -0
  283. package/dist/runner/websocket.js +77 -0
  284. package/dist/runner/websocket.js.map +1 -0
  285. package/dist/socketChannel-KmtzF-9G.js +3658 -0
  286. package/dist/supervisorPlugin-Inb1S5IV.js +737 -0
  287. package/dist/token-v5ne2I0-.js +17 -0
  288. package/dist/tokenCredentials-WUJm2AKm.js +31 -0
  289. package/dist/websocketServer-MXcCJx0v.js +58 -0
  290. package/dist/workerChannel-P82YdNjh.js +27 -0
  291. package/package.json +69 -3
  292. package/src/Auth.ts +62 -0
  293. package/src/Contract.ts +100 -0
  294. package/src/Errors.ts +82 -0
  295. package/src/Instance.ts +12 -0
  296. package/src/Testing.ts +135 -0
  297. package/src/Transport.ts +52 -0
  298. package/src/bin.ts +145 -0
  299. package/src/host/auth/bearer.ts +10 -0
  300. package/src/host/auth/jwt.ts +10 -0
  301. package/src/host/auth/mtls.ts +48 -0
  302. package/src/host/auth/none.ts +13 -0
  303. package/src/host/command.ts +131 -0
  304. package/src/host/local.ts +41 -0
  305. package/src/host/unix.ts +65 -0
  306. package/src/host/websocket.ts +66 -0
  307. package/src/host/worker.ts +90 -0
  308. package/src/index.ts +115 -0
  309. package/src/internal/Certificates.ts +330 -0
  310. package/src/internal/FailureGroup.ts +176 -0
  311. package/src/internal/Limits.ts +12 -0
  312. package/src/internal/Peer.ts +4 -0
  313. package/src/internal/ServeLifecycle.ts +53 -0
  314. package/src/internal/Supervisor.ts +14 -0
  315. package/src/internal/assembly.ts +337 -0
  316. package/src/internal/auth/mtls.ts +40 -0
  317. package/src/internal/auth/token.ts +26 -0
  318. package/src/internal/auth/tokenCredentials.ts +65 -0
  319. package/src/internal/child.ts +323 -0
  320. package/src/internal/childErrors.ts +44 -0
  321. package/src/internal/childRuntime.ts +111 -0
  322. package/src/internal/cleanup.ts +34 -0
  323. package/src/internal/config.ts +8 -0
  324. package/src/internal/control.ts +49 -0
  325. package/src/internal/credentials.ts +112 -0
  326. package/src/internal/directTransport.ts +38 -0
  327. package/src/internal/entry.ts +288 -0
  328. package/src/internal/entryConfig.ts +190 -0
  329. package/src/internal/execution.ts +121 -0
  330. package/src/internal/follow.ts +17 -0
  331. package/src/internal/forkTree.ts +13 -0
  332. package/src/internal/host/local.ts +53 -0
  333. package/src/internal/host/runner.ts +187 -0
  334. package/src/internal/host.ts +209 -0
  335. package/src/internal/importer.ts +27 -0
  336. package/src/internal/listenerStartup.ts +55 -0
  337. package/src/internal/loadModule.ts +23 -0
  338. package/src/internal/platform.ts +12 -0
  339. package/src/internal/port.ts +623 -0
  340. package/src/internal/release.ts +71 -0
  341. package/src/internal/runner/Bootstrap.ts +9 -0
  342. package/src/internal/runner/Connection.ts +184 -0
  343. package/src/internal/runner/Execution.ts +244 -0
  344. package/src/internal/runner/Framing.ts +122 -0
  345. package/src/internal/runner/Local.ts +73 -0
  346. package/src/internal/runner/Lock.ts +29 -0
  347. package/src/internal/runner/Multiplex.ts +120 -0
  348. package/src/internal/runner/Packages.ts +178 -0
  349. package/src/internal/runner/ProcessObservation.ts +63 -0
  350. package/src/internal/runner/Processes.ts +109 -0
  351. package/src/internal/runner/Retention.ts +49 -0
  352. package/src/internal/runner/Store.ts +160 -0
  353. package/src/internal/runner/Supervisor.ts +901 -0
  354. package/src/internal/runner/Watchdog.ts +83 -0
  355. package/src/internal/runner/WatchdogProtocol.ts +12 -0
  356. package/src/internal/runner/Wire.ts +99 -0
  357. package/src/internal/runner/accept.ts +103 -0
  358. package/src/internal/runner/command.ts +15 -0
  359. package/src/internal/runner/connectionEnded.ts +28 -0
  360. package/src/internal/runner/model.ts +364 -0
  361. package/src/internal/serve.ts +117 -0
  362. package/src/internal/services.ts +74 -0
  363. package/src/internal/socketChannel.ts +64 -0
  364. package/src/internal/stdioChannel.ts +25 -0
  365. package/src/internal/supervisorPlugin.ts +67 -0
  366. package/src/internal/transportOptions.ts +17 -0
  367. package/src/internal/watchdogMain.ts +72 -0
  368. package/src/internal/websocket.ts +81 -0
  369. package/src/internal/websocketServer.ts +152 -0
  370. package/src/internal/workerBootstrap.ts +6 -0
  371. package/src/internal/workerChannel.ts +54 -0
  372. package/src/internal/workerMain.ts +23 -0
  373. package/src/runner/auth/bearer.ts +66 -0
  374. package/src/runner/auth/jwt.ts +114 -0
  375. package/src/runner/auth/mtls.ts +37 -0
  376. package/src/runner/auth/none.ts +13 -0
  377. package/src/runner/index.ts +97 -0
  378. package/src/runner/stdio.ts +76 -0
  379. package/src/runner/unix.ts +53 -0
  380. package/src/runner/websocket.ts +143 -0
@@ -0,0 +1,38 @@
1
+ import { Context } from "effect"
2
+ import type { Effect, Option, Scope, PlatformError } from "effect"
3
+ import type { ProcessExited, TransportError } from "../Errors"
4
+ import type { Channel } from "../Transport"
5
+ export interface LocalOptions {
6
+ readonly command?: readonly [string, ...string[]]
7
+ readonly contractModule: string
8
+ readonly session: string
9
+ }
10
+ export interface Execution {
11
+ readonly channel: Channel
12
+ readonly pid: Option.Option<number>
13
+ readonly threadId?: number
14
+ readonly exited: Effect.Effect<ProcessExited, TransportError>
15
+ readonly failure: Effect.Effect<never, TransportError>
16
+ }
17
+ export class LocalTransport extends Context.Service<
18
+ LocalTransport,
19
+ {
20
+ readonly start: (
21
+ options: LocalOptions,
22
+ ) => Effect.Effect<Execution, PlatformError.PlatformError, Scope.Scope>
23
+ }
24
+ >()("@graftland/plugin-remote/internal/directTransport/LocalTransport") {}
25
+
26
+ export interface WorkerOptions {
27
+ readonly execArgv?: ReadonlyArray<string>
28
+ readonly contractModule: string
29
+ readonly session: string
30
+ }
31
+ export class WorkerTransport extends Context.Service<
32
+ WorkerTransport,
33
+ {
34
+ readonly start: (
35
+ options: WorkerOptions,
36
+ ) => Effect.Effect<Execution, TransportError, Scope.Scope>
37
+ }
38
+ >()("@graftland/plugin-remote/internal/directTransport/WorkerTransport") {}
@@ -0,0 +1,288 @@
1
+ import { Graft, Plugin, type Fork } from "@graftland/graft"
2
+ import { ConfigDirectory, Entry, ModuleResolver } from "@graftland/loader"
3
+ import {
4
+ Cause,
5
+ Effect,
6
+ Option,
7
+ Path,
8
+ Schema,
9
+ References,
10
+ Scope,
11
+ String,
12
+ } from "effect"
13
+ import { ChildProcessSpawner } from "effect/process"
14
+ import * as Contract from "../Contract"
15
+ import { MissingInstance } from "../Errors"
16
+ import { LocalTransport, WorkerTransport } from "./directTransport"
17
+ import * as Configuration from "./entryConfig"
18
+ import * as Assembly from "./assembly"
19
+ import { executionPlugin } from "./execution"
20
+ import { follow } from "./follow"
21
+ import { children } from "./cleanup"
22
+ import { resolveEntry } from "./runner/Packages"
23
+ import type { LocalTarget, WorkerTarget } from "./runner/Connection"
24
+ import type { ExecutionOptions } from "./execution"
25
+ import * as Importer from "./importer"
26
+ import { SecureRandom } from "effect/crypto"
27
+
28
+ export class EntryError extends Schema.TaggedError<
29
+ EntryError,
30
+ { readonly brand: unique symbol }
31
+ >()("RemoteEntryError", {
32
+ entry: Schema.Option(Schema.String),
33
+ directory: Schema.Option(Schema.String),
34
+ field: Schema.String,
35
+ cause: Schema.Cause(Schema.Unknown, Schema.Unknown),
36
+ }) {
37
+ override get message() {
38
+ return `Remote entry ${Option.getOrElse(this.entry, () => "<programmatic>")} failed at ${this.field}`
39
+ }
40
+ }
41
+ export const boundary = Effect.fnUntraced(function* (field: string) {
42
+ const entry = yield* Entry.CurrentId
43
+ const directory = yield* ConfigDirectory
44
+ return (cause: Cause.Cause<unknown>) =>
45
+ Effect.fail(EntryError.make({ entry, directory, field, cause }))
46
+ })
47
+ export const resolve = Effect.fnUntraced(function* (
48
+ reference: Configuration.Reference,
49
+ field: string,
50
+ ) {
51
+ const existing = yield* Effect.serviceOption(ModuleResolver.ModuleResolver)
52
+ const path = yield* Path.Path
53
+ const source = yield* ConfigDirectory
54
+ const directory = path.resolve(Option.getOrElse(source, () => "."))
55
+ const resolver = yield* Option.match(existing, {
56
+ onSome: Effect.succeed,
57
+ onNone: () =>
58
+ Effect.gen(function* () {
59
+ const importer = yield* Importer.make(directory)
60
+ return yield* ModuleResolver.make({
61
+ base: directory,
62
+ importer: (specifier) =>
63
+ String.startsWith("@graftland/plugin-remote/")(specifier)
64
+ ? import(specifier)
65
+ : importer(specifier),
66
+ })
67
+ }),
68
+ })
69
+ const fail = yield* boundary(field)
70
+ const plugin = yield* resolver
71
+ .resolve(reference.name)
72
+ .pipe(Effect.catchCause(fail))
73
+ return { plugin, config: reference.config }
74
+ })
75
+ export const loadContract = Effect.fnUntraced(function* (specifier: string) {
76
+ const resolver = yield* ModuleResolver.ModuleResolver
77
+ const fail = yield* boundary("contract")
78
+ return yield* resolver.importModule(specifier).pipe(
79
+ Effect.flatMap((module) =>
80
+ Effect.fromOption(Contract.fromModule(module), () =>
81
+ ModuleResolver.ModuleInvalid.make({
82
+ specifier,
83
+ cause: "Expected a default or named remote contract",
84
+ }),
85
+ ),
86
+ ),
87
+ Effect.catchCause(fail),
88
+ )
89
+ })
90
+
91
+ /** Direct execution installs only its execution capability in a private realm. */
92
+ export const direct = (
93
+ provider: Plugin.Plugin,
94
+ consumer: Plugin.Plugin,
95
+ input: Schema.Json,
96
+ key: typeof LocalTransport | typeof WorkerTransport,
97
+ ): Effect.Effect<Fork.Fork<never, unknown>, never, Graft.Graft | Scope.Scope> =>
98
+ Graft.plugin(
99
+ Plugin.make({
100
+ name: "remote-direct",
101
+ apply: Effect.fnUntraced(function* () {
102
+ const capability = yield* Graft.plugin(provider)
103
+ yield* follow(capability, (cause) =>
104
+ Effect.fail(Assembly.CapabilityFailed.make({ cause })),
105
+ )
106
+ const execution = yield* Graft.plugin(consumer, input)
107
+ yield* follow(execution, (cause) =>
108
+ Effect.fail(Assembly.CapabilityFailed.make({ cause })),
109
+ )
110
+ }),
111
+ }),
112
+ undefined,
113
+ { isolate: [key] },
114
+ )
115
+
116
+ type Annotations = Readonly<Record<string, unknown>>
117
+ const directTarget = Effect.fnUntraced(function* <
118
+ S extends Schema.Top & {
119
+ readonly Encoded: Schema.Json
120
+ readonly DecodingServices: never
121
+ readonly EncodingServices: never
122
+ },
123
+ E extends Schema.Top & {
124
+ readonly DecodingServices: never
125
+ readonly EncodingServices: never
126
+ },
127
+ >(
128
+ contract: Contract.Contract<S, E>,
129
+ input: typeof Configuration.Host.Type,
130
+ selected: LocalTarget | WorkerTarget,
131
+ annotations: Annotations,
132
+ options: ExecutionOptions,
133
+ ) {
134
+ const path = yield* Path.Path
135
+ const source = yield* ConfigDirectory
136
+ const directory = path.resolve(Option.getOrElse(source, () => "."))
137
+ const module = String.startsWith("file:")(input.contract)
138
+ ? input.contract
139
+ : yield* resolveEntry(directory, input.contract)
140
+ const capability = yield* resolve(
141
+ {
142
+ name:
143
+ selected._tag === "Local"
144
+ ? "@graftland/plugin-remote/host/local"
145
+ : "@graftland/plugin-remote/host/worker",
146
+ },
147
+ "connect",
148
+ )
149
+ return yield* direct(
150
+ capability.plugin,
151
+ executionPlugin(
152
+ contract,
153
+ { ...options, contractModule: module },
154
+ selected,
155
+ annotations,
156
+ ),
157
+ input.config,
158
+ selected._tag === "Local" ? LocalTransport : WorkerTransport,
159
+ )
160
+ })
161
+ const runnerTarget = Effect.fnUntraced(function* <
162
+ S extends Schema.Top & {
163
+ readonly Encoded: Schema.Json
164
+ readonly DecodingServices: never
165
+ readonly EncodingServices: never
166
+ },
167
+ E extends Schema.Top & {
168
+ readonly DecodingServices: never
169
+ readonly EncodingServices: never
170
+ },
171
+ >(
172
+ contract: Contract.Contract<S, E>,
173
+ input: typeof Configuration.Host.Type,
174
+ target: Exclude<
175
+ Configuration.Connect,
176
+ { readonly local: object } | { readonly worker: object }
177
+ >,
178
+ annotations: Annotations,
179
+ options: ExecutionOptions,
180
+ authOverride: typeof Assembly.Invocation.Type | undefined,
181
+ ) {
182
+ const instance =
183
+ target.instance === undefined
184
+ ? yield* Entry.CurrentId
185
+ : Option.some(target.instance)
186
+ if (Option.isNone(instance)) return yield* MissingInstance.make({})
187
+ const transport = yield* resolve(
188
+ Configuration.hostTransport(target),
189
+ "connect.transport",
190
+ )
191
+ const auth =
192
+ authOverride ??
193
+ (yield* resolve(
194
+ Configuration.authentication("host", target.auth),
195
+ "connect.auth",
196
+ ))
197
+ const consumer = executionPlugin(
198
+ contract,
199
+ options,
200
+ {
201
+ _tag: "Connector",
202
+ explicitAuth: target.auth !== undefined,
203
+ instance: instance.value,
204
+ ...(target.lease === undefined ? {} : { lease: target.lease }),
205
+ ...(target.margin === undefined ? {} : { margin: target.margin }),
206
+ ...(target.expect === undefined ? {} : { expect: target.expect }),
207
+ },
208
+ annotations,
209
+ )
210
+ return yield* Assembly.host({
211
+ transport,
212
+ auth,
213
+ consumer,
214
+ input: input.config,
215
+ })
216
+ })
217
+
218
+ export const launch = Effect.fnUntraced(function* <
219
+ S extends Schema.Top & {
220
+ readonly Encoded: Schema.Json
221
+ readonly DecodingServices: never
222
+ readonly EncodingServices: never
223
+ },
224
+ E extends Schema.Top & {
225
+ readonly DecodingServices: never
226
+ readonly EncodingServices: never
227
+ },
228
+ >(
229
+ contract: Contract.Contract<S, E>,
230
+ input: typeof Configuration.Host.Type,
231
+ options: ExecutionOptions,
232
+ authOverride?: typeof Assembly.Invocation.Type,
233
+ ) {
234
+ const annotations = yield* References.CurrentLogAnnotations
235
+ const connect = input.connect
236
+ const scope = yield* children
237
+ return yield* Effect.gen(function* () {
238
+ if (connect.local !== undefined)
239
+ return yield* directTarget(
240
+ contract,
241
+ input,
242
+ { _tag: "Local", ...connect.local },
243
+ annotations,
244
+ options,
245
+ )
246
+ if (connect.worker !== undefined)
247
+ return yield* directTarget(
248
+ contract,
249
+ input,
250
+ { _tag: "Worker", ...connect.worker },
251
+ annotations,
252
+ options,
253
+ )
254
+ return yield* runnerTarget(
255
+ contract,
256
+ input,
257
+ connect,
258
+ annotations,
259
+ options,
260
+ authOverride,
261
+ )
262
+ }).pipe(Scope.provide(scope))
263
+ })
264
+ const load = Effect.fnUntraced(function* (
265
+ input: typeof Configuration.Host.Type,
266
+ ) {
267
+ const contract = yield* loadContract(input.contract)
268
+ const failConfig = yield* boundary("config")
269
+ yield* Schema.decodeEffect(contract.config)(input.config).pipe(
270
+ Effect.catchCause(failConfig),
271
+ )
272
+ const failConnect = yield* boundary("connect")
273
+ const fork = yield* launch(contract, input, {
274
+ contractModule: input.contract,
275
+ }).pipe(Effect.catchCause(failConnect))
276
+ yield* follow(fork, failConnect)
277
+ })
278
+ export const host = Plugin.make({
279
+ name: "remote",
280
+ config: Configuration.Host,
281
+ inject: [
282
+ SecureRandom.SecureRandom,
283
+ ModuleResolver.ModuleResolver,
284
+ Path.Path,
285
+ ChildProcessSpawner.ChildProcessSpawner,
286
+ ],
287
+ apply: load,
288
+ })
@@ -0,0 +1,190 @@
1
+ import { Effect, Schema } from "effect"
2
+ import { PositiveDuration } from "./config"
3
+
4
+ export const Reference = Schema.Struct({
5
+ name: Schema.String,
6
+ config: Schema.optionalKey(Schema.Unknown),
7
+ })
8
+ export type Reference = typeof Reference.Type
9
+ const absent = Schema.optionalKey(Schema.Never)
10
+ const authFields = {
11
+ name: absent,
12
+ config: absent,
13
+ mtls: absent,
14
+ bearer: absent,
15
+ jwt: absent,
16
+ none: absent,
17
+ }
18
+ export const Authentication = Schema.Union([
19
+ Schema.Struct({
20
+ ...authFields,
21
+ name: Schema.String,
22
+ config: Schema.optionalKey(Schema.Unknown),
23
+ }),
24
+ Schema.Struct({ ...authFields, mtls: Schema.Unknown }),
25
+ Schema.Struct({ ...authFields, bearer: Schema.Unknown }),
26
+ Schema.Struct({ ...authFields, jwt: Schema.Unknown }),
27
+ Schema.Struct({ ...authFields, none: Schema.Unknown }),
28
+ ])
29
+ const transportFields = {
30
+ url: absent,
31
+ unix: absent,
32
+ command: absent,
33
+ stdio: absent,
34
+ local: absent,
35
+ worker: absent,
36
+ transport: absent,
37
+ }
38
+ const auth = Schema.optionalKey(Authentication)
39
+ const common = {
40
+ instance: Schema.optionalKey(Schema.String),
41
+ lease: Schema.optionalKey(PositiveDuration),
42
+ margin: Schema.optionalKey(PositiveDuration),
43
+ expect: Schema.optionalKey(
44
+ Schema.Struct({
45
+ version: Schema.optionalKey(Schema.String),
46
+ digest: Schema.optionalKey(Schema.String),
47
+ }),
48
+ ),
49
+ }
50
+ const network = {
51
+ ...transportFields,
52
+ ...common,
53
+ auth,
54
+ url: Schema.String,
55
+ ca: Schema.optionalKey(Schema.String),
56
+ servername: Schema.optionalKey(Schema.String),
57
+ }
58
+ export const Connect = Schema.Union([
59
+ Schema.Struct(network),
60
+ Schema.Struct({ ...transportFields, ...common, auth, unix: Schema.String }),
61
+ Schema.Struct({
62
+ ...transportFields,
63
+ ...common,
64
+ command: Schema.NonEmptyArray(Schema.String),
65
+ auth: Schema.optionalKey(
66
+ Schema.Never.annotate({
67
+ message: "Direct and stdio transports do not accept auth",
68
+ }),
69
+ ),
70
+ cwd: Schema.optionalKey(Schema.String),
71
+ env: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
72
+ }),
73
+ Schema.Struct({
74
+ ...transportFields,
75
+ auth: Schema.optionalKey(
76
+ Schema.Never.annotate({
77
+ message: "Direct and stdio transports do not accept auth",
78
+ }),
79
+ ),
80
+ local: Schema.Struct({
81
+ command: Schema.optionalKey(Schema.NonEmptyArray(Schema.String)),
82
+ }),
83
+ }),
84
+ Schema.Struct({
85
+ ...transportFields,
86
+ auth: Schema.optionalKey(
87
+ Schema.Never.annotate({
88
+ message: "Direct and stdio transports do not accept auth",
89
+ }),
90
+ ),
91
+ worker: Schema.Struct({
92
+ execArgv: Schema.optionalKey(Schema.Array(Schema.String)),
93
+ }),
94
+ }),
95
+ Schema.Struct({ ...transportFields, ...common, auth, transport: Reference }),
96
+ ])
97
+ export type Connect = typeof Connect.Type
98
+ export const Listen = Schema.Union([
99
+ Schema.Struct({
100
+ ...transportFields,
101
+ auth,
102
+ url: Schema.String,
103
+ cert: Schema.optionalKey(Schema.String),
104
+ key: Schema.optionalKey(Schema.String),
105
+ }),
106
+ Schema.Struct({ ...transportFields, auth, unix: Schema.String }),
107
+ Schema.Struct({
108
+ ...transportFields,
109
+ stdio: Schema.Literal(true),
110
+ auth: Schema.optionalKey(
111
+ Schema.Never.annotate({
112
+ message: "Direct and stdio transports do not accept auth",
113
+ }),
114
+ ),
115
+ identity: Schema.optionalKey(Schema.String),
116
+ }),
117
+ Schema.Struct({ ...transportFields, auth, transport: Reference }),
118
+ ])
119
+ export type Listen = typeof Listen.Type
120
+ const capability = (
121
+ side: "host" | "runner",
122
+ name: string,
123
+ config: unknown,
124
+ ): Reference => ({ name: `@graftland/plugin-remote/${side}/${name}`, config })
125
+ export const authentication = (
126
+ side: "host" | "runner",
127
+ input: typeof Authentication.Type | undefined,
128
+ ): Reference => {
129
+ if (input === undefined) return capability(side, "auth/none", {})
130
+ if (input.name !== undefined) return input
131
+ if (input.mtls !== undefined) return capability(side, "auth/mtls", input.mtls)
132
+ if (input.bearer !== undefined)
133
+ return capability(side, "auth/bearer", input.bearer)
134
+ if (input.jwt !== undefined) return capability(side, "auth/jwt", input.jwt)
135
+ return capability(side, "auth/none", input.none)
136
+ }
137
+ export const hostTransport = (
138
+ input: Exclude<
139
+ Connect,
140
+ { readonly local: object } | { readonly worker: object }
141
+ >,
142
+ ): Reference => {
143
+ if (input.transport !== undefined) return input.transport
144
+ if (input.url !== undefined)
145
+ return capability("host", "websocket", {
146
+ url: input.url,
147
+ ...(input.ca === undefined ? {} : { ca: input.ca }),
148
+ ...(input.servername === undefined
149
+ ? {}
150
+ : { servername: input.servername }),
151
+ })
152
+ if (input.unix !== undefined)
153
+ return capability("host", "unix", { path: input.unix })
154
+ return capability("host", "command", {
155
+ argv: input.command,
156
+ ...("cwd" in input && input.cwd !== undefined ? { cwd: input.cwd } : {}),
157
+ ...("env" in input && input.env !== undefined ? { env: input.env } : {}),
158
+ })
159
+ }
160
+ export const runnerTransport = (input: Listen): Reference => {
161
+ if (input.transport !== undefined) return input.transport
162
+ if (input.url !== undefined)
163
+ return capability("runner", "websocket", {
164
+ url: input.url,
165
+ ...(input.cert === undefined ? {} : { cert: input.cert }),
166
+ ...(input.key === undefined ? {} : { key: input.key }),
167
+ })
168
+ if (input.unix !== undefined)
169
+ return capability("runner", "unix", { path: input.unix })
170
+ return capability("runner", "stdio", {})
171
+ }
172
+ export const Host = Schema.Struct({
173
+ contract: Schema.String,
174
+ connect: Connect,
175
+ config: Schema.Json.pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
176
+ })
177
+ export const Runner = Schema.Struct({
178
+ root: Schema.String,
179
+ state: Schema.String,
180
+ lease: Schema.optionalKey(PositiveDuration),
181
+ grace: Schema.optionalKey(PositiveDuration),
182
+ listen: Schema.Array(Listen),
183
+ })
184
+
185
+ export const runnerAuthentication = (input: Listen): Reference =>
186
+ input.stdio !== undefined
187
+ ? capability("runner", "auth/none", {
188
+ identity: input.identity ?? "anonymous",
189
+ })
190
+ : authentication("runner", input.auth)
@@ -0,0 +1,121 @@
1
+ import { Plugin } from "@graftland/graft"
2
+ import { Array, Cause, Effect, Fiber, Schema, Scope } from "effect"
3
+ import { SecureRandom } from "effect/crypto"
4
+ import type {
5
+ LocalTarget as Local,
6
+ WorkerTarget as Worker,
7
+ } from "./runner/Connection"
8
+ import { Connector } from "../Transport"
9
+ import { LocalTransport, WorkerTransport } from "./directTransport"
10
+ import { Credentials } from "../Auth"
11
+ import type { Duration } from "effect"
12
+ import * as Connection from "./runner/Connection"
13
+ import * as Services from "./services"
14
+ import * as Host from "./host"
15
+ import { RemoteWithdrawn, RemoteError, MissingInstance } from "../Errors"
16
+ import * as Contract from "../Contract"
17
+ import * as Control from "./control"
18
+
19
+ export interface ExecutionOptions {
20
+ readonly contractModule: string
21
+ readonly shutdownTimeout?: Duration.Input | undefined
22
+ }
23
+
24
+ const dependencies = (
25
+ target: Local | Worker | Connection.ConfiguredRunner,
26
+ ): ReadonlyArray<Plugin.Dependency> =>
27
+ target._tag === "Connector"
28
+ ? [Connector, Credentials]
29
+ : target._tag === "Local"
30
+ ? [LocalTransport]
31
+ : [WorkerTransport]
32
+
33
+ /** One owned execution per activation, with explicitly mapped services. */
34
+ export const executionPlugin = <
35
+ S extends Schema.Top & {
36
+ readonly Encoded: Schema.Json
37
+ readonly DecodingServices: never
38
+ readonly EncodingServices: never
39
+ },
40
+ E extends Schema.Top & {
41
+ readonly DecodingServices: never
42
+ readonly EncodingServices: never
43
+ },
44
+ >(
45
+ contract: Contract.Contract<S, E>,
46
+ options: ExecutionOptions,
47
+ configured: Local | Worker | Connection.ConfiguredRunner,
48
+ annotations: Readonly<Record<string, unknown>> = {},
49
+ ): Plugin.Plugin<
50
+ S["Encoded"],
51
+ S["Encoded"],
52
+ | E["Type"]
53
+ | Contract.UndeclaredFailure
54
+ | RemoteError
55
+ | RemoteWithdrawn
56
+ | MissingInstance
57
+ > =>
58
+ Plugin.make({
59
+ name: contract.name,
60
+ inject: [
61
+ SecureRandom.SecureRandom,
62
+ ...dependencies(configured),
63
+ ...Array.map(contract.inject, (service) => service.key),
64
+ ],
65
+ config: Schema.toEncoded(contract.config),
66
+ apply: (input) =>
67
+ Effect.gen(function* () {
68
+ const random = yield* SecureRandom.SecureRandom
69
+ const session = yield* random.uuidV4()
70
+ const active = yield* Connection.acquire(
71
+ configured,
72
+ options.contractModule,
73
+ {
74
+ session,
75
+ serve: Services.endpoints(contract.inject),
76
+ call: {
77
+ ...Services.endpoints(contract.provides),
78
+ [Control.endpoint]: contract.control,
79
+ },
80
+ },
81
+ Host.initialize(contract),
82
+ Host.dispose,
83
+ options.shutdownTimeout ?? "5 seconds",
84
+ )
85
+ yield* Host.load(active, input)
86
+ for (const service of contract.provides)
87
+ yield* service
88
+ .publish(active.connection.transport)
89
+ .pipe(Scope.provide(active.connection.resources))
90
+ yield* Plugin.fork(
91
+ Effect.raceFirst(
92
+ Fiber.join(active.events),
93
+ active.remoteFailure.await,
94
+ ).pipe(
95
+ Effect.mapError((error) => publicError(contract.error, error)),
96
+ ),
97
+ )
98
+ return () => Effect.succeed(false)
99
+ }).pipe(
100
+ Effect.annotateLogs(annotations),
101
+ Effect.mapError((error) => publicError(contract.error, error)),
102
+ ),
103
+ })
104
+
105
+ export const publicError = <E extends Schema.Top>(
106
+ declared: E,
107
+ error: unknown,
108
+ ):
109
+ | E["Type"]
110
+ | Contract.UndeclaredFailure
111
+ | RemoteWithdrawn
112
+ | RemoteError
113
+ | MissingInstance =>
114
+ Schema.is(declared)(error)
115
+ ? error
116
+ : Schema.is(Contract.UndeclaredFailure)(error) ||
117
+ Schema.is(RemoteWithdrawn)(error) ||
118
+ Schema.is(RemoteError)(error) ||
119
+ Schema.is(MissingInstance)(error)
120
+ ? error
121
+ : RemoteError.make({ cause: Cause.fail(error) })
@@ -0,0 +1,17 @@
1
+ import { Plugin, type Fork, type Graft } from "@graftland/graft"
2
+ import { Effect, Stream, type Cause, type Schema } from "effect"
3
+
4
+ /** Follow startup and later failures without changing the caller's error boundary. */
5
+ export const follow = Effect.fnUntraced(function* <I, E, F>(
6
+ fork: Fork.Fork<I, E>,
7
+ fail: (cause: Cause.Cause<E | Schema.SchemaError>) => Effect.Effect<never, F>,
8
+ ): Effect.fn.Return<void, F, Graft.Graft | Plugin.Tasks<F>> {
9
+ yield* fork.await.pipe(Effect.catchCause(fail))
10
+ yield* Plugin.fork(
11
+ fork.state.pipe(
12
+ Stream.runForEach((state) =>
13
+ state._tag === "Failed" ? fail(state.cause) : Effect.void,
14
+ ),
15
+ ),
16
+ )
17
+ })
@@ -0,0 +1,13 @@
1
+ import type { Fork } from "@graftland/graft"
2
+ import { Array, Option } from "effect"
3
+
4
+ export const findSubtree = (
5
+ trees: ReadonlyArray<Fork.ForkTree>,
6
+ id: number,
7
+ ): Option.Option<Fork.ForkTree> =>
8
+ Array.findFirst(trees, (tree) =>
9
+ tree.id === id ? Option.some(tree) : findSubtree(tree.children, id),
10
+ )
11
+
12
+ export const isSubtreeActive = (tree: Fork.ForkTree): boolean =>
13
+ tree.state._tag === "Active" && Array.every(tree.children, isSubtreeActive)