@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.
Files changed (184) hide show
  1. package/dist/Auth.d.ts +2 -2
  2. package/dist/Auth.d.ts.map +1 -1
  3. package/dist/Auth.js.map +1 -1
  4. package/dist/{Bootstrap-Dr6sX7el.js → Bootstrap-H9gDsgsC.js} +2 -2
  5. package/dist/{Contract-DL2mHvaT.js → Contract-DsJtisvL.js} +2 -2
  6. package/dist/Contract.js +1 -1
  7. package/dist/{Errors-BMKmu5Y7.js → Errors-DYhsGZcZ.js} +3 -1
  8. package/dist/Errors.d.ts +7 -0
  9. package/dist/Errors.d.ts.map +1 -1
  10. package/dist/Errors.js +3 -1
  11. package/dist/Errors.js.map +1 -1
  12. package/dist/{FailureGroup-BcH0XOBi.js → FailureGroup-BgT73AaR.js} +14 -4
  13. package/dist/{Framing-zaYdOJnT.js → Framing-G9eSaeLb.js} +1 -1
  14. package/dist/{Graft-CVyueNOf.js → Graft-B71CPA2Y.js} +20 -16
  15. package/dist/{Packages-JNL34JpS.js → Packages-AgoCGotL.js} +23 -26
  16. package/dist/{Peer-BT7eAGmh.js → Peer-DXeVrGBh.js} +5 -5
  17. package/dist/{ProcessObservation-DEGrEMfP.js → ProcessObservation-gLgGirYv.js} +1 -1
  18. package/dist/{ServeLifecycle-CJM0gG5B.js → ServeLifecycle-Bd1FPJ6e.js} +1 -1
  19. package/dist/Transport.d.ts +2 -2
  20. package/dist/Transport.d.ts.map +1 -1
  21. package/dist/Transport.js.map +1 -1
  22. package/dist/bin.js +48 -47
  23. package/dist/bin.js.map +1 -1
  24. package/dist/{childRuntime-An0HsIzl.js → childRuntime-Bm3iSg_N.js} +29 -26
  25. package/dist/{connectionEnded-DCpFCjMX.js → connectionEnded-BwcxQ7W8.js} +4 -4
  26. package/dist/{entry-B89sepMU.js → entry-psOpX3Bj.js} +72 -35
  27. package/dist/host/auth/bearer.d.ts +9 -1
  28. package/dist/host/auth/bearer.d.ts.map +1 -1
  29. package/dist/host/auth/bearer.js +1 -1
  30. package/dist/host/auth/jwt.d.ts +9 -1
  31. package/dist/host/auth/jwt.d.ts.map +1 -1
  32. package/dist/host/auth/jwt.js +1 -1
  33. package/dist/host/auth/mtls.d.ts +8 -1
  34. package/dist/host/auth/mtls.d.ts.map +1 -1
  35. package/dist/host/auth/mtls.js +2 -2
  36. package/dist/host/auth/none.d.ts +3 -1
  37. package/dist/host/auth/none.js +1 -1
  38. package/dist/host/command.d.ts +14 -1
  39. package/dist/host/command.d.ts.map +1 -1
  40. package/dist/host/command.js +4 -4
  41. package/dist/host/local.d.ts +2 -1
  42. package/dist/host/local.d.ts.map +1 -1
  43. package/dist/host/local.js +3 -3
  44. package/dist/host/unix.d.ts +6 -1
  45. package/dist/host/unix.d.ts.map +1 -1
  46. package/dist/host/unix.js +3 -3
  47. package/dist/host/websocket.d.ts +10 -1
  48. package/dist/host/websocket.d.ts.map +1 -1
  49. package/dist/host/websocket.js +3 -3
  50. package/dist/host/worker.d.ts +3 -1
  51. package/dist/host/worker.d.ts.map +1 -1
  52. package/dist/host/worker.js +4 -5
  53. package/dist/{importer-Bk6U_sn4.js → importer-Cvf88eAY.js} +5 -8
  54. package/dist/index.js +9 -9
  55. package/dist/index.js.map +1 -1
  56. package/dist/internal/Certificates.js +4 -4
  57. package/dist/internal/Certificates.js.map +1 -1
  58. package/dist/internal/FailureGroup.js +3 -2
  59. package/dist/internal/FailureGroup.js.map +1 -1
  60. package/dist/internal/assembly.d.ts +2 -1
  61. package/dist/internal/assembly.js +9 -2
  62. package/dist/internal/assembly.js.map +1 -1
  63. package/dist/internal/auth/mtls.js +1 -1
  64. package/dist/internal/auth/mtls.js.map +1 -1
  65. package/dist/internal/auth/tokenCredentials.d.ts +2 -1
  66. package/dist/internal/auth/tokenCredentials.d.ts.map +1 -1
  67. package/dist/internal/child.js +20 -17
  68. package/dist/internal/child.js.map +1 -1
  69. package/dist/internal/childRuntime.js +4 -4
  70. package/dist/internal/childRuntime.js.map +1 -1
  71. package/dist/internal/credentials.d.ts +1 -1
  72. package/dist/internal/directTransport.d.ts +1 -1
  73. package/dist/internal/entry.d.ts +415 -3
  74. package/dist/internal/entry.d.ts.map +1 -1
  75. package/dist/internal/entry.js +1 -1
  76. package/dist/internal/entry.js.map +1 -1
  77. package/dist/internal/execution.js +40 -5
  78. package/dist/internal/execution.js.map +1 -1
  79. package/dist/internal/host/runner.js +7 -6
  80. package/dist/internal/host/runner.js.map +1 -1
  81. package/dist/internal/host.js +5 -5
  82. package/dist/internal/host.js.map +1 -1
  83. package/dist/internal/port.js +5 -5
  84. package/dist/internal/port.js.map +1 -1
  85. package/dist/internal/release.js +1 -1
  86. package/dist/internal/release.js.map +1 -1
  87. package/dist/internal/runner/Connection.d.ts +1 -1
  88. package/dist/internal/runner/Connection.js +4 -4
  89. package/dist/internal/runner/Connection.js.map +1 -1
  90. package/dist/internal/runner/Execution.js +3 -3
  91. package/dist/internal/runner/Execution.js.map +1 -1
  92. package/dist/internal/runner/Framing.js +1 -1
  93. package/dist/internal/runner/Framing.js.map +1 -1
  94. package/dist/internal/runner/Local.js +1 -1
  95. package/dist/internal/runner/Local.js.map +1 -1
  96. package/dist/internal/runner/Lock.js +1 -1
  97. package/dist/internal/runner/Lock.js.map +1 -1
  98. package/dist/internal/runner/Packages.d.ts +1 -1
  99. package/dist/internal/runner/Packages.js +22 -25
  100. package/dist/internal/runner/Packages.js.map +1 -1
  101. package/dist/internal/runner/Processes.js +7 -9
  102. package/dist/internal/runner/Processes.js.map +1 -1
  103. package/dist/internal/runner/Store.js +3 -3
  104. package/dist/internal/runner/Store.js.map +1 -1
  105. package/dist/internal/runner/Supervisor.js +46 -47
  106. package/dist/internal/runner/Supervisor.js.map +1 -1
  107. package/dist/internal/runner/accept.js +3 -3
  108. package/dist/internal/runner/accept.js.map +1 -1
  109. package/dist/internal/runner/model.js +1 -1
  110. package/dist/internal/runner/model.js.map +1 -1
  111. package/dist/internal/serve.js +1 -1
  112. package/dist/internal/serve.js.map +1 -1
  113. package/dist/internal/supervisorPlugin.js +1 -1
  114. package/dist/internal/watchdogMain.js +5 -5
  115. package/dist/internal/watchdogMain.js.map +1 -1
  116. package/dist/internal/websocketServer.js +3 -1
  117. package/dist/internal/websocketServer.js.map +1 -1
  118. package/dist/internal/workerMain.js +3 -3
  119. package/dist/{port-DSVUY8Bq.js → port--3x2zJ4D.js} +8 -8
  120. package/dist/{release-BY4Mlluy.js → release-DfZPuIcK.js} +1 -1
  121. package/dist/runner/auth/bearer.d.ts +6 -1
  122. package/dist/runner/auth/bearer.d.ts.map +1 -1
  123. package/dist/runner/auth/bearer.js +2 -2
  124. package/dist/runner/auth/jwt.d.ts +29 -2
  125. package/dist/runner/auth/jwt.d.ts.map +1 -1
  126. package/dist/runner/auth/jwt.js +4 -4
  127. package/dist/runner/auth/jwt.js.map +1 -1
  128. package/dist/runner/auth/mtls.d.ts +6 -1
  129. package/dist/runner/auth/mtls.d.ts.map +1 -1
  130. package/dist/runner/auth/mtls.js +3 -3
  131. package/dist/runner/auth/none.d.ts +7 -1
  132. package/dist/runner/auth/none.js +1 -1
  133. package/dist/runner/index.d.ts +310 -1
  134. package/dist/runner/index.d.ts.map +1 -1
  135. package/dist/runner/index.js +5 -5
  136. package/dist/runner/stdio.d.ts +6 -1
  137. package/dist/runner/stdio.d.ts.map +1 -1
  138. package/dist/runner/stdio.js +3 -3
  139. package/dist/runner/unix.d.ts +6 -1
  140. package/dist/runner/unix.d.ts.map +1 -1
  141. package/dist/runner/unix.js +3 -3
  142. package/dist/runner/websocket.d.ts +24 -1
  143. package/dist/runner/websocket.d.ts.map +1 -1
  144. package/dist/runner/websocket.js +4 -4
  145. package/dist/{socketChannel-C_ppdSzz.js → socketChannel-CJvL2DiB.js} +2 -2
  146. package/dist/{supervisorPlugin-CivhM7x5.js → supervisorPlugin-t6Z6PrhD.js} +72 -76
  147. package/dist/{token-Cc_1CTbE.js → token-CYBNNlhS.js} +1 -1
  148. package/dist/{tokenCredentials-CI6mMRRd.js → tokenCredentials-CbCuk-Rt.js} +3 -3
  149. package/dist/{websocketServer-D2Hk7wsA.js → websocketServer-NQhODlEt.js} +5 -3
  150. package/dist/{workerChannel-cmLc13vm.js → workerChannel-C8hhBJzA.js} +1 -1
  151. package/package.json +4 -4
  152. package/src/Auth.ts +9 -2
  153. package/src/Errors.ts +8 -0
  154. package/src/Transport.ts +6 -2
  155. package/src/bin.ts +28 -30
  156. package/src/index.ts +5 -3
  157. package/src/internal/Certificates.ts +10 -13
  158. package/src/internal/FailureGroup.ts +128 -121
  159. package/src/internal/assembly.ts +19 -10
  160. package/src/internal/auth/mtls.ts +19 -20
  161. package/src/internal/child.ts +248 -239
  162. package/src/internal/childRuntime.ts +81 -80
  163. package/src/internal/entry.ts +10 -11
  164. package/src/internal/execution.ts +69 -12
  165. package/src/internal/host/runner.ts +153 -153
  166. package/src/internal/host.ts +116 -120
  167. package/src/internal/port.ts +100 -103
  168. package/src/internal/release.ts +3 -2
  169. package/src/internal/runner/Connection.ts +52 -60
  170. package/src/internal/runner/Execution.ts +163 -164
  171. package/src/internal/runner/Framing.ts +9 -10
  172. package/src/internal/runner/Local.ts +26 -27
  173. package/src/internal/runner/Lock.ts +23 -25
  174. package/src/internal/runner/Packages.ts +67 -70
  175. package/src/internal/runner/Processes.ts +89 -92
  176. package/src/internal/runner/Store.ts +110 -114
  177. package/src/internal/runner/Supervisor.ts +392 -405
  178. package/src/internal/runner/accept.ts +76 -84
  179. package/src/internal/runner/model.ts +20 -21
  180. package/src/internal/serve.ts +15 -13
  181. package/src/internal/watchdogMain.ts +16 -11
  182. package/src/internal/websocketServer.ts +18 -3
  183. package/src/runner/auth/jwt.ts +10 -6
  184. package/dist/cleanup-CXLa1Wd9.js +0 -13
@@ -1 +1 @@
1
- {"version":3,"file":"Execution.js","names":["Processes.recover","Packages.resolve","ProcessObservation.observe","FailureGroup.make","Multiplex.make","identity","Processes.identity"],"sources":["../../../src/internal/runner/Execution.ts"],"sourcesContent":["import * as ProcessObservation from \"./ProcessObservation\"\nimport * as FailureGroup from \"../FailureGroup\"\nimport { Command, CommandJson } from \"./WatchdogProtocol\"\nimport {\n\tArray,\n\tCause,\n\tFileSystem,\n\tPath,\n\tSchema,\n\tContext,\n\tEffect,\n\tHashMap,\n\tHashSet,\n\tQueue,\n\tRef,\n\tSink,\n\tStream,\n\tLayer,\n\tScope,\n} from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\"\nimport { TransportError } from \"../../Errors\"\nimport * as Multiplex from \"./Multiplex\"\nimport * as Packages from \"./Packages\"\nimport * as Processes from \"./Processes\"\nimport {\n\tExecution,\n\tExecutionError,\n\tSessionConflict,\n\tSessionStopped,\n} from \"./model\"\nimport { Bootstrap } from \"./Bootstrap\"\nimport { command } from \"./command\"\n\nexport class Channels extends Context.Service<\n\tChannels,\n\t{\n\t\treadonly peer: (\n\t\t\ttoken: string,\n\t\t) => Effect.Effect<\n\t\t\tMultiplex.Peer,\n\t\t\tSessionStopped | SessionConflict,\n\t\t\tScope.Scope\n\t\t>\n\t}\n>()(\"@graftland/plugin-remote/internal/runner/Execution/Channels\") {}\n\nexport const make = (root: string) =>\n\tEffect.gen(function* () {\n\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n\t\tconst fs = yield* FileSystem.FileSystem\n\t\tconst path = yield* Path.Path\n\t\tconst platform = Context.make(\n\t\t\tChildProcessSpawner.ChildProcessSpawner,\n\t\t\tspawner,\n\t\t).pipe(Context.add(FileSystem.FileSystem, fs), Context.add(Path.Path, path))\n\n\t\tconst peers = yield* Ref.make(HashMap.empty<string, Multiplex.Peer>())\n\t\tconst claimed = yield* Ref.make(HashSet.empty<string>())\n\t\tconst driver = Execution.of({\n\t\t\trecover: (child) =>\n\t\t\t\tProcesses.recover(child).pipe(Effect.provideContext(platform)),\n\t\t\tspawn: (handle, request, limits) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconst resolved = yield* Packages.resolve(\n\t\t\t\t\t\troot,\n\t\t\t\t\t\trequest.specifier,\n\t\t\t\t\t\trequest.digest,\n\t\t\t\t\t)\n\t\t\t\t\tconst argv = yield* command()\n\t\t\t\t\tconst child = yield* spawner.spawn(\n\t\t\t\t\t\tChildProcess.make(\n\t\t\t\t\t\t\targv[0],\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t...Array.drop(argv, 1),\n\t\t\t\t\t\t\t\t\"child\",\n\t\t\t\t\t\t\t\tresolved.entry,\n\t\t\t\t\t\t\t\thandle.token,\n\t\t\t\t\t\t\t\tyield* Schema.encodeEffect(Schema.fromJsonString(Bootstrap))({\n\t\t\t\t\t\t\t\t\tidentity: {\n\t\t\t\t\t\t\t\t\t\tid: handle.key.instance,\n\t\t\t\t\t\t\t\t\t\tgeneration: handle.generation,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tlimits,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstdin: \"pipe\",\n\t\t\t\t\t\t\t\tstdout: \"pipe\",\n\t\t\t\t\t\t\t\tstderr: \"pipe\",\n\t\t\t\t\t\t\t\tadditionalFds: {\n\t\t\t\t\t\t\t\t\tfd3: { type: \"output\" },\n\t\t\t\t\t\t\t\t\tfd4: { type: \"input\" },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tforceKillAfter: \"1 second\",\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\tconst observation = yield* ProcessObservation.observe(child)\n\t\t\t\t\tconst exited = observation.exited.pipe(\n\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\tdetail: \"Observing child exit failed\",\n\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tconst failures = yield* FailureGroup.make<ExecutionError>()\n\t\t\t\t\tyield* failures.run(\n\t\t\t\t\t\tobservation.failure.pipe(\n\t\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\tdetail: \"Reading child output failed\",\n\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tconst controls = yield* Queue.bounded<string>(4)\n\n\t\t\t\t\tyield* failures.run(\n\t\t\t\t\t\tStream.fromQueue(controls).pipe(\n\t\t\t\t\t\t\tStream.map((line) => new TextEncoder().encode(line + \"\\n\")),\n\t\t\t\t\t\t\tStream.run(child.getInputFd(4)),\n\t\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\tdetail: \"Child supervision channel failed\",\n\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tconst send = (value: typeof Command.Type) =>\n\t\t\t\t\t\tEffect.raceFirst(\n\t\t\t\t\t\t\tSchema.encodeEffect(CommandJson)(value).pipe(\n\t\t\t\t\t\t\t\tEffect.flatMap((line) => Queue.offer(controls, line)),\n\t\t\t\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\t\tdetail: \"Encoding watchdog command failed\",\n\t\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tfailures.await,\n\t\t\t\t\t\t)\n\t\t\t\t\tconst peer = yield* Multiplex.make({\n\t\t\t\t\t\tinput: child\n\t\t\t\t\t\t\t.getOutputFd(3)\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tStream.mapError((error) =>\n\t\t\t\t\t\t\t\t\tTransportError.make({ cause: Cause.fail(error) }),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\toutput: child.stdin.pipe(\n\t\t\t\t\t\t\tSink.mapError((error) =>\n\t\t\t\t\t\t\t\tTransportError.make({ cause: Cause.fail(error) }),\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\tconst identity = yield* Processes.identity(child.pid)\n\t\t\t\t\tyield* Ref.update(peers, HashMap.set(handle.token, peer))\n\t\t\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\t\t\tRef.update(peers, HashMap.remove(handle.token)),\n\t\t\t\t\t)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcode: resolved.identity,\n\t\t\t\t\t\tstart: send({ kind: \"start\" }),\n\t\t\t\t\t\tidentity,\n\t\t\t\t\t\texited,\n\t\t\t\t\t\tinterrupt: send({ kind: \"stop\" }),\n\t\t\t\t\t\tkill: child.kill({ killSignal: \"SIGKILL\" }).pipe(\n\t\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\tdetail: \"Killing the child failed\",\n\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\trenew: (millis: number) => send({ kind: \"renew\", millis }),\n\t\t\t\t\t}\n\t\t\t\t}).pipe(\n\t\t\t\t\tEffect.provideContext(platform),\n\t\t\t\t\tEffect.catchTags({\n\t\t\t\t\t\tPlatformError: (error) =>\n\t\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\tdetail: \"Starting the child failed\",\n\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\tSchemaError: (error) =>\n\t\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\tdetail: \"Encoding child bootstrap failed\",\n\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t})\n\t\treturn {\n\t\t\tdriver,\n\t\t\tpeer: (token: string) =>\n\t\t\t\tEffect.acquireRelease(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst peer = yield* Ref.get(peers).pipe(\n\t\t\t\t\t\t\tEffect.flatMap((all) => {\n\t\t\t\t\t\t\t\tconst peer = HashMap.get(all, token)\n\t\t\t\t\t\t\t\treturn peer._tag === \"Some\"\n\t\t\t\t\t\t\t\t\t? Effect.succeed(peer.value)\n\t\t\t\t\t\t\t\t\t: Effect.fail(\n\t\t\t\t\t\t\t\t\t\t\tSessionStopped.make({\n\t\t\t\t\t\t\t\t\t\t\t\tdetail: \"The execution channel is no longer available\",\n\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\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\tconst occupied = yield* Ref.modify(\n\t\t\t\t\t\t\tclaimed,\n\t\t\t\t\t\t\t(all) =>\n\t\t\t\t\t\t\t\t[HashSet.has(all, token), HashSet.add(all, token)] as const,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (occupied)\n\t\t\t\t\t\t\treturn yield* SessionConflict.make({\n\t\t\t\t\t\t\t\tdetail: \"The instance channel is already attached\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\treturn peer\n\t\t\t\t\t}),\n\t\t\t\t\t() => Ref.update(claimed, HashSet.remove(token)),\n\t\t\t\t),\n\t\t}\n\t})\n\nexport const layer = (root: string) =>\n\tLayer.effectContext(\n\t\tmake(root).pipe(\n\t\t\tEffect.map((execution) =>\n\t\t\t\tContext.make(Execution, execution.driver).pipe(\n\t\t\t\t\tContext.add(Channels, { peer: execution.peer }),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t)\n"],"mappings":"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"}
1
+ {"version":3,"file":"Execution.js","names":["Processes.recover","Packages.resolve","ProcessObservation.observe","FailureGroup.make","Multiplex.make","identity","Processes.identity"],"sources":["../../../src/internal/runner/Execution.ts"],"sourcesContent":["import * as ProcessObservation from \"./ProcessObservation\"\nimport * as FailureGroup from \"../FailureGroup\"\nimport { Command, CommandJson } from \"./WatchdogProtocol\"\nimport {\n\tArray,\n\tCause,\n\tFileSystem,\n\tPath,\n\tSchema,\n\tContext,\n\tEffect,\n\tHashMap,\n\tHashSet,\n\tQueue,\n\tRef,\n\tSink,\n\tStream,\n\tLayer,\n\tScope,\n} from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\"\nimport { TransportError } from \"../../Errors\"\nimport * as Multiplex from \"./Multiplex\"\nimport * as Packages from \"./Packages\"\nimport * as Processes from \"./Processes\"\nimport {\n\tExecution,\n\tExecutionError,\n\tSessionConflict,\n\tSessionStopped,\n} from \"./model\"\nimport { Bootstrap } from \"./Bootstrap\"\nimport { command } from \"./command\"\n\nexport class Channels extends Context.Service<\n\tChannels,\n\t{\n\t\treadonly peer: (\n\t\t\ttoken: string,\n\t\t) => Effect.Effect<\n\t\t\tMultiplex.Peer,\n\t\t\tSessionStopped | SessionConflict,\n\t\t\tScope.Scope\n\t\t>\n\t}\n>()(\"@graftland/plugin-remote/internal/runner/Execution/Channels\") {}\n\nexport const make = Effect.fnUntraced(function* (root: string) {\n\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tconst platform = Context.make(\n\t\tChildProcessSpawner.ChildProcessSpawner,\n\t\tspawner,\n\t).pipe(Context.add(FileSystem.FileSystem, fs), Context.add(Path.Path, path))\n\n\tconst peers = yield* Ref.make(HashMap.empty<string, Multiplex.Peer>())\n\tconst claimed = yield* Ref.make(HashSet.empty<string>())\n\tconst driver = Execution.of({\n\t\trecover: (child) =>\n\t\t\tProcesses.recover(child).pipe(Effect.provideContext(platform)),\n\t\tspawn: Effect.fnUntraced(\n\t\t\tfunction* (handle, request, limits) {\n\t\t\t\tconst resolved = yield* Packages.resolve(\n\t\t\t\t\troot,\n\t\t\t\t\trequest.specifier,\n\t\t\t\t\trequest.digest,\n\t\t\t\t)\n\t\t\t\tconst argv = yield* command()\n\t\t\t\tconst child = yield* spawner.spawn(\n\t\t\t\t\tChildProcess.make(\n\t\t\t\t\t\targv[0],\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t...Array.drop(argv, 1),\n\t\t\t\t\t\t\t\"child\",\n\t\t\t\t\t\t\tresolved.entry,\n\t\t\t\t\t\t\thandle.token,\n\t\t\t\t\t\t\tyield* Schema.encodeEffect(Schema.fromJsonString(Bootstrap))({\n\t\t\t\t\t\t\t\tidentity: {\n\t\t\t\t\t\t\t\t\tid: handle.key.instance,\n\t\t\t\t\t\t\t\t\tgeneration: handle.generation,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tlimits,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t],\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstdin: \"pipe\",\n\t\t\t\t\t\t\tstdout: \"pipe\",\n\t\t\t\t\t\t\tstderr: \"pipe\",\n\t\t\t\t\t\t\tadditionalFds: {\n\t\t\t\t\t\t\t\tfd3: { type: \"output\" },\n\t\t\t\t\t\t\t\tfd4: { type: \"input\" },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tforceKillAfter: \"1 second\",\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tconst observation = yield* ProcessObservation.observe(child)\n\t\t\t\tconst exited = observation.exited.pipe(\n\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\tdetail: \"Observing child exit failed\",\n\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tconst failures = yield* FailureGroup.make<ExecutionError>()\n\t\t\t\tyield* failures.run(\n\t\t\t\t\tobservation.failure.pipe(\n\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\tdetail: \"Reading child output failed\",\n\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tconst controls = yield* Queue.bounded<string>(4)\n\n\t\t\t\tyield* failures.run(\n\t\t\t\t\tStream.fromQueue(controls).pipe(\n\t\t\t\t\t\tStream.map((line) => new TextEncoder().encode(line + \"\\n\")),\n\t\t\t\t\t\tStream.run(child.getInputFd(4)),\n\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\tdetail: \"Child supervision channel failed\",\n\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tconst send = (value: typeof Command.Type) =>\n\t\t\t\t\tEffect.raceFirst(\n\t\t\t\t\t\tSchema.encodeEffect(CommandJson)(value).pipe(\n\t\t\t\t\t\t\tEffect.flatMap((line) => Queue.offer(controls, line)),\n\t\t\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\t\tdetail: \"Encoding watchdog command failed\",\n\t\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\tfailures.await,\n\t\t\t\t\t)\n\t\t\t\tconst peer = yield* Multiplex.make({\n\t\t\t\t\tinput: child\n\t\t\t\t\t\t.getOutputFd(3)\n\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\tStream.mapError((error) =>\n\t\t\t\t\t\t\t\tTransportError.make({ cause: Cause.fail(error) }),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\toutput: child.stdin.pipe(\n\t\t\t\t\t\tSink.mapError((error) =>\n\t\t\t\t\t\t\tTransportError.make({ cause: Cause.fail(error) }),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t})\n\t\t\t\tconst identity = yield* Processes.identity(child.pid)\n\t\t\t\tyield* Ref.update(peers, HashMap.set(handle.token, peer))\n\t\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\t\tRef.update(peers, HashMap.remove(handle.token)),\n\t\t\t\t)\n\t\t\t\treturn {\n\t\t\t\t\tcode: resolved.identity,\n\t\t\t\t\tstart: send({ kind: \"start\" }),\n\t\t\t\t\tidentity,\n\t\t\t\t\texited,\n\t\t\t\t\tinterrupt: send({ kind: \"stop\" }),\n\t\t\t\t\tkill: child.kill({ killSignal: \"SIGKILL\" }).pipe(\n\t\t\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\t\tdetail: \"Killing the child failed\",\n\t\t\t\t\t\t\t\tcause: Cause.fail(error),\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\trenew: (millis: number) => send({ kind: \"renew\", millis }),\n\t\t\t\t}\n\t\t\t},\n\t\t\tEffect.provideContext(platform),\n\t\t\tEffect.catchTags({\n\t\t\t\tPlatformError: (error) =>\n\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\tdetail: \"Starting the child failed\",\n\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\tSchemaError: (error) =>\n\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\t\tdetail: \"Encoding child bootstrap failed\",\n\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t})\n\treturn {\n\t\tdriver,\n\t\tpeer: (token: string) =>\n\t\t\tEffect.acquireRelease(\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconst peer = yield* Ref.get(peers).pipe(\n\t\t\t\t\t\tEffect.flatMap((all) => {\n\t\t\t\t\t\t\tconst peer = HashMap.get(all, token)\n\t\t\t\t\t\t\treturn peer._tag === \"Some\"\n\t\t\t\t\t\t\t\t? Effect.succeed(peer.value)\n\t\t\t\t\t\t\t\t: Effect.fail(\n\t\t\t\t\t\t\t\t\t\tSessionStopped.make({\n\t\t\t\t\t\t\t\t\t\t\tdetail: \"The execution channel is no longer available\",\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\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\tconst occupied = yield* Ref.modify(\n\t\t\t\t\t\tclaimed,\n\t\t\t\t\t\t(all) =>\n\t\t\t\t\t\t\t[HashSet.has(all, token), HashSet.add(all, token)] as const,\n\t\t\t\t\t)\n\t\t\t\t\tif (occupied)\n\t\t\t\t\t\treturn yield* SessionConflict.make({\n\t\t\t\t\t\t\tdetail: \"The instance channel is already attached\",\n\t\t\t\t\t\t})\n\t\t\t\t\treturn peer\n\t\t\t\t}),\n\t\t\t\t() => Ref.update(claimed, HashSet.remove(token)),\n\t\t\t),\n\t}\n})\n\nexport const layer = (root: string) =>\n\tLayer.effectContext(\n\t\tmake(root).pipe(\n\t\t\tEffect.map((execution) =>\n\t\t\t\tContext.make(Execution, execution.driver).pipe(\n\t\t\t\t\tContext.add(Channels, { peer: execution.peer }),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t)\n"],"mappings":"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"}
@@ -14,7 +14,7 @@ var EndOfStream = class extends Schema.TaggedError()("RunnerEndOfStream", {}) {
14
14
  const maxPayload = 1048576;
15
15
  const invalid = (detail) => FrameError.make({ detail });
16
16
  /** Version 2 carries only channel and length; request admission belongs to port. */
17
- const encode = (frame) => Effect.gen(function* () {
17
+ const encode = Effect.fnUntraced(function* (frame) {
18
18
  if (frame.payload.byteLength > 1048576) return yield* invalid("Runner frame exceeds the payload limit");
19
19
  const bytes = new Uint8Array(8 + frame.payload.byteLength);
20
20
  bytes.set([
@@ -1 +1 @@
1
- {"version":3,"file":"Framing.js","names":[],"sources":["../../../src/internal/runner/Framing.ts"],"sourcesContent":["import { Array, Effect, MutableRef, Option, Result, Schema } from \"effect\"\n\nexport class FrameError extends Schema.TaggedError<\n\tFrameError,\n\t{ readonly brand: unique symbol }\n>()(\"FrameError\", { detail: Schema.String }) {\n\toverride get message() {\n\t\treturn this.detail\n\t}\n}\n/** A complete byte stream ended; malformed trailing bytes remain FrameError. */\nexport class EndOfStream extends Schema.TaggedError<\n\tEndOfStream,\n\t{ readonly brand: unique symbol }\n>()(\"RunnerEndOfStream\", {}) {\n\toverride get message() {\n\t\treturn \"Runner byte channel ended\"\n\t}\n}\nexport type Channel = 0 | 1\nexport interface Frame {\n\treadonly channel: Channel\n\treadonly payload: Uint8Array\n}\nexport const headerSize = 8\nexport const maxPayload = 1024 * 1024\nconst invalid = (detail: string) => FrameError.make({ detail })\n\n/** Version 2 carries only channel and length; request admission belongs to port. */\nexport const encode = (frame: Frame) =>\n\tEffect.gen(function* () {\n\t\tif (frame.payload.byteLength > maxPayload)\n\t\t\treturn yield* invalid(\"Runner frame exceeds the payload limit\")\n\t\tconst bytes = new Uint8Array(headerSize + frame.payload.byteLength)\n\t\tbytes.set([2, frame.channel, 0, 0])\n\t\tnew DataView(bytes.buffer).setUint32(4, frame.payload.byteLength)\n\t\tbytes.set(frame.payload, headerSize)\n\t\treturn bytes\n\t})\n\n/** Check a message boundary; the decoder still validates the frame's contents. */\nexport const isCompleteFrame = (bytes: Uint8Array): boolean =>\n\tbytes.byteLength >= headerSize &&\n\tnew DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(\n\t\t4,\n\t) ===\n\t\tbytes.byteLength - headerSize\n\n/** The decoder owns its byte buffer. Results expose malformed frames without throwing through a generator. */\nexport const decoder = () => {\n\tconst pending = MutableRef.make<Result.Result<Uint8Array, FrameError>>(\n\t\tResult.succeed(new Uint8Array(0)),\n\t)\n\tconst decode = (\n\t\tchunk: Uint8Array,\n\t): Result.Result<ReadonlyArray<Frame>, FrameError> =>\n\t\tResult.flatMap(MutableRef.get(pending), (previous) => {\n\t\t\tconst bytes = new Uint8Array(previous.length + chunk.length)\n\t\t\tbytes.set(previous)\n\t\t\tbytes.set(chunk, previous.length)\n\t\t\tconst frames = Array.unfold(\n\t\t\t\t0,\n\t\t\t\t(\n\t\t\t\t\toffset,\n\t\t\t\t): Option.Option<\n\t\t\t\t\treadonly [Result.Result<Frame, FrameError>, number]\n\t\t\t\t> => {\n\t\t\t\t\tif (bytes.length - offset < headerSize) return Option.none()\n\t\t\t\t\tconst header = new DataView(bytes.buffer, offset, headerSize)\n\t\t\t\t\tconst channel = header.getUint8(1)\n\t\t\t\t\tconst length = header.getUint32(4)\n\t\t\t\t\tif (\n\t\t\t\t\t\theader.getUint8(0) !== 2 ||\n\t\t\t\t\t\t(channel !== 0 && channel !== 1) ||\n\t\t\t\t\t\theader.getUint16(2) !== 0 ||\n\t\t\t\t\t\tlength > maxPayload\n\t\t\t\t\t)\n\t\t\t\t\t\treturn Option.some([\n\t\t\t\t\t\t\tResult.fail(\n\t\t\t\t\t\t\t\tinvalid(\"Invalid runner frame header or payload length\"),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tbytes.length,\n\t\t\t\t\t\t])\n\t\t\t\t\tconst end = offset + headerSize + length\n\t\t\t\t\tif (end > bytes.length) return Option.none()\n\t\t\t\t\treturn Option.some([\n\t\t\t\t\t\tResult.succeed({\n\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\tpayload: bytes.subarray(offset + headerSize, end),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tend,\n\t\t\t\t\t])\n\t\t\t\t},\n\t\t\t)\n\t\t\tconst result = Result.all(frames)\n\t\t\tMutableRef.set(\n\t\t\t\tpending,\n\t\t\t\tResult.map(result, (frames) =>\n\t\t\t\t\tbytes.subarray(\n\t\t\t\t\t\tArray.reduce(\n\t\t\t\t\t\t\tframes,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t(used, frame) => used + headerSize + frame.payload.length,\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\treturn result\n\t\t})\n\treturn {\n\t\tdecode,\n\t\tfinish: Effect.suspend(() =>\n\t\t\tEffect.fromResult(\n\t\t\t\tResult.flatMap(MutableRef.get(pending), (bytes) =>\n\t\t\t\t\tbytes.length === 0\n\t\t\t\t\t\t? Result.succeed(undefined)\n\t\t\t\t\t\t: Result.fail(invalid(\"Runner connection ended inside a frame\")),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t}\n}\n"],"mappings":";;AAEA,IAAa,aAAb,cAAgC,OAAO,YAGrC,CAAC,CAAC,cAAc,EAAE,QAAQ,OAAO,OAAO,CAAC,CAAC,CAAC;CAC5C,IAAa,UAAU;EACtB,OAAO,KAAK;CACb;AACD;;AAEA,IAAa,cAAb,cAAiC,OAAO,YAGtC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;CAC5B,IAAa,UAAU;EACtB,OAAO;CACR;AACD;AAOA,MAAa,aAAa;AAC1B,MAAM,WAAW,WAAmB,WAAW,KAAK,EAAE,OAAO,CAAC;;AAG9D,MAAa,UAAU,UACtB,OAAO,IAAI,aAAa;CACvB,IAAI,MAAM,QAAQ,aAAA,SACjB,OAAO,OAAO,QAAQ,wCAAwC;CAC/D,MAAM,QAAQ,IAAI,WAAA,IAAwB,MAAM,QAAQ,UAAU;CAClE,MAAM,IAAI;EAAC;EAAG,MAAM;EAAS;EAAG;CAAC,CAAC;CAClC,IAAI,SAAS,MAAM,MAAM,CAAC,CAAC,UAAU,GAAG,MAAM,QAAQ,UAAU;CAChE,MAAM,IAAI,MAAM,SAAA,CAAmB;CACnC,OAAO;AACR,CAAC;;AAGF,MAAa,mBAAmB,UAC/B,MAAM,cAAA,KACN,IAAI,SAAS,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU,CAAC,CAAC,UAC9D,CACD,MACC,MAAM,aAAA;;AAGR,MAAa,gBAAgB;CAC5B,MAAM,UAAU,WAAW,KAC1B,OAAO,wBAAQ,IAAI,WAAW,CAAC,CAAC,CACjC;CACA,MAAM,UACL,UAEA,OAAO,QAAQ,WAAW,IAAI,OAAO,IAAI,aAAa;EACrD,MAAM,QAAQ,IAAI,WAAW,SAAS,SAAS,MAAM,MAAM;EAC3D,MAAM,IAAI,QAAQ;EAClB,MAAM,IAAI,OAAO,SAAS,MAAM;EAChC,MAAM,SAAS,MAAM,OACpB,IAEC,WAGI;GACJ,IAAI,MAAM,SAAS,SAAA,GAAqB,OAAO,OAAO,KAAK;GAC3D,MAAM,SAAS,IAAI,SAAS,MAAM,QAAQ,QAAA,CAAkB;GAC5D,MAAM,UAAU,OAAO,SAAS,CAAC;GACjC,MAAM,SAAS,OAAO,UAAU,CAAC;GACjC,IACC,OAAO,SAAS,CAAC,MAAM,KACtB,YAAY,KAAK,YAAY,KAC9B,OAAO,UAAU,CAAC,MAAM,KACxB,SAAA,SAEA,OAAO,OAAO,KAAK,CAClB,OAAO,KACN,QAAQ,+CAA+C,CACxD,GACA,MAAM,MACP,CAAC;GACF,MAAM,MAAM,SAAA,IAAsB;GAClC,IAAI,MAAM,MAAM,QAAQ,OAAO,OAAO,KAAK;GAC3C,OAAO,OAAO,KAAK,CAClB,OAAO,QAAQ;IACd;IACA,SAAS,MAAM,SAAS,SAAA,GAAqB,GAAG;GACjD,CAAC,GACD,GACD,CAAC;EACF,CACD;EACA,MAAM,SAAS,OAAO,IAAI,MAAM;EAChC,WAAW,IACV,SACA,OAAO,IAAI,SAAS,WACnB,MAAM,SACL,MAAM,OACL,QACA,IACC,MAAM,UAAU,OAAA,IAAoB,MAAM,QAAQ,MACpD,CACD,CACD,CACD;EACA,OAAO;CACR,CAAC;CACF,OAAO;EACN;EACA,QAAQ,OAAO,cACd,OAAO,WACN,OAAO,QAAQ,WAAW,IAAI,OAAO,IAAI,UACxC,MAAM,WAAW,IACd,OAAO,QAAQ,KAAA,CAAS,IACxB,OAAO,KAAK,QAAQ,wCAAwC,CAAC,CACjE,CACD,CACD;CACD;AACD"}
1
+ {"version":3,"file":"Framing.js","names":[],"sources":["../../../src/internal/runner/Framing.ts"],"sourcesContent":["import { Array, Effect, MutableRef, Option, Result, Schema } from \"effect\"\n\nexport class FrameError extends Schema.TaggedError<\n\tFrameError,\n\t{ readonly brand: unique symbol }\n>()(\"FrameError\", { detail: Schema.String }) {\n\toverride get message() {\n\t\treturn this.detail\n\t}\n}\n/** A complete byte stream ended; malformed trailing bytes remain FrameError. */\nexport class EndOfStream extends Schema.TaggedError<\n\tEndOfStream,\n\t{ readonly brand: unique symbol }\n>()(\"RunnerEndOfStream\", {}) {\n\toverride get message() {\n\t\treturn \"Runner byte channel ended\"\n\t}\n}\nexport type Channel = 0 | 1\nexport interface Frame {\n\treadonly channel: Channel\n\treadonly payload: Uint8Array\n}\nexport const headerSize = 8\nexport const maxPayload = 1024 * 1024\nconst invalid = (detail: string) => FrameError.make({ detail })\n\n/** Version 2 carries only channel and length; request admission belongs to port. */\nexport const encode = Effect.fnUntraced(function* (frame: Frame) {\n\tif (frame.payload.byteLength > maxPayload)\n\t\treturn yield* invalid(\"Runner frame exceeds the payload limit\")\n\tconst bytes = new Uint8Array(headerSize + frame.payload.byteLength)\n\tbytes.set([2, frame.channel, 0, 0])\n\tnew DataView(bytes.buffer).setUint32(4, frame.payload.byteLength)\n\tbytes.set(frame.payload, headerSize)\n\treturn bytes\n})\n\n/** Check a message boundary; the decoder still validates the frame's contents. */\nexport const isCompleteFrame = (bytes: Uint8Array): boolean =>\n\tbytes.byteLength >= headerSize &&\n\tnew DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(\n\t\t4,\n\t) ===\n\t\tbytes.byteLength - headerSize\n\n/** The decoder owns its byte buffer. Results expose malformed frames without throwing through a generator. */\nexport const decoder = () => {\n\tconst pending = MutableRef.make<Result.Result<Uint8Array, FrameError>>(\n\t\tResult.succeed(new Uint8Array(0)),\n\t)\n\tconst decode = (\n\t\tchunk: Uint8Array,\n\t): Result.Result<ReadonlyArray<Frame>, FrameError> =>\n\t\tResult.flatMap(MutableRef.get(pending), (previous) => {\n\t\t\tconst bytes = new Uint8Array(previous.length + chunk.length)\n\t\t\tbytes.set(previous)\n\t\t\tbytes.set(chunk, previous.length)\n\t\t\tconst frames = Array.unfold(\n\t\t\t\t0,\n\t\t\t\t(\n\t\t\t\t\toffset,\n\t\t\t\t): Option.Option<\n\t\t\t\t\treadonly [Result.Result<Frame, FrameError>, number]\n\t\t\t\t> => {\n\t\t\t\t\tif (bytes.length - offset < headerSize) return Option.none()\n\t\t\t\t\tconst header = new DataView(bytes.buffer, offset, headerSize)\n\t\t\t\t\tconst channel = header.getUint8(1)\n\t\t\t\t\tconst length = header.getUint32(4)\n\t\t\t\t\tif (\n\t\t\t\t\t\theader.getUint8(0) !== 2 ||\n\t\t\t\t\t\t(channel !== 0 && channel !== 1) ||\n\t\t\t\t\t\theader.getUint16(2) !== 0 ||\n\t\t\t\t\t\tlength > maxPayload\n\t\t\t\t\t)\n\t\t\t\t\t\treturn Option.some([\n\t\t\t\t\t\t\tResult.fail(\n\t\t\t\t\t\t\t\tinvalid(\"Invalid runner frame header or payload length\"),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tbytes.length,\n\t\t\t\t\t\t])\n\t\t\t\t\tconst end = offset + headerSize + length\n\t\t\t\t\tif (end > bytes.length) return Option.none()\n\t\t\t\t\treturn Option.some([\n\t\t\t\t\t\tResult.succeed({\n\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\tpayload: bytes.subarray(offset + headerSize, end),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tend,\n\t\t\t\t\t])\n\t\t\t\t},\n\t\t\t)\n\t\t\tconst result = Result.all(frames)\n\t\t\tMutableRef.set(\n\t\t\t\tpending,\n\t\t\t\tResult.map(result, (frames) =>\n\t\t\t\t\tbytes.subarray(\n\t\t\t\t\t\tArray.reduce(\n\t\t\t\t\t\t\tframes,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t(used, frame) => used + headerSize + frame.payload.length,\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\treturn result\n\t\t})\n\treturn {\n\t\tdecode,\n\t\tfinish: Effect.suspend(() =>\n\t\t\tEffect.fromResult(\n\t\t\t\tResult.flatMap(MutableRef.get(pending), (bytes) =>\n\t\t\t\t\tbytes.length === 0\n\t\t\t\t\t\t? Result.succeed(undefined)\n\t\t\t\t\t\t: Result.fail(invalid(\"Runner connection ended inside a frame\")),\n\t\t\t\t),\n\t\t\t),\n\t\t),\n\t}\n}\n"],"mappings":";;AAEA,IAAa,aAAb,cAAgC,OAAO,YAGrC,CAAC,CAAC,cAAc,EAAE,QAAQ,OAAO,OAAO,CAAC,CAAC,CAAC;CAC5C,IAAa,UAAU;EACtB,OAAO,KAAK;CACb;AACD;;AAEA,IAAa,cAAb,cAAiC,OAAO,YAGtC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;CAC5B,IAAa,UAAU;EACtB,OAAO;CACR;AACD;AAOA,MAAa,aAAa;AAC1B,MAAM,WAAW,WAAmB,WAAW,KAAK,EAAE,OAAO,CAAC;;AAG9D,MAAa,SAAS,OAAO,WAAW,WAAW,OAAc;CAChE,IAAI,MAAM,QAAQ,aAAA,SACjB,OAAO,OAAO,QAAQ,wCAAwC;CAC/D,MAAM,QAAQ,IAAI,WAAA,IAAwB,MAAM,QAAQ,UAAU;CAClE,MAAM,IAAI;EAAC;EAAG,MAAM;EAAS;EAAG;CAAC,CAAC;CAClC,IAAI,SAAS,MAAM,MAAM,CAAC,CAAC,UAAU,GAAG,MAAM,QAAQ,UAAU;CAChE,MAAM,IAAI,MAAM,SAAA,CAAmB;CACnC,OAAO;AACR,CAAC;;AAGD,MAAa,mBAAmB,UAC/B,MAAM,cAAA,KACN,IAAI,SAAS,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU,CAAC,CAAC,UAC9D,CACD,MACC,MAAM,aAAA;;AAGR,MAAa,gBAAgB;CAC5B,MAAM,UAAU,WAAW,KAC1B,OAAO,wBAAQ,IAAI,WAAW,CAAC,CAAC,CACjC;CACA,MAAM,UACL,UAEA,OAAO,QAAQ,WAAW,IAAI,OAAO,IAAI,aAAa;EACrD,MAAM,QAAQ,IAAI,WAAW,SAAS,SAAS,MAAM,MAAM;EAC3D,MAAM,IAAI,QAAQ;EAClB,MAAM,IAAI,OAAO,SAAS,MAAM;EAChC,MAAM,SAAS,MAAM,OACpB,IAEC,WAGI;GACJ,IAAI,MAAM,SAAS,SAAA,GAAqB,OAAO,OAAO,KAAK;GAC3D,MAAM,SAAS,IAAI,SAAS,MAAM,QAAQ,QAAA,CAAkB;GAC5D,MAAM,UAAU,OAAO,SAAS,CAAC;GACjC,MAAM,SAAS,OAAO,UAAU,CAAC;GACjC,IACC,OAAO,SAAS,CAAC,MAAM,KACtB,YAAY,KAAK,YAAY,KAC9B,OAAO,UAAU,CAAC,MAAM,KACxB,SAAA,SAEA,OAAO,OAAO,KAAK,CAClB,OAAO,KACN,QAAQ,+CAA+C,CACxD,GACA,MAAM,MACP,CAAC;GACF,MAAM,MAAM,SAAA,IAAsB;GAClC,IAAI,MAAM,MAAM,QAAQ,OAAO,OAAO,KAAK;GAC3C,OAAO,OAAO,KAAK,CAClB,OAAO,QAAQ;IACd;IACA,SAAS,MAAM,SAAS,SAAA,GAAqB,GAAG;GACjD,CAAC,GACD,GACD,CAAC;EACF,CACD;EACA,MAAM,SAAS,OAAO,IAAI,MAAM;EAChC,WAAW,IACV,SACA,OAAO,IAAI,SAAS,WACnB,MAAM,SACL,MAAM,OACL,QACA,IACC,MAAM,UAAU,OAAA,IAAoB,MAAM,QAAQ,MACpD,CACD,CACD,CACD;EACA,OAAO;CACR,CAAC;CACF,OAAO;EACN;EACA,QAAQ,OAAO,cACd,OAAO,WACN,OAAO,QAAQ,WAAW,IAAI,OAAO,IAAI,UACxC,MAAM,WAAW,IACd,OAAO,QAAQ,KAAA,CAAS,IACxB,OAAO,KAAK,QAAQ,wCAAwC,CAAC,CACjE,CACD,CACD;CACD;AACD"}
@@ -24,7 +24,7 @@ const connect = Effect.fnUntraced(function* (execution, options) {
24
24
  report
25
25
  },
26
26
  diagnostics: Fiber.await(exited).pipe(Effect.andThen(failures.cause)),
27
- terminate: (graceful) => Effect.gen(function* () {
27
+ terminate: Effect.fnUntraced(function* (graceful) {
28
28
  yield* failures.close;
29
29
  if (!graceful) return;
30
30
  const status = yield* peer.end.pipe(Effect.catchCauseIf(Cause.hasInterruptsOnly, () => Effect.void), Effect.andThen(Fiber.join(exited)), Effect.interruptible, Effect.timeoutOrElse({
@@ -1 +1 @@
1
- {"version":3,"file":"Local.js","names":["FailureGroup.make","Port.make"],"sources":["../../../src/internal/runner/Local.ts"],"sourcesContent":["import { Cause, Effect, Fiber, Option } from \"effect\"\nimport type { Execution } from \"../directTransport\"\nimport * as FailureGroup from \"../FailureGroup\"\nimport {\n\tLocalTerminationTimeout,\n\tProcessExited,\n\tTransportError,\n} from \"../../Errors\"\nimport * as Port from \"../port\"\nimport { stdinExitTimeout } from \"./ProcessObservation\"\n\n/** Direct execution observers stay alive until exit, including forced cleanup. */\nexport const connect = Effect.fnUntraced(function* (\n\texecution: Execution,\n\toptions: Port.Options,\n) {\n\tconst failures = yield* FailureGroup.make<ProcessExited | TransportError>()\n\tconst exited = yield* execution.exited.pipe(Effect.forkScoped)\n\tconst peer = yield* Port.make(execution.channel, options)\n\tyield* failures.run(\n\t\tEffect.raceFirst(\n\t\t\tpeer.await,\n\t\t\tFiber.join(exited).pipe(Effect.flatMap(Effect.fail)),\n\t\t),\n\t)\n\tconst report = (cause: Cause.Cause<unknown>) =>\n\t\tCause.hasInterruptsOnly(cause)\n\t\t\t? Effect.void\n\t\t\t: failures\n\t\t\t\t\t.fail(TransportError.make({ cause }))\n\t\t\t\t\t.pipe(Effect.andThen(peer.fail(TransportError.make({ cause }))))\n\tyield* failures.run(execution.failure)\n\n\treturn {\n\t\t...peer,\n\t\tpid: execution.pid,\n\t\t...(execution.threadId === undefined\n\t\t\t? {}\n\t\t\t: { threadId: execution.threadId }),\n\t\texited,\n\t\tresources: yield* Effect.scope,\n\t\ttransport: { ...peer, failure: failures.await, report },\n\t\tdiagnostics: Fiber.await(exited).pipe(Effect.andThen(failures.cause)),\n\t\tterminate: (graceful: boolean) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// Stop observation before intentionally ending stdin or killing the process.\n\t\t\t\tyield* failures.close\n\t\t\t\tif (!graceful) return\n\t\t\t\t// If this fails, the execution scope forces termination and waits for exit.\n\t\t\t\tconst status = yield* peer.end.pipe(\n\t\t\t\t\t// Peer EOF can interrupt the writer as its output ends. Still confirm the unit's exit.\n\t\t\t\t\tEffect.catchCauseIf(Cause.hasInterruptsOnly, () => Effect.void),\n\t\t\t\t\tEffect.andThen(Fiber.join(exited)),\n\t\t\t\t\tEffect.interruptible,\n\t\t\t\t\tEffect.timeoutOrElse({\n\t\t\t\t\t\tduration: stdinExitTimeout,\n\t\t\t\t\t\torElse: () =>\n\t\t\t\t\t\t\tLocalTerminationTimeout.make({\n\t\t\t\t\t\t\t\t...Option.match(execution.pid, {\n\t\t\t\t\t\t\t\t\tonNone: () => ({}),\n\t\t\t\t\t\t\t\t\tonSome: (pid) => ({ pid }),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t...(execution.threadId === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { threadId: execution.threadId }),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\tif (status.exitCode !== 0 || status.statusCause.reasons.length > 0)\n\t\t\t\t\treturn yield* status\n\t\t\t}),\n\t}\n})\n"],"mappings":";;;;;;;AAYA,MAAa,UAAU,OAAO,WAAW,WACxC,WACA,SACC;CACD,MAAM,WAAW,OAAOA,KAAkD;CAC1E,MAAM,SAAS,OAAO,UAAU,OAAO,KAAK,OAAO,UAAU;CAC7D,MAAM,OAAO,OAAOC,OAAU,UAAU,SAAS,OAAO;CACxD,OAAO,SAAS,IACf,OAAO,UACN,KAAK,OACL,MAAM,KAAK,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,OAAO,IAAI,CAAC,CACpD,CACD;CACA,MAAM,UAAU,UACf,MAAM,kBAAkB,KAAK,IAC1B,OAAO,OACP,SACC,KAAK,eAAe,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CACpC,KAAK,OAAO,QAAQ,KAAK,KAAK,eAAe,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CACnE,OAAO,SAAS,IAAI,UAAU,OAAO;CAErC,OAAO;EACN,GAAG;EACH,KAAK,UAAU;EACf,GAAI,UAAU,aAAa,KAAA,IACxB,CAAC,IACD,EAAE,UAAU,UAAU,SAAS;EAClC;EACA,WAAW,OAAO,OAAO;EACzB,WAAW;GAAE,GAAG;GAAM,SAAS,SAAS;GAAO;EAAO;EACtD,aAAa,MAAM,MAAM,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,SAAS,KAAK,CAAC;EACpE,YAAY,aACX,OAAO,IAAI,aAAa;GAEvB,OAAO,SAAS;GAChB,IAAI,CAAC,UAAU;GAEf,MAAM,SAAS,OAAO,KAAK,IAAI,KAE9B,OAAO,aAAa,MAAM,yBAAyB,OAAO,IAAI,GAC9D,OAAO,QAAQ,MAAM,KAAK,MAAM,CAAC,GACjC,OAAO,eACP,OAAO,cAAc;IACpB,UAAU;IACV,cACC,wBAAwB,KAAK;KAC5B,GAAG,OAAO,MAAM,UAAU,KAAK;MAC9B,eAAe,CAAC;MAChB,SAAS,SAAS,EAAE,IAAI;KACzB,CAAC;KACD,GAAI,UAAU,aAAa,KAAA,IACxB,CAAC,IACD,EAAE,UAAU,UAAU,SAAS;IACnC,CAAC;GACH,CAAC,CACF;GACA,IAAI,OAAO,aAAa,KAAK,OAAO,YAAY,QAAQ,SAAS,GAChE,OAAO,OAAO;EAChB,CAAC;CACH;AACD,CAAC"}
1
+ {"version":3,"file":"Local.js","names":["FailureGroup.make","Port.make"],"sources":["../../../src/internal/runner/Local.ts"],"sourcesContent":["import { Cause, Effect, Fiber, Option } from \"effect\"\nimport type { Execution } from \"../directTransport\"\nimport * as FailureGroup from \"../FailureGroup\"\nimport {\n\tLocalTerminationTimeout,\n\tProcessExited,\n\tTransportError,\n} from \"../../Errors\"\nimport * as Port from \"../port\"\nimport { stdinExitTimeout } from \"./ProcessObservation\"\n\n/** Direct execution observers stay alive until exit, including forced cleanup. */\nexport const connect = Effect.fnUntraced(function* (\n\texecution: Execution,\n\toptions: Port.Options,\n) {\n\tconst failures = yield* FailureGroup.make<ProcessExited | TransportError>()\n\tconst exited = yield* execution.exited.pipe(Effect.forkScoped)\n\tconst peer = yield* Port.make(execution.channel, options)\n\tyield* failures.run(\n\t\tEffect.raceFirst(\n\t\t\tpeer.await,\n\t\t\tFiber.join(exited).pipe(Effect.flatMap(Effect.fail)),\n\t\t),\n\t)\n\tconst report = (cause: Cause.Cause<unknown>) =>\n\t\tCause.hasInterruptsOnly(cause)\n\t\t\t? Effect.void\n\t\t\t: failures\n\t\t\t\t\t.fail(TransportError.make({ cause }))\n\t\t\t\t\t.pipe(Effect.andThen(peer.fail(TransportError.make({ cause }))))\n\tyield* failures.run(execution.failure)\n\n\treturn {\n\t\t...peer,\n\t\tpid: execution.pid,\n\t\t...(execution.threadId === undefined\n\t\t\t? {}\n\t\t\t: { threadId: execution.threadId }),\n\t\texited,\n\t\tresources: yield* Effect.scope,\n\t\ttransport: { ...peer, failure: failures.await, report },\n\t\tdiagnostics: Fiber.await(exited).pipe(Effect.andThen(failures.cause)),\n\t\tterminate: Effect.fnUntraced(function* (graceful: boolean) {\n\t\t\t// Stop observation before intentionally ending stdin or killing the process.\n\t\t\tyield* failures.close\n\t\t\tif (!graceful) return\n\t\t\t// If this fails, the execution scope forces termination and waits for exit.\n\t\t\tconst status = yield* peer.end.pipe(\n\t\t\t\t// Peer EOF can interrupt the writer as its output ends. Still confirm the unit's exit.\n\t\t\t\tEffect.catchCauseIf(Cause.hasInterruptsOnly, () => Effect.void),\n\t\t\t\tEffect.andThen(Fiber.join(exited)),\n\t\t\t\tEffect.interruptible,\n\t\t\t\tEffect.timeoutOrElse({\n\t\t\t\t\tduration: stdinExitTimeout,\n\t\t\t\t\torElse: () =>\n\t\t\t\t\t\tLocalTerminationTimeout.make({\n\t\t\t\t\t\t\t...Option.match(execution.pid, {\n\t\t\t\t\t\t\t\tonNone: () => ({}),\n\t\t\t\t\t\t\t\tonSome: (pid) => ({ pid }),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t...(execution.threadId === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { threadId: execution.threadId }),\n\t\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t)\n\t\t\tif (status.exitCode !== 0 || status.statusCause.reasons.length > 0)\n\t\t\t\treturn yield* status\n\t\t}),\n\t}\n})\n"],"mappings":";;;;;;;AAYA,MAAa,UAAU,OAAO,WAAW,WACxC,WACA,SACC;CACD,MAAM,WAAW,OAAOA,KAAkD;CAC1E,MAAM,SAAS,OAAO,UAAU,OAAO,KAAK,OAAO,UAAU;CAC7D,MAAM,OAAO,OAAOC,OAAU,UAAU,SAAS,OAAO;CACxD,OAAO,SAAS,IACf,OAAO,UACN,KAAK,OACL,MAAM,KAAK,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,OAAO,IAAI,CAAC,CACpD,CACD;CACA,MAAM,UAAU,UACf,MAAM,kBAAkB,KAAK,IAC1B,OAAO,OACP,SACC,KAAK,eAAe,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CACpC,KAAK,OAAO,QAAQ,KAAK,KAAK,eAAe,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CACnE,OAAO,SAAS,IAAI,UAAU,OAAO;CAErC,OAAO;EACN,GAAG;EACH,KAAK,UAAU;EACf,GAAI,UAAU,aAAa,KAAA,IACxB,CAAC,IACD,EAAE,UAAU,UAAU,SAAS;EAClC;EACA,WAAW,OAAO,OAAO;EACzB,WAAW;GAAE,GAAG;GAAM,SAAS,SAAS;GAAO;EAAO;EACtD,aAAa,MAAM,MAAM,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,SAAS,KAAK,CAAC;EACpE,WAAW,OAAO,WAAW,WAAW,UAAmB;GAE1D,OAAO,SAAS;GAChB,IAAI,CAAC,UAAU;GAEf,MAAM,SAAS,OAAO,KAAK,IAAI,KAE9B,OAAO,aAAa,MAAM,yBAAyB,OAAO,IAAI,GAC9D,OAAO,QAAQ,MAAM,KAAK,MAAM,CAAC,GACjC,OAAO,eACP,OAAO,cAAc;IACpB,UAAU;IACV,cACC,wBAAwB,KAAK;KAC5B,GAAG,OAAO,MAAM,UAAU,KAAK;MAC9B,eAAe,CAAC;MAChB,SAAS,SAAS,EAAE,IAAI;KACzB,CAAC;KACD,GAAI,UAAU,aAAa,KAAA,IACxB,CAAC,IACD,EAAE,UAAU,UAAU,SAAS;IACnC,CAAC;GACH,CAAC,CACF;GACA,IAAI,OAAO,aAAa,KAAK,OAAO,YAAY,QAAQ,SAAS,GAChE,OAAO,OAAO;EAChB,CAAC;CACF;AACD,CAAC"}
@@ -2,7 +2,7 @@ import { StateDirectoryLocked } from "./model.js";
2
2
  import { Cause, Effect, FileSystem, Path } from "effect";
3
3
  // src/internal/runner/Lock.ts
4
4
  /** SQLite owns the local directory lock for the enclosing scope, including failed startup. */
5
- const acquire = (directory) => Effect.gen(function* () {
5
+ const acquire = Effect.fnUntraced(function* (directory) {
6
6
  const fs = yield* FileSystem.FileSystem;
7
7
  const path = yield* Path.Path;
8
8
  yield* fs.makeDirectory(directory, { recursive: true }).pipe(Effect.uninterruptible);
@@ -1 +1 @@
1
- {"version":3,"file":"Lock.js","names":[],"sources":["../../../src/internal/runner/Lock.ts"],"sourcesContent":["import { Cause, Effect, FileSystem, Path } from \"effect\"\nimport { StateDirectoryLocked } from \"./model\"\n\n/** SQLite owns the local directory lock for the enclosing scope, including failed startup. */\nexport const acquire = (directory: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem\n\t\tconst path = yield* Path.Path\n\t\tyield* fs\n\t\t\t.makeDirectory(directory, { recursive: true })\n\t\t\t.pipe(Effect.uninterruptible)\n\t\tconst { DatabaseSync } = yield* Effect.promise(\n\t\t\t() => import(\"node:sqlite\"),\n\t\t).pipe(Effect.uninterruptible)\n\t\tconst locked = (cause: unknown) =>\n\t\t\tStateDirectoryLocked.make({\n\t\t\t\tdetail:\n\t\t\t\t\t\"The runner state directory is already owned or cannot be locked\",\n\t\t\t\tcause: Cause.die(cause),\n\t\t\t})\n\t\tconst db = yield* Effect.acquireRelease(\n\t\t\tEffect.try({\n\t\t\t\ttry: () => new DatabaseSync(path.join(directory, \"owner.sqlite\")),\n\t\t\t\tcatch: locked,\n\t\t\t}),\n\t\t\t(db) => Effect.sync(() => db.close()),\n\t\t)\n\t\tyield* Effect.try({ try: () => db.exec(\"BEGIN EXCLUSIVE\"), catch: locked })\n\t})\n"],"mappings":";;;;AAIA,MAAa,WAAW,cACvB,OAAO,IAAI,aAAa;CACvB,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,OAAO,GACL,cAAc,WAAW,EAAE,WAAW,KAAK,CAAC,CAAC,CAC7C,KAAK,OAAO,eAAe;CAC7B,MAAM,EAAE,iBAAiB,OAAO,OAAO,cAChC,OAAO,cACd,CAAC,CAAC,KAAK,OAAO,eAAe;CAC7B,MAAM,UAAU,UACf,qBAAqB,KAAK;EACzB,QACC;EACD,OAAO,MAAM,IAAI,KAAK;CACvB,CAAC;CACF,MAAM,KAAK,OAAO,OAAO,eACxB,OAAO,IAAI;EACV,WAAW,IAAI,aAAa,KAAK,KAAK,WAAW,cAAc,CAAC;EAChE,OAAO;CACR,CAAC,IACA,OAAO,OAAO,WAAW,GAAG,MAAM,CAAC,CACrC;CACA,OAAO,OAAO,IAAI;EAAE,WAAW,GAAG,KAAK,iBAAiB;EAAG,OAAO;CAAO,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"Lock.js","names":[],"sources":["../../../src/internal/runner/Lock.ts"],"sourcesContent":["import { Cause, Effect, FileSystem, Path } from \"effect\"\nimport { StateDirectoryLocked } from \"./model\"\n\n/** SQLite owns the local directory lock for the enclosing scope, including failed startup. */\nexport const acquire = Effect.fnUntraced(function* (directory: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tyield* fs\n\t\t.makeDirectory(directory, { recursive: true })\n\t\t.pipe(Effect.uninterruptible)\n\tconst { DatabaseSync } = yield* Effect.promise(\n\t\t() => import(\"node:sqlite\"),\n\t).pipe(Effect.uninterruptible)\n\tconst locked = (cause: unknown) =>\n\t\tStateDirectoryLocked.make({\n\t\t\tdetail: \"The runner state directory is already owned or cannot be locked\",\n\t\t\tcause: Cause.die(cause),\n\t\t})\n\tconst db = yield* Effect.acquireRelease(\n\t\tEffect.try({\n\t\t\ttry: () => new DatabaseSync(path.join(directory, \"owner.sqlite\")),\n\t\t\tcatch: locked,\n\t\t}),\n\t\t(db) => Effect.sync(() => db.close()),\n\t)\n\tyield* Effect.try({ try: () => db.exec(\"BEGIN EXCLUSIVE\"), catch: locked })\n})\n"],"mappings":";;;;AAIA,MAAa,UAAU,OAAO,WAAW,WAAW,WAAmB;CACtE,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,OAAO,GACL,cAAc,WAAW,EAAE,WAAW,KAAK,CAAC,CAAC,CAC7C,KAAK,OAAO,eAAe;CAC7B,MAAM,EAAE,iBAAiB,OAAO,OAAO,cAChC,OAAO,cACd,CAAC,CAAC,KAAK,OAAO,eAAe;CAC7B,MAAM,UAAU,UACf,qBAAqB,KAAK;EACzB,QAAQ;EACR,OAAO,MAAM,IAAI,KAAK;CACvB,CAAC;CACF,MAAM,KAAK,OAAO,OAAO,eACxB,OAAO,IAAI;EACV,WAAW,IAAI,aAAa,KAAK,KAAK,WAAW,cAAc,CAAC;EAChE,OAAO;CACR,CAAC,IACA,OAAO,OAAO,WAAW,GAAG,MAAM,CAAC,CACrC;CACA,OAAO,OAAO,IAAI;EAAE,WAAW,GAAG,KAAK,iBAAiB;EAAG,OAAO;CAAO,CAAC;AAC3E,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import "./model.js";
2
- import { Effect, FileSystem, Path } from "effect";
2
+ import { Effect, FileSystem, Path, PlatformError } from "effect";
3
3
  import { ChildProcessSpawner } from "effect/process";
@@ -15,7 +15,7 @@ const digest = Effect.fnUntraced(function* (directory) {
15
15
  const fs = yield* FileSystem.FileSystem;
16
16
  const path = yield* Path.Path;
17
17
  const hash = yield* Effect.sync(() => createHash("sha256").update("graft-package-sha256-v1\0"));
18
- const visit = (relative) => Effect.gen(function* () {
18
+ const visit = Effect.fnUntraced(function* (relative) {
19
19
  const filename = path.join(directory, relative);
20
20
  const info = yield* fs.stat(filename);
21
21
  if (info.type !== "File" && info.type !== "Directory") return yield* PackageError.make({ detail: `Unsupported package entry: ${relative}` });
@@ -78,31 +78,28 @@ const resolve = Effect.fnUntraced(function* (root, specifier, includeDigest = fa
78
78
  cause: Cause.fail(error)
79
79
  }))
80
80
  }));
81
- const resolveEntry = (installation, specifier) => Effect.gen(function* () {
82
- const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
83
- return yield* Effect.scoped(Effect.gen(function* () {
84
- const child = yield* spawner.spawn(ChildProcess.make(process.execPath, [
85
- "--input-type=module",
86
- "--eval",
87
- "process.stdout.write(import.meta.resolve(process.argv[1]))",
88
- "--",
89
- specifier
90
- ], {
91
- cwd: installation,
92
- env: {},
93
- stdin: "ignore",
94
- stdout: "pipe",
95
- stderr: "pipe"
96
- }));
97
- const [code, stdout, stderr] = yield* Effect.all([
98
- child.exitCode,
99
- child.stdout.pipe(Stream.decodeText(), Stream.mkString),
100
- child.stderr.pipe(Stream.decodeText(), Stream.mkString)
101
- ], { concurrency: "unbounded" });
102
- if (code !== 0) return yield* PackageError.make({ detail: `Package resolution failed: ${stderr}` });
103
- return stdout;
81
+ const resolveEntry = Effect.fnUntraced(function* (installation, specifier) {
82
+ const child = yield* (yield* ChildProcessSpawner.ChildProcessSpawner).spawn(ChildProcess.make(process.execPath, [
83
+ "--input-type=module",
84
+ "--eval",
85
+ "process.stdout.write(import.meta.resolve(process.argv[1]))",
86
+ "--",
87
+ specifier
88
+ ], {
89
+ cwd: installation,
90
+ env: {},
91
+ stdin: "ignore",
92
+ stdout: "pipe",
93
+ stderr: "pipe"
104
94
  }));
105
- });
95
+ const [code, stdout, stderr] = yield* Effect.all([
96
+ child.exitCode,
97
+ child.stdout.pipe(Stream.decodeText(), Stream.mkString),
98
+ child.stderr.pipe(Stream.decodeText(), Stream.mkString)
99
+ ], { concurrency: "unbounded" });
100
+ if (code !== 0) return yield* PackageError.make({ detail: `Package resolution failed: ${stderr}` });
101
+ return stdout;
102
+ }, Effect.scoped);
106
103
  export { digest, resolve, resolveEntry, verify };
107
104
 
108
105
  //# sourceMappingURL=Packages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Packages.js","names":[],"sources":["../../../src/internal/runner/Packages.ts"],"sourcesContent":["import {\n\tArray,\n\tCause,\n\tEffect,\n\tFileSystem,\n\tOrder,\n\tPath,\n\tSchema,\n\tStream,\n\tString,\n} from \"effect\"\nimport type { PlatformError } from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\"\n// @effect-diagnostics-next-line nodeBuiltinImport:off -- WebCrypto has no incremental digest API; package files are hashed as streams without buffering the directory.\nimport { createHash } from \"node:crypto\"\nimport process from \"node:process\"\nimport { fileURLToPath } from \"node:url\"\nimport { PackageError, type CodeIdentity } from \"./model\"\n\nconst Manifest = Schema.Struct({ name: Schema.String, version: Schema.String })\nexport interface Expected {\n\treadonly version?: string\n\treadonly digest?: string\n}\nexport const verify = (actual: CodeIdentity, expected: Expected = {}) =>\n\texpected.version !== undefined && actual.version !== expected.version\n\t\t? Effect.fail(\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: `Package version mismatch: expected ${expected.version}, received ${actual.version}`,\n\t\t\t\t}),\n\t\t\t)\n\t\t: expected.digest !== undefined && actual.digest !== expected.digest\n\t\t\t? Effect.fail(\n\t\t\t\t\tPackageError.make({\n\t\t\t\t\t\tdetail: `Package digest mismatch: expected ${expected.digest}, received ${actual.digest}`,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t: Effect.void\n\n/** A path-sensitive SHA-256 of sorted entries and bytes, excluding every node_modules subtree. */\nexport const digest = Effect.fnUntraced(function* (directory: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tconst hash = yield* Effect.sync(() =>\n\t\tcreateHash(\"sha256\").update(\"graft-package-sha256-v1\\0\"),\n\t)\n\tconst visit = (\n\t\trelative: string,\n\t): Effect.Effect<void, PackageError | PlatformError.PlatformError> =>\n\t\tEffect.gen(function* () {\n\t\t\tconst filename = path.join(directory, relative)\n\t\t\tconst info = yield* fs.stat(filename)\n\t\t\tif (info.type !== \"File\" && info.type !== \"Directory\")\n\t\t\t\treturn yield* PackageError.make({\n\t\t\t\t\tdetail: `Unsupported package entry: ${relative}`,\n\t\t\t\t})\n\t\t\tconst name = new TextEncoder().encode(relative)\n\t\t\tyield* Effect.sync(() => {\n\t\t\t\thash.update(\n\t\t\t\t\t`${info.type}:${name.byteLength}:${info.type === \"File\" ? info.size : 0}:`,\n\t\t\t\t)\n\t\t\t\thash.update(name)\n\t\t\t})\n\t\t\tif (info.type === \"File\") {\n\t\t\t\tyield* fs.stream(filename).pipe(\n\t\t\t\t\tStream.runForEach((bytes) =>\n\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\thash.update(bytes)\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tconst entries = yield* fs.readDirectory(filename)\n\t\t\t\tfor (const entry of Array.sort(entries, Order.String)) {\n\t\t\t\t\tif (entry === \"node_modules\") continue\n\t\t\t\t\tyield* visit(relative === \"\" ? entry : `${relative}/${entry}`)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\tyield* visit(\"\")\n\treturn yield* Effect.sync(() => hash.digest(\"hex\"))\n})\n\n/**\n * Resolve using Node's import conditions without importing executable package code.\n * The helper's cwd is the installation root and it inherits no NODE_OPTIONS/loaders.\n * The installation directory and its package exports are trusted.\n */\nexport const resolve = Effect.fnUntraced(\n\tfunction* (root: string, specifier: string, includeDigest: boolean = false) {\n\t\tconst segments = String.split(specifier, \"/\")\n\t\tconst scoped = String.startsWith(\"@\")(specifier)\n\t\tconst name = Array.join(Array.take(segments, scoped ? 2 : 1), \"/\")\n\t\tconst fs = yield* FileSystem.FileSystem\n\t\tconst path = yield* Path.Path\n\t\tconst installation = yield* fs.realPath(root)\n\t\tconst directory = yield* fs.realPath(\n\t\t\tpath.join(installation, \"node_modules\", name),\n\t\t)\n\t\tconst manifest = yield* fs\n\t\t\t.readFileString(path.join(directory, \"package.json\"))\n\t\t\t.pipe(\n\t\t\t\tEffect.flatMap(Schema.decodeEffect(Schema.fromJsonString(Manifest))),\n\t\t\t)\n\t\tconst resolved = yield* resolveEntry(installation, specifier)\n\t\tconst filename = yield* Effect.try({\n\t\t\ttry: () => fileURLToPath(resolved),\n\t\t\tcatch: (error) =>\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: \"The package export is not a file URL\",\n\t\t\t\t\tcause: Cause.die(error),\n\t\t\t\t}),\n\t\t})\n\t\tconst entry = yield* fs.realPath(filename)\n\t\tconst identity: CodeIdentity = {\n\t\t\t...manifest,\n\t\t\t...(includeDigest ? { digest: yield* digest(directory) } : {}),\n\t\t}\n\t\treturn { directory, entry, identity }\n\t},\n\tEffect.catchTags({\n\t\tPlatformError: (error) =>\n\t\t\tEffect.fail(\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: \"Reading the installed package failed\",\n\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t}),\n\t\t\t),\n\t\tSchemaError: (error) =>\n\t\t\tEffect.fail(\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: \"Reading the package manifest failed\",\n\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t}),\n\t\t\t),\n\t}),\n)\n\nexport const resolveEntry = (installation: string, specifier: string) =>\n\tEffect.gen(function* () {\n\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n\t\treturn yield* Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst child = yield* spawner.spawn(\n\t\t\t\t\tChildProcess.make(\n\t\t\t\t\t\tprocess.execPath,\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"--input-type=module\",\n\t\t\t\t\t\t\t\"--eval\",\n\t\t\t\t\t\t\t\"process.stdout.write(import.meta.resolve(process.argv[1]))\",\n\t\t\t\t\t\t\t\"--\",\n\t\t\t\t\t\t\tspecifier,\n\t\t\t\t\t\t],\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcwd: installation,\n\t\t\t\t\t\t\tenv: {},\n\t\t\t\t\t\t\tstdin: \"ignore\",\n\t\t\t\t\t\t\tstdout: \"pipe\",\n\t\t\t\t\t\t\tstderr: \"pipe\",\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tconst [code, stdout, stderr] = yield* Effect.all(\n\t\t\t\t\t[\n\t\t\t\t\t\tchild.exitCode,\n\t\t\t\t\t\tchild.stdout.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\t\t\t\tchild.stderr.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\t\t\t],\n\t\t\t\t\t{ concurrency: \"unbounded\" },\n\t\t\t\t)\n\t\t\t\tif (code !== 0)\n\t\t\t\t\treturn yield* PackageError.make({\n\t\t\t\t\t\tdetail: `Package resolution failed: ${stderr}`,\n\t\t\t\t\t})\n\t\t\t\treturn stdout\n\t\t\t}),\n\t\t)\n\t})\n"],"mappings":"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"}
1
+ {"version":3,"file":"Packages.js","names":[],"sources":["../../../src/internal/runner/Packages.ts"],"sourcesContent":["import {\n\tArray,\n\tCause,\n\tEffect,\n\tFileSystem,\n\tOrder,\n\tPath,\n\tSchema,\n\tStream,\n\tString,\n} from \"effect\"\nimport type { PlatformError } from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\"\n// @effect-diagnostics-next-line nodeBuiltinImport:off -- WebCrypto has no incremental digest API; package files are hashed as streams without buffering the directory.\nimport { createHash } from \"node:crypto\"\nimport process from \"node:process\"\nimport { fileURLToPath } from \"node:url\"\nimport { PackageError, type CodeIdentity } from \"./model\"\n\nconst Manifest = Schema.Struct({ name: Schema.String, version: Schema.String })\nexport interface Expected {\n\treadonly version?: string\n\treadonly digest?: string\n}\nexport const verify = (actual: CodeIdentity, expected: Expected = {}) =>\n\texpected.version !== undefined && actual.version !== expected.version\n\t\t? Effect.fail(\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: `Package version mismatch: expected ${expected.version}, received ${actual.version}`,\n\t\t\t\t}),\n\t\t\t)\n\t\t: expected.digest !== undefined && actual.digest !== expected.digest\n\t\t\t? Effect.fail(\n\t\t\t\t\tPackageError.make({\n\t\t\t\t\t\tdetail: `Package digest mismatch: expected ${expected.digest}, received ${actual.digest}`,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t: Effect.void\n\n/** A path-sensitive SHA-256 of sorted entries and bytes, excluding every node_modules subtree. */\nexport const digest = Effect.fnUntraced(function* (directory: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tconst hash = yield* Effect.sync(() =>\n\t\tcreateHash(\"sha256\").update(\"graft-package-sha256-v1\\0\"),\n\t)\n\tconst visit = Effect.fnUntraced(function* (\n\t\trelative: string,\n\t): Effect.fn.Return<void, PackageError | PlatformError.PlatformError> {\n\t\tconst filename = path.join(directory, relative)\n\t\tconst info = yield* fs.stat(filename)\n\t\tif (info.type !== \"File\" && info.type !== \"Directory\")\n\t\t\treturn yield* PackageError.make({\n\t\t\t\tdetail: `Unsupported package entry: ${relative}`,\n\t\t\t})\n\t\tconst name = new TextEncoder().encode(relative)\n\t\tyield* Effect.sync(() => {\n\t\t\thash.update(\n\t\t\t\t`${info.type}:${name.byteLength}:${info.type === \"File\" ? info.size : 0}:`,\n\t\t\t)\n\t\t\thash.update(name)\n\t\t})\n\t\tif (info.type === \"File\") {\n\t\t\tyield* fs.stream(filename).pipe(\n\t\t\t\tStream.runForEach((bytes) =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\thash.update(bytes)\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)\n\t\t} else {\n\t\t\tconst entries = yield* fs.readDirectory(filename)\n\t\t\tfor (const entry of Array.sort(entries, Order.String)) {\n\t\t\t\tif (entry === \"node_modules\") continue\n\t\t\t\tyield* visit(relative === \"\" ? entry : `${relative}/${entry}`)\n\t\t\t}\n\t\t}\n\t})\n\tyield* visit(\"\")\n\treturn yield* Effect.sync(() => hash.digest(\"hex\"))\n})\n\n/**\n * Resolve using Node's import conditions without importing executable package code.\n * The helper's cwd is the installation root and it inherits no NODE_OPTIONS/loaders.\n * The installation directory and its package exports are trusted.\n */\nexport const resolve = Effect.fnUntraced(\n\tfunction* (root: string, specifier: string, includeDigest: boolean = false) {\n\t\tconst segments = String.split(specifier, \"/\")\n\t\tconst scoped = String.startsWith(\"@\")(specifier)\n\t\tconst name = Array.join(Array.take(segments, scoped ? 2 : 1), \"/\")\n\t\tconst fs = yield* FileSystem.FileSystem\n\t\tconst path = yield* Path.Path\n\t\tconst installation = yield* fs.realPath(root)\n\t\tconst directory = yield* fs.realPath(\n\t\t\tpath.join(installation, \"node_modules\", name),\n\t\t)\n\t\tconst manifest = yield* fs\n\t\t\t.readFileString(path.join(directory, \"package.json\"))\n\t\t\t.pipe(\n\t\t\t\tEffect.flatMap(Schema.decodeEffect(Schema.fromJsonString(Manifest))),\n\t\t\t)\n\t\tconst resolved = yield* resolveEntry(installation, specifier)\n\t\tconst filename = yield* Effect.try({\n\t\t\ttry: () => fileURLToPath(resolved),\n\t\t\tcatch: (error) =>\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: \"The package export is not a file URL\",\n\t\t\t\t\tcause: Cause.die(error),\n\t\t\t\t}),\n\t\t})\n\t\tconst entry = yield* fs.realPath(filename)\n\t\tconst identity: CodeIdentity = {\n\t\t\t...manifest,\n\t\t\t...(includeDigest ? { digest: yield* digest(directory) } : {}),\n\t\t}\n\t\treturn { directory, entry, identity }\n\t},\n\tEffect.catchTags({\n\t\tPlatformError: (error) =>\n\t\t\tEffect.fail(\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: \"Reading the installed package failed\",\n\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t}),\n\t\t\t),\n\t\tSchemaError: (error) =>\n\t\t\tEffect.fail(\n\t\t\t\tPackageError.make({\n\t\t\t\t\tdetail: \"Reading the package manifest failed\",\n\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t}),\n\t\t\t),\n\t}),\n)\n\nexport const resolveEntry = Effect.fnUntraced(function* (\n\tinstallation: string,\n\tspecifier: string,\n) {\n\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n\tconst child = yield* spawner.spawn(\n\t\tChildProcess.make(\n\t\t\tprocess.execPath,\n\t\t\t[\n\t\t\t\t\"--input-type=module\",\n\t\t\t\t\"--eval\",\n\t\t\t\t\"process.stdout.write(import.meta.resolve(process.argv[1]))\",\n\t\t\t\t\"--\",\n\t\t\t\tspecifier,\n\t\t\t],\n\t\t\t{\n\t\t\t\tcwd: installation,\n\t\t\t\tenv: {},\n\t\t\t\tstdin: \"ignore\",\n\t\t\t\tstdout: \"pipe\",\n\t\t\t\tstderr: \"pipe\",\n\t\t\t},\n\t\t),\n\t)\n\tconst [code, stdout, stderr] = yield* Effect.all(\n\t\t[\n\t\t\tchild.exitCode,\n\t\t\tchild.stdout.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\tchild.stderr.pipe(Stream.decodeText(), Stream.mkString),\n\t\t],\n\t\t{ concurrency: \"unbounded\" },\n\t)\n\tif (code !== 0)\n\t\treturn yield* PackageError.make({\n\t\t\tdetail: `Package resolution failed: ${stderr}`,\n\t\t})\n\treturn stdout\n}, Effect.scoped)\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { Cause, Effect, Option, Schedule, Stream, String } from "effect";
3
3
  import { ChildProcess, ChildProcessSpawner } from "effect/process";
4
4
  import process from "node:process";
5
5
  // src/internal/runner/Processes.ts
6
- const inspect = (pid) => Effect.scoped(Effect.gen(function* () {
6
+ const inspect = Effect.fnUntraced(function* (pid) {
7
7
  const child = yield* (yield* ChildProcessSpawner.ChildProcessSpawner).spawn(ChildProcess.make("ps", [
8
8
  "-p",
9
9
  `${pid}`,
@@ -12,10 +12,8 @@ const inspect = (pid) => Effect.scoped(Effect.gen(function* () {
12
12
  "-o",
13
13
  "stat="
14
14
  ], {
15
- env: {
16
- ...process.env,
17
- LC_ALL: "C"
18
- },
15
+ env: { LC_ALL: "C" },
16
+ extendEnv: true,
19
17
  stdin: "ignore"
20
18
  }));
21
19
  const [code, output, stderr] = yield* Effect.all([
@@ -28,11 +26,11 @@ const inspect = (pid) => Effect.scoped(Effect.gen(function* () {
28
26
  if (code !== 0 || born === void 0 || status === void 0) return yield* ExecutionError.make({ detail: "Cannot inspect process identity: " + stderr });
29
27
  if (String.startsWith("Z")(status)) return Option.none();
30
28
  return Option.some({ born });
31
- })).pipe(Effect.mapError((error) => error._tag === "ExecutionError" ? error : ExecutionError.make({
29
+ }, Effect.scoped, Effect.mapError((error) => error._tag === "ExecutionError" ? error : ExecutionError.make({
32
30
  detail: "Inspecting process identity failed",
33
31
  cause: Cause.fail(error)
34
32
  })));
35
- const identity = (pid) => Effect.gen(function* () {
33
+ const identity = Effect.fnUntraced(function* (pid) {
36
34
  const current = yield* inspect(pid);
37
35
  if (Option.isNone(current)) return yield* ExecutionError.make({ detail: "The child exited before its identity could be recorded" });
38
36
  return {
@@ -40,12 +38,12 @@ const identity = (pid) => Effect.gen(function* () {
40
38
  start: current.value
41
39
  };
42
40
  });
43
- const matches = (child) => Effect.gen(function* () {
41
+ const matches = Effect.fnUntraced(function* (child) {
44
42
  const current = yield* inspect(child.pid);
45
43
  if (Option.isNone(current) || current.value.born !== child.start.born) return false;
46
44
  return true;
47
45
  });
48
- const recover = (child) => Effect.gen(function* () {
46
+ const recover = Effect.fnUntraced(function* (child) {
49
47
  if (!(yield* matches(child))) return {
50
48
  kind: "Exited",
51
49
  exit: {
@@ -1 +1 @@
1
- {"version":3,"file":"Processes.js","names":[],"sources":["../../../src/internal/runner/Processes.ts"],"sourcesContent":["import { Cause, Effect, Option, Schedule, Stream, String } from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\"\nimport process from \"node:process\"\nimport {\n\tExecutionError,\n\tTerminationUnconfirmed,\n\ttype ProcessIdentity,\n\ttype Termination,\n} from \"./model\"\n\nconst inspect = (pid: number) =>\n\tEffect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n\t\t\tconst child = yield* spawner.spawn(\n\t\t\t\tChildProcess.make(\n\t\t\t\t\t\"ps\",\n\t\t\t\t\t[\"-p\", `${pid}`, \"-o\", \"lstart=\", \"-o\", \"stat=\"],\n\t\t\t\t\t{\n\t\t\t\t\t\tenv: { ...process.env, LC_ALL: \"C\" },\n\t\t\t\t\t\tstdin: \"ignore\",\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t)\n\t\t\tconst [code, output, stderr] = yield* Effect.all(\n\t\t\t\t[\n\t\t\t\t\tchild.exitCode,\n\t\t\t\t\tchild.stdout.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\t\t\tchild.stderr.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\t\t],\n\t\t\t\t{ concurrency: \"unbounded\" },\n\t\t\t)\n\t\t\tif (code === 1 && String.trim(output) === \"\") return Option.none()\n\t\t\tconst [, born, status] =\n\t\t\t\t/^(.{24})\\s+(\\S+)$/m.exec(String.trim(output)) ?? []\n\t\t\tif (code !== 0 || born === undefined || status === undefined)\n\t\t\t\treturn yield* ExecutionError.make({\n\t\t\t\t\tdetail: \"Cannot inspect process identity: \" + stderr,\n\t\t\t\t})\n\t\t\tif (String.startsWith(\"Z\")(status)) return Option.none()\n\t\t\treturn Option.some({ born })\n\t\t}),\n\t).pipe(\n\t\tEffect.mapError((error) =>\n\t\t\terror._tag === \"ExecutionError\"\n\t\t\t\t? error\n\t\t\t\t: ExecutionError.make({\n\t\t\t\t\t\tdetail: \"Inspecting process identity failed\",\n\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t}),\n\t\t),\n\t)\n\nexport const identity = (pid: number) =>\n\tEffect.gen(function* () {\n\t\tconst current = yield* inspect(pid)\n\t\tif (Option.isNone(current))\n\t\t\treturn yield* ExecutionError.make({\n\t\t\t\tdetail: \"The child exited before its identity could be recorded\",\n\t\t\t})\n\t\treturn { pid, start: current.value }\n\t})\n\n// The OS may discard argv before reporting a zombie; PID and start time remain the identity.\nexport const matches = (child: ProcessIdentity) =>\n\tEffect.gen(function* () {\n\t\tconst current = yield* inspect(child.pid)\n\t\tif (Option.isNone(current) || current.value.born !== child.start.born)\n\t\t\treturn false\n\t\treturn true\n\t})\n\nexport const recover = (child: ProcessIdentity) =>\n\tEffect.gen(function* () {\n\t\tif (!(yield* matches(child)))\n\t\t\treturn {\n\t\t\t\tkind: \"Exited\",\n\t\t\t\texit: { code: null, signal: null },\n\t\t\t\tcause: Cause.empty,\n\t\t\t} satisfies Termination\n\t\t// The PID can still be reused between this final check and kill; an external supervisor covers descendants.\n\t\tconst sent = yield* Effect.exit(\n\t\t\tEffect.try({\n\t\t\t\ttry: () => process.kill(child.pid, \"SIGKILL\"),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tExecutionError.make({\n\t\t\t\t\t\tdetail: \"Signaling the orphan failed\",\n\t\t\t\t\t\tcause: Cause.die(cause),\n\t\t\t\t\t}),\n\t\t\t}),\n\t\t)\n\t\tconst confirmed = yield* matches(child).pipe(\n\t\t\tEffect.repeat({\n\t\t\t\tschedule: Schedule.spaced(\"50 millis\"),\n\t\t\t\twhile: (value) => value,\n\t\t\t}),\n\t\t\tEffect.timeoutOption(\"10 seconds\"),\n\t\t)\n\t\tif (Option.isNone(confirmed))\n\t\t\treturn yield* TerminationUnconfirmed.make({\n\t\t\t\tdetail: \"The orphan did not exit after recovery\",\n\t\t\t\tcause: sent._tag === \"Failure\" ? sent.cause : Cause.empty,\n\t\t\t})\n\t\treturn {\n\t\t\tkind: \"Killed\",\n\t\t\texit: { code: null, signal: \"SIGKILL\" },\n\t\t\tcause: sent._tag === \"Failure\" ? sent.cause : Cause.empty,\n\t\t} satisfies Termination\n\t})\n"],"mappings":";;;;;AAUA,MAAM,WAAW,QAChB,OAAO,OACN,OAAO,IAAI,aAAa;CAEvB,MAAM,QAAQ,QAAO,OADE,oBAAoB,oBAAA,CACd,MAC5B,aAAa,KACZ,MACA;EAAC;EAAM,GAAG;EAAO;EAAM;EAAW;EAAM;CAAO,GAC/C;EACC,KAAK;GAAE,GAAG,QAAQ;GAAK,QAAQ;EAAI;EACnC,OAAO;CACR,CACD,CACD;CACA,MAAM,CAAC,MAAM,QAAQ,UAAU,OAAO,OAAO,IAC5C;EACC,MAAM;EACN,MAAM,OAAO,KAAK,OAAO,WAAW,GAAG,OAAO,QAAQ;EACtD,MAAM,OAAO,KAAK,OAAO,WAAW,GAAG,OAAO,QAAQ;CACvD,GACA,EAAE,aAAa,YAAY,CAC5B;CACA,IAAI,SAAS,KAAK,OAAO,KAAK,MAAM,MAAM,IAAI,OAAO,OAAO,KAAK;CACjE,MAAM,GAAG,MAAM,UACd,qBAAqB,KAAK,OAAO,KAAK,MAAM,CAAC,KAAK,CAAC;CACpD,IAAI,SAAS,KAAK,SAAS,KAAA,KAAa,WAAW,KAAA,GAClD,OAAO,OAAO,eAAe,KAAK,EACjC,QAAQ,sCAAsC,OAC/C,CAAC;CACF,IAAI,OAAO,WAAW,GAAG,CAAC,CAAC,MAAM,GAAG,OAAO,OAAO,KAAK;CACvD,OAAO,OAAO,KAAK,EAAE,KAAK,CAAC;AAC5B,CAAC,CACF,CAAC,CAAC,KACD,OAAO,UAAU,UAChB,MAAM,SAAS,mBACZ,QACA,eAAe,KAAK;CACpB,QAAQ;CACR,OAAO,MAAM,KAAK,KAAK;AACxB,CAAC,CACJ,CACD;AAED,MAAa,YAAY,QACxB,OAAO,IAAI,aAAa;CACvB,MAAM,UAAU,OAAO,QAAQ,GAAG;CAClC,IAAI,OAAO,OAAO,OAAO,GACxB,OAAO,OAAO,eAAe,KAAK,EACjC,QAAQ,yDACT,CAAC;CACF,OAAO;EAAE;EAAK,OAAO,QAAQ;CAAM;AACpC,CAAC;AAGF,MAAa,WAAW,UACvB,OAAO,IAAI,aAAa;CACvB,MAAM,UAAU,OAAO,QAAQ,MAAM,GAAG;CACxC,IAAI,OAAO,OAAO,OAAO,KAAK,QAAQ,MAAM,SAAS,MAAM,MAAM,MAChE,OAAO;CACR,OAAO;AACR,CAAC;AAEF,MAAa,WAAW,UACvB,OAAO,IAAI,aAAa;CACvB,IAAI,EAAE,OAAO,QAAQ,KAAK,IACzB,OAAO;EACN,MAAM;EACN,MAAM;GAAE,MAAM;GAAM,QAAQ;EAAK;EACjC,OAAO,MAAM;CACd;CAED,MAAM,OAAO,OAAO,OAAO,KAC1B,OAAO,IAAI;EACV,WAAW,QAAQ,KAAK,MAAM,KAAK,SAAS;EAC5C,QAAQ,UACP,eAAe,KAAK;GACnB,QAAQ;GACR,OAAO,MAAM,IAAI,KAAK;EACvB,CAAC;CACH,CAAC,CACF;CACA,MAAM,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,KACvC,OAAO,OAAO;EACb,UAAU,SAAS,OAAO,WAAW;EACrC,QAAQ,UAAU;CACnB,CAAC,GACD,OAAO,cAAc,YAAY,CAClC;CACA,IAAI,OAAO,OAAO,SAAS,GAC1B,OAAO,OAAO,uBAAuB,KAAK;EACzC,QAAQ;EACR,OAAO,KAAK,SAAS,YAAY,KAAK,QAAQ,MAAM;CACrD,CAAC;CACF,OAAO;EACN,MAAM;EACN,MAAM;GAAE,MAAM;GAAM,QAAQ;EAAU;EACtC,OAAO,KAAK,SAAS,YAAY,KAAK,QAAQ,MAAM;CACrD;AACD,CAAC"}
1
+ {"version":3,"file":"Processes.js","names":[],"sources":["../../../src/internal/runner/Processes.ts"],"sourcesContent":["import { Cause, Effect, Option, Schedule, Stream, String } from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\"\nimport process from \"node:process\"\nimport {\n\tExecutionError,\n\tTerminationUnconfirmed,\n\ttype ProcessIdentity,\n\ttype Termination,\n} from \"./model\"\n\nconst inspect = Effect.fnUntraced(\n\tfunction* (pid: number) {\n\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n\t\tconst child = yield* spawner.spawn(\n\t\t\tChildProcess.make(\n\t\t\t\t\"ps\",\n\t\t\t\t[\"-p\", `${pid}`, \"-o\", \"lstart=\", \"-o\", \"stat=\"],\n\t\t\t\t{\n\t\t\t\t\tenv: { LC_ALL: \"C\" },\n\t\t\t\t\textendEnv: true,\n\t\t\t\t\tstdin: \"ignore\",\n\t\t\t\t},\n\t\t\t),\n\t\t)\n\t\tconst [code, output, stderr] = yield* Effect.all(\n\t\t\t[\n\t\t\t\tchild.exitCode,\n\t\t\t\tchild.stdout.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\t\tchild.stderr.pipe(Stream.decodeText(), Stream.mkString),\n\t\t\t],\n\t\t\t{ concurrency: \"unbounded\" },\n\t\t)\n\t\tif (code === 1 && String.trim(output) === \"\") return Option.none()\n\t\tconst [, born, status] =\n\t\t\t/^(.{24})\\s+(\\S+)$/m.exec(String.trim(output)) ?? []\n\t\tif (code !== 0 || born === undefined || status === undefined)\n\t\t\treturn yield* ExecutionError.make({\n\t\t\t\tdetail: \"Cannot inspect process identity: \" + stderr,\n\t\t\t})\n\t\tif (String.startsWith(\"Z\")(status)) return Option.none()\n\t\treturn Option.some({ born })\n\t},\n\tEffect.scoped,\n\tEffect.mapError((error) =>\n\t\terror._tag === \"ExecutionError\"\n\t\t\t? error\n\t\t\t: ExecutionError.make({\n\t\t\t\t\tdetail: \"Inspecting process identity failed\",\n\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t}),\n\t),\n)\n\nexport const identity = Effect.fnUntraced(function* (pid: number) {\n\tconst current = yield* inspect(pid)\n\tif (Option.isNone(current))\n\t\treturn yield* ExecutionError.make({\n\t\t\tdetail: \"The child exited before its identity could be recorded\",\n\t\t})\n\treturn { pid, start: current.value }\n})\n\n// The OS may discard argv before reporting a zombie; PID and start time remain the identity.\nexport const matches = Effect.fnUntraced(function* (child: ProcessIdentity) {\n\tconst current = yield* inspect(child.pid)\n\tif (Option.isNone(current) || current.value.born !== child.start.born)\n\t\treturn false\n\treturn true\n})\n\nexport const recover = Effect.fnUntraced(function* (child: ProcessIdentity) {\n\tif (!(yield* matches(child)))\n\t\treturn {\n\t\t\tkind: \"Exited\",\n\t\t\texit: { code: null, signal: null },\n\t\t\tcause: Cause.empty,\n\t\t} satisfies Termination\n\t// The PID can still be reused between this final check and kill; an external supervisor covers descendants.\n\tconst sent = yield* Effect.exit(\n\t\tEffect.try({\n\t\t\ttry: () => process.kill(child.pid, \"SIGKILL\"),\n\t\t\tcatch: (cause) =>\n\t\t\t\tExecutionError.make({\n\t\t\t\t\tdetail: \"Signaling the orphan failed\",\n\t\t\t\t\tcause: Cause.die(cause),\n\t\t\t\t}),\n\t\t}),\n\t)\n\tconst confirmed = yield* matches(child).pipe(\n\t\tEffect.repeat({\n\t\t\tschedule: Schedule.spaced(\"50 millis\"),\n\t\t\twhile: (value) => value,\n\t\t}),\n\t\tEffect.timeoutOption(\"10 seconds\"),\n\t)\n\tif (Option.isNone(confirmed))\n\t\treturn yield* TerminationUnconfirmed.make({\n\t\t\tdetail: \"The orphan did not exit after recovery\",\n\t\t\tcause: sent._tag === \"Failure\" ? sent.cause : Cause.empty,\n\t\t})\n\treturn {\n\t\tkind: \"Killed\",\n\t\texit: { code: null, signal: \"SIGKILL\" },\n\t\tcause: sent._tag === \"Failure\" ? sent.cause : Cause.empty,\n\t} satisfies Termination\n})\n"],"mappings":";;;;;AAUA,MAAM,UAAU,OAAO,WACtB,WAAW,KAAa;CAEvB,MAAM,QAAQ,QAAO,OADE,oBAAoB,oBAAA,CACd,MAC5B,aAAa,KACZ,MACA;EAAC;EAAM,GAAG;EAAO;EAAM;EAAW;EAAM;CAAO,GAC/C;EACC,KAAK,EAAE,QAAQ,IAAI;EACnB,WAAW;EACX,OAAO;CACR,CACD,CACD;CACA,MAAM,CAAC,MAAM,QAAQ,UAAU,OAAO,OAAO,IAC5C;EACC,MAAM;EACN,MAAM,OAAO,KAAK,OAAO,WAAW,GAAG,OAAO,QAAQ;EACtD,MAAM,OAAO,KAAK,OAAO,WAAW,GAAG,OAAO,QAAQ;CACvD,GACA,EAAE,aAAa,YAAY,CAC5B;CACA,IAAI,SAAS,KAAK,OAAO,KAAK,MAAM,MAAM,IAAI,OAAO,OAAO,KAAK;CACjE,MAAM,GAAG,MAAM,UACd,qBAAqB,KAAK,OAAO,KAAK,MAAM,CAAC,KAAK,CAAC;CACpD,IAAI,SAAS,KAAK,SAAS,KAAA,KAAa,WAAW,KAAA,GAClD,OAAO,OAAO,eAAe,KAAK,EACjC,QAAQ,sCAAsC,OAC/C,CAAC;CACF,IAAI,OAAO,WAAW,GAAG,CAAC,CAAC,MAAM,GAAG,OAAO,OAAO,KAAK;CACvD,OAAO,OAAO,KAAK,EAAE,KAAK,CAAC;AAC5B,GACA,OAAO,QACP,OAAO,UAAU,UAChB,MAAM,SAAS,mBACZ,QACA,eAAe,KAAK;CACpB,QAAQ;CACR,OAAO,MAAM,KAAK,KAAK;AACxB,CAAC,CACJ,CACD;AAEA,MAAa,WAAW,OAAO,WAAW,WAAW,KAAa;CACjE,MAAM,UAAU,OAAO,QAAQ,GAAG;CAClC,IAAI,OAAO,OAAO,OAAO,GACxB,OAAO,OAAO,eAAe,KAAK,EACjC,QAAQ,yDACT,CAAC;CACF,OAAO;EAAE;EAAK,OAAO,QAAQ;CAAM;AACpC,CAAC;AAGD,MAAa,UAAU,OAAO,WAAW,WAAW,OAAwB;CAC3E,MAAM,UAAU,OAAO,QAAQ,MAAM,GAAG;CACxC,IAAI,OAAO,OAAO,OAAO,KAAK,QAAQ,MAAM,SAAS,MAAM,MAAM,MAChE,OAAO;CACR,OAAO;AACR,CAAC;AAED,MAAa,UAAU,OAAO,WAAW,WAAW,OAAwB;CAC3E,IAAI,EAAE,OAAO,QAAQ,KAAK,IACzB,OAAO;EACN,MAAM;EACN,MAAM;GAAE,MAAM;GAAM,QAAQ;EAAK;EACjC,OAAO,MAAM;CACd;CAED,MAAM,OAAO,OAAO,OAAO,KAC1B,OAAO,IAAI;EACV,WAAW,QAAQ,KAAK,MAAM,KAAK,SAAS;EAC5C,QAAQ,UACP,eAAe,KAAK;GACnB,QAAQ;GACR,OAAO,MAAM,IAAI,KAAK;EACvB,CAAC;CACH,CAAC,CACF;CACA,MAAM,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,KACvC,OAAO,OAAO;EACb,UAAU,SAAS,OAAO,WAAW;EACrC,QAAQ,UAAU;CACnB,CAAC,GACD,OAAO,cAAc,YAAY,CAClC;CACA,IAAI,OAAO,OAAO,SAAS,GAC1B,OAAO,OAAO,uBAAuB,KAAK;EACzC,QAAQ;EACR,OAAO,KAAK,SAAS,YAAY,KAAK,QAAQ,MAAM;CACrD,CAAC;CACF,OAAO;EACN,MAAM;EACN,MAAM;GAAE,MAAM;GAAM,QAAQ;EAAU;EACtC,OAAO,KAAK,SAAS,YAAY,KAAK,QAAQ,MAAM;CACrD;AACD,CAAC"}
@@ -16,7 +16,7 @@ const memory = Effect.gen(function* () {
16
16
  * Older terminal request ids expire; Open fences their retries with expectedGeneration.
17
17
  * Requires exclusive directory ownership; it is not a multi-writer database.
18
18
  */
19
- const directory = (root) => Effect.gen(function* () {
19
+ const directory = Effect.fnUntraced(function* (root) {
20
20
  const fs = yield* FileSystem.FileSystem;
21
21
  const path = yield* Path.Path;
22
22
  const digest = yield* Digest.Digest;
@@ -46,7 +46,7 @@ const directory = (root) => Effect.gen(function* () {
46
46
  yield* storage(compact);
47
47
  return Store.of({
48
48
  list: storage(mutex.withPermit(read.pipe(Effect.map((rows) => Array.map(rows, (row) => row.record))))),
49
- save: (record) => storage(mutex.withPermit(Effect.scoped(Effect.gen(function* () {
49
+ save: Effect.fnUntraced(function* (record) {
50
50
  const encoded = yield* Schema.encodeEffect(json)(record);
51
51
  const address = yield* Schema.encodeEffect(Schema.fromJsonString(Schema.Struct({
52
52
  key: Key,
@@ -68,7 +68,7 @@ const directory = (root) => Effect.gen(function* () {
68
68
  yield* (yield* fs.open(root, { flag: "r" })).sync.pipe(Effect.uninterruptible);
69
69
  }));
70
70
  yield* compact;
71
- }))))
71
+ }, Effect.scoped, mutex.withPermit, storage)
72
72
  });
73
73
  });
74
74
  Layer.effect(Store, memory);
@@ -1 +1 @@
1
- {"version":3,"file":"Store.js","names":["Retention.save","Retention.retain"],"sources":["../../../src/internal/runner/Store.ts"],"sourcesContent":["import {\n\tArray,\n\tCause,\n\tLayer,\n\tEffect,\n\tFileSystem,\n\tHashMap,\n\tHashSet,\n\tPath,\n\tRef,\n\tSchema,\n\tSemaphore,\n\tString,\n\ttype PlatformError,\n} from \"effect\"\nimport { Digest, SecureRandom } from \"effect/crypto\"\nimport { Key, SessionRecord, Store, StateStorageError } from \"./model\"\nimport * as Retention from \"./Retention\"\n\n/** Injectable store used by deterministic supervisor tests. */\nexport const memory = Effect.gen(function* () {\n\tconst records = yield* Ref.make(HashMap.empty<string, SessionRecord>())\n\treturn Store.of({\n\t\tlist: Ref.get(records).pipe(\n\t\t\tEffect.map((records) => Array.fromIterable(HashMap.values(records))),\n\t\t),\n\t\tsave: (record) => Ref.update(records, (all) => Retention.save(all, record)),\n\t})\n})\n\n/**\n * Atomically replaced records retain unfinished sessions and each key's high-water mark.\n * Older terminal request ids expire; Open fences their retries with expectedGeneration.\n * Requires exclusive directory ownership; it is not a multi-writer database.\n */\nexport const directory = (root: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem\n\t\tconst path = yield* Path.Path\n\t\tconst digest = yield* Digest.Digest\n\t\tconst json = Schema.fromJsonString(Schema.toCodecJson(SessionRecord))\n\t\tconst random = yield* SecureRandom.SecureRandom\n\t\tconst storage = <A, R>(\n\t\t\teffect: Effect.Effect<\n\t\t\t\tA,\n\t\t\t\tPlatformError.PlatformError | Schema.SchemaError | StateStorageError,\n\t\t\t\tR\n\t\t\t>,\n\t\t) =>\n\t\t\teffect.pipe(\n\t\t\t\tEffect.mapError((error) =>\n\t\t\t\t\terror._tag === \"StateStorageError\"\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: StateStorageError.make({\n\t\t\t\t\t\t\t\tdetail: \"Runner state storage failed\",\n\t\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)\n\t\tyield* storage(\n\t\t\tfs.makeDirectory(root, { recursive: true }).pipe(Effect.uninterruptible),\n\t\t)\n\t\tconst mutex = yield* Semaphore.make(1)\n\t\tconst read = Effect.gen(function* () {\n\t\t\tconst files = yield* fs.readDirectory(root)\n\t\t\tconst rows = yield* Effect.forEach(\n\t\t\t\tArray.filter(files, String.endsWith(\".json\")),\n\t\t\t\t(file) =>\n\t\t\t\t\tfs.readFileString(path.join(root, file)).pipe(\n\t\t\t\t\t\tEffect.flatMap(Schema.decodeEffect(json)),\n\t\t\t\t\t\tEffect.map((record) => ({ file, record })),\n\t\t\t\t\t),\n\t\t\t)\n\t\t\treturn rows\n\t\t})\n\t\tconst compact = Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst rows = yield* read\n\t\t\t\tconst retained = Retention.retain(Array.map(rows, (row) => row.record))\n\t\t\t\tconst tokens = HashSet.fromIterable(\n\t\t\t\t\tArray.map(retained, (record) => record.handle.token),\n\t\t\t\t)\n\t\t\t\tconst obsolete = Array.filter(\n\t\t\t\t\trows,\n\t\t\t\t\t(row) => !HashSet.has(tokens, row.record.handle.token),\n\t\t\t\t)\n\t\t\t\tyield* Effect.forEach(\n\t\t\t\t\tobsolete,\n\t\t\t\t\t(row) =>\n\t\t\t\t\t\tfs.remove(path.join(root, row.file)).pipe(Effect.uninterruptible),\n\t\t\t\t\t{ discard: true },\n\t\t\t\t)\n\t\t\t\tif (obsolete.length > 0) {\n\t\t\t\t\tconst directory = yield* fs.open(root, { flag: \"r\" })\n\t\t\t\t\tyield* directory.sync.pipe(Effect.uninterruptible)\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t\tyield* storage(compact)\n\t\treturn Store.of({\n\t\t\tlist: storage(\n\t\t\t\tmutex.withPermit(\n\t\t\t\t\tread.pipe(Effect.map((rows) => Array.map(rows, (row) => row.record))),\n\t\t\t\t),\n\t\t\t),\n\t\t\tsave: (record) =>\n\t\t\t\tstorage(\n\t\t\t\t\tmutex.withPermit(\n\t\t\t\t\t\tEffect.scoped(\n\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\tconst encoded = yield* Schema.encodeEffect(json)(record)\n\t\t\t\t\t\t\t\tconst address = yield* Schema.encodeEffect(\n\t\t\t\t\t\t\t\t\tSchema.fromJsonString(\n\t\t\t\t\t\t\t\t\t\tSchema.Struct({ key: Key, generation: Schema.Int }),\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\t\tkey: record.handle.key,\n\t\t\t\t\t\t\t\t\tgeneration: record.handle.generation,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tconst name = yield* digest.digestHex(\n\t\t\t\t\t\t\t\t\tDigest.sha256,\n\t\t\t\t\t\t\t\t\tnew TextEncoder().encode(address),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tconst nonce = yield* random.uuidV4()\n\t\t\t\t\t\t\t\tconst temporary = path.join(root, `.${name}.${nonce}.tmp`)\n\t\t\t\t\t\t\t\tconst destination = path.join(root, name + \".json\")\n\t\t\t\t\t\t\t\tyield* Effect.acquireRelease(\n\t\t\t\t\t\t\t\t\tfs.open(temporary, { flag: \"wx\", mode: 0o600 }),\n\t\t\t\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\t\t\t\tfs.remove(temporary, { force: true }).pipe(Effect.orDie),\n\t\t\t\t\t\t\t\t).pipe(\n\t\t\t\t\t\t\t\t\tEffect.flatMap((file) =>\n\t\t\t\t\t\t\t\t\t\tfile\n\t\t\t\t\t\t\t\t\t\t\t.writeAll(new TextEncoder().encode(encoded))\n\t\t\t\t\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\t\t\t\t\tEffect.uninterruptible,\n\t\t\t\t\t\t\t\t\t\t\t\tEffect.andThen(file.sync.pipe(Effect.uninterruptible)),\n\t\t\t\t\t\t\t\t\t\t\t),\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\t// Keep rename and directory synchronization together if the caller is canceled.\n\t\t\t\t\t\t\t\tyield* Effect.uninterruptible(\n\t\t\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\t\t\tyield* fs.rename(temporary, destination)\n\t\t\t\t\t\t\t\t\t\tconst directory = yield* fs.open(root, { flag: \"r\" })\n\t\t\t\t\t\t\t\t\t\tyield* directory.sync.pipe(Effect.uninterruptible)\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\t// The new high-water file is durable before any old record is removed.\n\t\t\t\t\t\t\t\tyield* compact\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})\n\t})\n\nexport const layerMemory = Layer.effect(Store, memory)\nexport const layerDirectory = (root: string) =>\n\tLayer.effect(Store, directory(root))\n"],"mappings":"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"}
1
+ {"version":3,"file":"Store.js","names":["Retention.save","Retention.retain"],"sources":["../../../src/internal/runner/Store.ts"],"sourcesContent":["import {\n\tArray,\n\tCause,\n\tLayer,\n\tEffect,\n\tFileSystem,\n\tHashMap,\n\tHashSet,\n\tPath,\n\tRef,\n\tSchema,\n\tSemaphore,\n\tString,\n\ttype PlatformError,\n} from \"effect\"\nimport { Digest, SecureRandom } from \"effect/crypto\"\nimport { Key, SessionRecord, Store, StateStorageError } from \"./model\"\nimport * as Retention from \"./Retention\"\n\n/** Injectable store used by deterministic supervisor tests. */\nexport const memory = Effect.gen(function* () {\n\tconst records = yield* Ref.make(HashMap.empty<string, SessionRecord>())\n\treturn Store.of({\n\t\tlist: Ref.get(records).pipe(\n\t\t\tEffect.map((records) => Array.fromIterable(HashMap.values(records))),\n\t\t),\n\t\tsave: (record) => Ref.update(records, (all) => Retention.save(all, record)),\n\t})\n})\n\n/**\n * Atomically replaced records retain unfinished sessions and each key's high-water mark.\n * Older terminal request ids expire; Open fences their retries with expectedGeneration.\n * Requires exclusive directory ownership; it is not a multi-writer database.\n */\nexport const directory = Effect.fnUntraced(function* (root: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tconst digest = yield* Digest.Digest\n\tconst json = Schema.fromJsonString(Schema.toCodecJson(SessionRecord))\n\tconst random = yield* SecureRandom.SecureRandom\n\tconst storage = <A, R>(\n\t\teffect: Effect.Effect<\n\t\t\tA,\n\t\t\tPlatformError.PlatformError | Schema.SchemaError | StateStorageError,\n\t\t\tR\n\t\t>,\n\t) =>\n\t\teffect.pipe(\n\t\t\tEffect.mapError((error) =>\n\t\t\t\terror._tag === \"StateStorageError\"\n\t\t\t\t\t? error\n\t\t\t\t\t: StateStorageError.make({\n\t\t\t\t\t\t\tdetail: \"Runner state storage failed\",\n\t\t\t\t\t\t\tcause: Cause.fail(error),\n\t\t\t\t\t\t}),\n\t\t\t),\n\t\t)\n\tyield* storage(\n\t\tfs.makeDirectory(root, { recursive: true }).pipe(Effect.uninterruptible),\n\t)\n\tconst mutex = yield* Semaphore.make(1)\n\tconst read = Effect.gen(function* () {\n\t\tconst files = yield* fs.readDirectory(root)\n\t\tconst rows = yield* Effect.forEach(\n\t\t\tArray.filter(files, String.endsWith(\".json\")),\n\t\t\t(file) =>\n\t\t\t\tfs.readFileString(path.join(root, file)).pipe(\n\t\t\t\t\tEffect.flatMap(Schema.decodeEffect(json)),\n\t\t\t\t\tEffect.map((record) => ({ file, record })),\n\t\t\t\t),\n\t\t)\n\t\treturn rows\n\t})\n\tconst compact = Effect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tconst rows = yield* read\n\t\t\tconst retained = Retention.retain(Array.map(rows, (row) => row.record))\n\t\t\tconst tokens = HashSet.fromIterable(\n\t\t\t\tArray.map(retained, (record) => record.handle.token),\n\t\t\t)\n\t\t\tconst obsolete = Array.filter(\n\t\t\t\trows,\n\t\t\t\t(row) => !HashSet.has(tokens, row.record.handle.token),\n\t\t\t)\n\t\t\tyield* Effect.forEach(\n\t\t\t\tobsolete,\n\t\t\t\t(row) =>\n\t\t\t\t\tfs.remove(path.join(root, row.file)).pipe(Effect.uninterruptible),\n\t\t\t\t{ discard: true },\n\t\t\t)\n\t\t\tif (obsolete.length > 0) {\n\t\t\t\tconst directory = yield* fs.open(root, { flag: \"r\" })\n\t\t\t\tyield* directory.sync.pipe(Effect.uninterruptible)\n\t\t\t}\n\t\t}),\n\t)\n\tyield* storage(compact)\n\treturn Store.of({\n\t\tlist: storage(\n\t\t\tmutex.withPermit(\n\t\t\t\tread.pipe(Effect.map((rows) => Array.map(rows, (row) => row.record))),\n\t\t\t),\n\t\t),\n\t\tsave: Effect.fnUntraced(\n\t\t\tfunction* (record: SessionRecord) {\n\t\t\t\tconst encoded = yield* Schema.encodeEffect(json)(record)\n\t\t\t\tconst address = yield* Schema.encodeEffect(\n\t\t\t\t\tSchema.fromJsonString(\n\t\t\t\t\t\tSchema.Struct({ key: Key, generation: Schema.Int }),\n\t\t\t\t\t),\n\t\t\t\t)({\n\t\t\t\t\tkey: record.handle.key,\n\t\t\t\t\tgeneration: record.handle.generation,\n\t\t\t\t})\n\t\t\t\tconst name = yield* digest.digestHex(\n\t\t\t\t\tDigest.sha256,\n\t\t\t\t\tnew TextEncoder().encode(address),\n\t\t\t\t)\n\t\t\t\tconst nonce = yield* random.uuidV4()\n\t\t\t\tconst temporary = path.join(root, `.${name}.${nonce}.tmp`)\n\t\t\t\tconst destination = path.join(root, name + \".json\")\n\t\t\t\tyield* Effect.acquireRelease(\n\t\t\t\t\tfs.open(temporary, { flag: \"wx\", mode: 0o600 }),\n\t\t\t\t\t() => fs.remove(temporary, { force: true }).pipe(Effect.orDie),\n\t\t\t\t).pipe(\n\t\t\t\t\tEffect.flatMap((file) =>\n\t\t\t\t\t\tfile\n\t\t\t\t\t\t\t.writeAll(new TextEncoder().encode(encoded))\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tEffect.uninterruptible,\n\t\t\t\t\t\t\t\tEffect.andThen(file.sync.pipe(Effect.uninterruptible)),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t// Keep rename and directory synchronization together if the caller is canceled.\n\t\t\t\tyield* Effect.uninterruptible(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tyield* fs.rename(temporary, destination)\n\t\t\t\t\t\tconst directory = yield* fs.open(root, { flag: \"r\" })\n\t\t\t\t\t\tyield* directory.sync.pipe(Effect.uninterruptible)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t// The new high-water file is durable before any old record is removed.\n\t\t\t\tyield* compact\n\t\t\t},\n\t\t\tEffect.scoped,\n\t\t\tmutex.withPermit,\n\t\t\tstorage,\n\t\t),\n\t})\n})\n\nexport const layerMemory = Layer.effect(Store, memory)\nexport const layerDirectory = (root: string) =>\n\tLayer.effect(Store, directory(root))\n"],"mappings":"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"}