reactor-effect-client 0.7.1 → 0.8.0

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 (514) hide show
  1. package/NOTICE +7 -2
  2. package/README.md +103 -141
  3. package/dist/Coordinator.d.ts +382 -0
  4. package/dist/Coordinator.d.ts.map +1 -0
  5. package/dist/Coordinator.js +732 -0
  6. package/dist/Coordinator.js.map +1 -0
  7. package/dist/H3.d.ts +159 -0
  8. package/dist/H3.d.ts.map +1 -0
  9. package/dist/H3.js +21 -0
  10. package/dist/H3.js.map +1 -0
  11. package/dist/H3Source.d.ts +93 -0
  12. package/dist/H3Source.d.ts.map +1 -0
  13. package/dist/H3Source.js +401 -0
  14. package/dist/H3Source.js.map +1 -0
  15. package/dist/LocalSource.d.ts +68 -0
  16. package/dist/LocalSource.d.ts.map +1 -0
  17. package/dist/LocalSource.js +354 -0
  18. package/dist/LocalSource.js.map +1 -0
  19. package/dist/Media.d.ts +106 -0
  20. package/dist/Media.d.ts.map +1 -0
  21. package/dist/Media.js +16 -0
  22. package/dist/Media.js.map +1 -0
  23. package/dist/Peer.d.ts +134 -0
  24. package/dist/Peer.d.ts.map +1 -0
  25. package/dist/Peer.js +57 -0
  26. package/dist/Peer.js.map +1 -0
  27. package/dist/Playout.d.ts +724 -0
  28. package/dist/Playout.d.ts.map +1 -0
  29. package/dist/Playout.js +28 -0
  30. package/dist/Playout.js.map +1 -0
  31. package/dist/Reactor.d.ts +135 -0
  32. package/dist/Reactor.d.ts.map +1 -0
  33. package/dist/Reactor.js +158 -0
  34. package/dist/Reactor.js.map +1 -0
  35. package/dist/ReactorError.d.ts +331 -0
  36. package/dist/ReactorError.d.ts.map +1 -0
  37. package/dist/ReactorError.js +316 -0
  38. package/dist/ReactorError.js.map +1 -0
  39. package/dist/ReactorTest.d.ts +383 -0
  40. package/dist/ReactorTest.d.ts.map +1 -0
  41. package/dist/ReactorTest.js +317 -0
  42. package/dist/ReactorTest.js.map +1 -0
  43. package/dist/Session.d.ts +314 -0
  44. package/dist/Session.d.ts.map +1 -0
  45. package/dist/Session.js +51 -0
  46. package/dist/Session.js.map +1 -0
  47. package/dist/index.d.ts +12 -22
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +12 -11
  50. package/dist/index.js.map +1 -1
  51. package/dist/internal/correlator.d.ts +46 -0
  52. package/dist/internal/correlator.d.ts.map +1 -0
  53. package/dist/internal/correlator.js +150 -0
  54. package/dist/internal/correlator.js.map +1 -0
  55. package/dist/internal/deadline.d.ts +24 -0
  56. package/dist/internal/deadline.d.ts.map +1 -0
  57. package/dist/internal/deadline.js +44 -0
  58. package/dist/internal/deadline.js.map +1 -0
  59. package/dist/{h3/_internal/contracts.d.ts → internal/h3/commands.d.ts} +39 -33
  60. package/dist/internal/h3/commands.d.ts.map +1 -0
  61. package/dist/internal/h3/commands.js +128 -0
  62. package/dist/internal/h3/commands.js.map +1 -0
  63. package/dist/{h3 → internal/h3}/messages.d.ts +16 -11
  64. package/dist/internal/h3/messages.d.ts.map +1 -0
  65. package/dist/{h3 → internal/h3}/messages.js +19 -31
  66. package/dist/internal/h3/messages.js.map +1 -0
  67. package/dist/internal/h3/operations.d.ts +145 -0
  68. package/dist/internal/h3/operations.d.ts.map +1 -0
  69. package/dist/internal/h3/operations.js +284 -0
  70. package/dist/internal/h3/operations.js.map +1 -0
  71. package/dist/{h3 → internal/h3}/profile.d.ts +63 -65
  72. package/dist/internal/h3/profile.d.ts.map +1 -0
  73. package/dist/{h3 → internal/h3}/profile.js +39 -39
  74. package/dist/internal/h3/profile.js.map +1 -0
  75. package/dist/internal/h3/provider.d.ts +14 -0
  76. package/dist/internal/h3/provider.d.ts.map +1 -0
  77. package/dist/internal/h3/provider.js +672 -0
  78. package/dist/internal/h3/provider.js.map +1 -0
  79. package/dist/internal/h3/references.d.ts +68 -0
  80. package/dist/internal/h3/references.d.ts.map +1 -0
  81. package/dist/internal/h3/references.js +339 -0
  82. package/dist/internal/h3/references.js.map +1 -0
  83. package/dist/internal/h3/request.d.ts +56 -0
  84. package/dist/internal/h3/request.d.ts.map +1 -0
  85. package/dist/internal/h3/request.js +70 -0
  86. package/dist/internal/h3/request.js.map +1 -0
  87. package/dist/internal/h3/state.d.ts +120 -0
  88. package/dist/internal/h3/state.d.ts.map +1 -0
  89. package/dist/internal/h3/state.js +270 -0
  90. package/dist/internal/h3/state.js.map +1 -0
  91. package/dist/{Submission.d.ts → internal/h3/submission.d.ts} +1 -3
  92. package/dist/internal/h3/submission.d.ts.map +1 -0
  93. package/dist/{Submission.js → internal/h3/submission.js} +1 -9
  94. package/dist/internal/h3/submission.js.map +1 -0
  95. package/dist/internal/hub.d.ts +32 -0
  96. package/dist/internal/hub.d.ts.map +1 -0
  97. package/dist/internal/hub.js +92 -0
  98. package/dist/internal/hub.js.map +1 -0
  99. package/dist/internal/playout/errors.d.ts +51 -0
  100. package/dist/internal/playout/errors.d.ts.map +1 -0
  101. package/dist/internal/playout/errors.js +40 -0
  102. package/dist/internal/playout/errors.js.map +1 -0
  103. package/dist/internal/playout/policy.d.ts +559 -0
  104. package/dist/internal/playout/policy.d.ts.map +1 -0
  105. package/dist/internal/playout/policy.js +2338 -0
  106. package/dist/internal/playout/policy.js.map +1 -0
  107. package/dist/internal/playout/runtime.d.ts +28 -0
  108. package/dist/internal/playout/runtime.d.ts.map +1 -0
  109. package/dist/internal/playout/runtime.js +766 -0
  110. package/dist/internal/playout/runtime.js.map +1 -0
  111. package/dist/internal/playout/tag.d.ts +14 -0
  112. package/dist/internal/playout/tag.d.ts.map +1 -0
  113. package/dist/internal/playout/tag.js +43 -0
  114. package/dist/internal/playout/tag.js.map +1 -0
  115. package/dist/internal/proto/reactor_wire/v1/common_pb.d.ts +55 -0
  116. package/dist/internal/proto/reactor_wire/v1/common_pb.d.ts.map +1 -0
  117. package/dist/internal/proto/reactor_wire/v1/common_pb.js +42 -0
  118. package/dist/internal/proto/reactor_wire/v1/common_pb.js.map +1 -0
  119. package/dist/internal/proto/reactor_wire/v1/control_pb.d.ts +160 -0
  120. package/dist/internal/proto/reactor_wire/v1/control_pb.d.ts.map +1 -0
  121. package/dist/internal/proto/reactor_wire/v1/control_pb.js +21 -0
  122. package/dist/internal/proto/reactor_wire/v1/control_pb.js.map +1 -0
  123. package/dist/internal/proto/reactor_wire/v1/data_pb.d.ts +89 -0
  124. package/dist/internal/proto/reactor_wire/v1/data_pb.d.ts.map +1 -0
  125. package/dist/internal/proto/reactor_wire/v1/data_pb.js +20 -0
  126. package/dist/internal/proto/reactor_wire/v1/data_pb.js.map +1 -0
  127. package/dist/internal/proto/reactor_wire/v1/model_pb.d.ts +85 -0
  128. package/dist/internal/proto/reactor_wire/v1/model_pb.d.ts.map +1 -0
  129. package/dist/internal/proto/reactor_wire/v1/model_pb.js +24 -0
  130. package/dist/internal/proto/reactor_wire/v1/model_pb.js.map +1 -0
  131. package/dist/internal/proto/reactor_wire/v1/platform_pb.d.ts +190 -0
  132. package/dist/internal/proto/reactor_wire/v1/platform_pb.d.ts.map +1 -0
  133. package/dist/internal/proto/reactor_wire/v1/platform_pb.js +54 -0
  134. package/dist/internal/proto/reactor_wire/v1/platform_pb.js.map +1 -0
  135. package/dist/internal/proto/reactor_wire/v1/track_pb.d.ts +88 -0
  136. package/dist/internal/proto/reactor_wire/v1/track_pb.d.ts.map +1 -0
  137. package/dist/internal/proto/reactor_wire/v1/track_pb.js +33 -0
  138. package/dist/internal/proto/reactor_wire/v1/track_pb.js.map +1 -0
  139. package/dist/internal/queue.d.ts +4 -0
  140. package/dist/internal/queue.d.ts.map +1 -0
  141. package/dist/{_internal → internal}/queue.js +0 -9
  142. package/dist/internal/queue.js.map +1 -0
  143. package/dist/internal/reactorTest/coordinator.d.ts +5 -0
  144. package/dist/internal/reactorTest/coordinator.d.ts.map +1 -0
  145. package/dist/internal/reactorTest/coordinator.js +178 -0
  146. package/dist/internal/reactorTest/coordinator.js.map +1 -0
  147. package/dist/internal/reactorTest/faults.d.ts +172 -0
  148. package/dist/internal/reactorTest/faults.d.ts.map +1 -0
  149. package/dist/internal/reactorTest/faults.js +23 -0
  150. package/dist/internal/reactorTest/faults.js.map +1 -0
  151. package/dist/internal/reactorTest/h3.d.ts +431 -0
  152. package/dist/internal/reactorTest/h3.d.ts.map +1 -0
  153. package/dist/internal/reactorTest/h3.js +625 -0
  154. package/dist/internal/reactorTest/h3.js.map +1 -0
  155. package/dist/internal/reactorTest/media.d.ts +22 -0
  156. package/dist/internal/reactorTest/media.d.ts.map +1 -0
  157. package/dist/internal/reactorTest/media.js +34 -0
  158. package/dist/internal/reactorTest/media.js.map +1 -0
  159. package/dist/internal/reactorTest/peer.d.ts +318 -0
  160. package/dist/internal/reactorTest/peer.d.ts.map +1 -0
  161. package/dist/internal/reactorTest/peer.js +206 -0
  162. package/dist/internal/reactorTest/peer.js.map +1 -0
  163. package/dist/internal/reactorTest/playout.d.ts +34 -0
  164. package/dist/internal/reactorTest/playout.d.ts.map +1 -0
  165. package/dist/internal/reactorTest/playout.js +340 -0
  166. package/dist/internal/reactorTest/playout.js.map +1 -0
  167. package/dist/internal/reactorTest/references.d.ts +25 -0
  168. package/dist/internal/reactorTest/references.d.ts.map +1 -0
  169. package/dist/{testing/Png.js → internal/reactorTest/references.js} +50 -12
  170. package/dist/internal/reactorTest/references.js.map +1 -0
  171. package/dist/internal/reactorTest/sessions.d.ts +364 -0
  172. package/dist/internal/reactorTest/sessions.d.ts.map +1 -0
  173. package/dist/internal/reactorTest/sessions.js +592 -0
  174. package/dist/internal/reactorTest/sessions.js.map +1 -0
  175. package/dist/internal/reactorTest/timing.d.ts +13 -0
  176. package/dist/internal/reactorTest/timing.d.ts.map +1 -0
  177. package/dist/internal/reactorTest/timing.js +20 -0
  178. package/dist/internal/reactorTest/timing.js.map +1 -0
  179. package/dist/internal/recording.d.ts +52 -0
  180. package/dist/internal/recording.d.ts.map +1 -0
  181. package/dist/internal/recording.js +141 -0
  182. package/dist/internal/recording.js.map +1 -0
  183. package/dist/internal/session/connect.d.ts +34 -0
  184. package/dist/internal/session/connect.d.ts.map +1 -0
  185. package/dist/internal/session/connect.js +502 -0
  186. package/dist/internal/session/connect.js.map +1 -0
  187. package/dist/internal/session/generation.d.ts +35 -0
  188. package/dist/internal/session/generation.d.ts.map +1 -0
  189. package/dist/internal/session/generation.js +185 -0
  190. package/dist/internal/session/generation.js.map +1 -0
  191. package/dist/internal/session/ice.d.ts +23 -0
  192. package/dist/internal/session/ice.d.ts.map +1 -0
  193. package/dist/internal/session/ice.js +57 -0
  194. package/dist/internal/session/ice.js.map +1 -0
  195. package/dist/internal/session/inbound.d.ts +50 -0
  196. package/dist/internal/session/inbound.d.ts.map +1 -0
  197. package/dist/internal/session/inbound.js +202 -0
  198. package/dist/internal/session/inbound.js.map +1 -0
  199. package/dist/internal/session/model.d.ts +163 -0
  200. package/dist/internal/session/model.d.ts.map +1 -0
  201. package/dist/internal/session/model.js +78 -0
  202. package/dist/internal/session/model.js.map +1 -0
  203. package/dist/internal/session/requests.d.ts +71 -0
  204. package/dist/internal/session/requests.d.ts.map +1 -0
  205. package/dist/internal/session/requests.js +240 -0
  206. package/dist/internal/session/requests.js.map +1 -0
  207. package/dist/internal/session/tracks.d.ts +21 -0
  208. package/dist/internal/session/tracks.d.ts.map +1 -0
  209. package/dist/internal/session/tracks.js +166 -0
  210. package/dist/internal/session/tracks.js.map +1 -0
  211. package/dist/internal/session/upload.d.ts +21 -0
  212. package/dist/internal/session/upload.d.ts.map +1 -0
  213. package/dist/internal/session/upload.js +68 -0
  214. package/dist/internal/session/upload.js.map +1 -0
  215. package/dist/internal/session.d.ts +66 -0
  216. package/dist/internal/session.d.ts.map +1 -0
  217. package/dist/internal/session.js +280 -0
  218. package/dist/internal/session.js.map +1 -0
  219. package/dist/{stats.d.ts → internal/stats.d.ts} +30 -16
  220. package/dist/internal/stats.d.ts.map +1 -0
  221. package/dist/internal/stats.js +201 -0
  222. package/dist/internal/stats.js.map +1 -0
  223. package/dist/internal/token.d.ts +22 -0
  224. package/dist/internal/token.d.ts.map +1 -0
  225. package/dist/internal/token.js +65 -0
  226. package/dist/internal/token.js.map +1 -0
  227. package/dist/internal/wire.d.ts +37 -0
  228. package/dist/internal/wire.d.ts.map +1 -0
  229. package/dist/internal/wire.js +49 -0
  230. package/dist/internal/wire.js.map +1 -0
  231. package/notices/bufbuild-protobuf-LICENSE +201 -0
  232. package/package.json +17 -38
  233. package/dist/FetchHttp.d.ts +0 -9
  234. package/dist/FetchHttp.d.ts.map +0 -1
  235. package/dist/FetchHttp.js +0 -63
  236. package/dist/FetchHttp.js.map +0 -1
  237. package/dist/PeerFactory.d.ts +0 -26
  238. package/dist/PeerFactory.d.ts.map +0 -1
  239. package/dist/PeerFactory.js +0 -4
  240. package/dist/PeerFactory.js.map +0 -1
  241. package/dist/PeerTypes.d.ts +0 -64
  242. package/dist/PeerTypes.d.ts.map +0 -1
  243. package/dist/PeerTypes.js +0 -2
  244. package/dist/PeerTypes.js.map +0 -1
  245. package/dist/Sequence.d.ts +0 -85
  246. package/dist/Sequence.d.ts.map +0 -1
  247. package/dist/Sequence.js +0 -210
  248. package/dist/Sequence.js.map +0 -1
  249. package/dist/SessionTypes.d.ts +0 -312
  250. package/dist/SessionTypes.d.ts.map +0 -1
  251. package/dist/SessionTypes.js +0 -19
  252. package/dist/SessionTypes.js.map +0 -1
  253. package/dist/Submission.d.ts.map +0 -1
  254. package/dist/Submission.js.map +0 -1
  255. package/dist/_internal/queue.d.ts +0 -6
  256. package/dist/_internal/queue.d.ts.map +0 -1
  257. package/dist/_internal/queue.js.map +0 -1
  258. package/dist/bytes.d.ts +0 -6
  259. package/dist/bytes.d.ts.map +0 -1
  260. package/dist/bytes.js +0 -32
  261. package/dist/bytes.js.map +0 -1
  262. package/dist/contract.d.ts +0 -149
  263. package/dist/contract.d.ts.map +0 -1
  264. package/dist/contract.js +0 -119
  265. package/dist/contract.js.map +0 -1
  266. package/dist/coordinator/_internal/client.d.ts +0 -215
  267. package/dist/coordinator/_internal/client.d.ts.map +0 -1
  268. package/dist/coordinator/_internal/client.js +0 -563
  269. package/dist/coordinator/_internal/client.js.map +0 -1
  270. package/dist/coordinator/_internal/recording.d.ts +0 -31
  271. package/dist/coordinator/_internal/recording.d.ts.map +0 -1
  272. package/dist/coordinator/_internal/recording.js +0 -123
  273. package/dist/coordinator/_internal/recording.js.map +0 -1
  274. package/dist/coordinator/_internal/response.d.ts +0 -15
  275. package/dist/coordinator/_internal/response.d.ts.map +0 -1
  276. package/dist/coordinator/_internal/response.js +0 -55
  277. package/dist/coordinator/_internal/response.js.map +0 -1
  278. package/dist/coordinator/_internal/schemas.d.ts +0 -73
  279. package/dist/coordinator/_internal/schemas.d.ts.map +0 -1
  280. package/dist/coordinator/_internal/schemas.js +0 -200
  281. package/dist/coordinator/_internal/schemas.js.map +0 -1
  282. package/dist/coordinator/index.d.ts +0 -40
  283. package/dist/coordinator/index.d.ts.map +0 -1
  284. package/dist/coordinator/index.js +0 -21
  285. package/dist/coordinator/index.js.map +0 -1
  286. package/dist/correlation.d.ts +0 -47
  287. package/dist/correlation.d.ts.map +0 -1
  288. package/dist/correlation.js +0 -131
  289. package/dist/correlation.js.map +0 -1
  290. package/dist/duration.d.ts +0 -27
  291. package/dist/duration.d.ts.map +0 -1
  292. package/dist/duration.js +0 -47
  293. package/dist/duration.js.map +0 -1
  294. package/dist/errors.d.ts +0 -1303
  295. package/dist/errors.d.ts.map +0 -1
  296. package/dist/errors.js +0 -745
  297. package/dist/errors.js.map +0 -1
  298. package/dist/h3/_internal/client.d.ts +0 -9
  299. package/dist/h3/_internal/client.d.ts.map +0 -1
  300. package/dist/h3/_internal/client.js +0 -652
  301. package/dist/h3/_internal/client.js.map +0 -1
  302. package/dist/h3/_internal/contracts.d.ts.map +0 -1
  303. package/dist/h3/_internal/contracts.js +0 -123
  304. package/dist/h3/_internal/contracts.js.map +0 -1
  305. package/dist/h3/_internal/deployment.d.ts +0 -8
  306. package/dist/h3/_internal/deployment.d.ts.map +0 -1
  307. package/dist/h3/_internal/deployment.js +0 -149
  308. package/dist/h3/_internal/deployment.js.map +0 -1
  309. package/dist/h3/_internal/evidence.d.ts +0 -17
  310. package/dist/h3/_internal/evidence.d.ts.map +0 -1
  311. package/dist/h3/_internal/evidence.js +0 -48
  312. package/dist/h3/_internal/evidence.js.map +0 -1
  313. package/dist/h3/_internal/operations.d.ts +0 -58
  314. package/dist/h3/_internal/operations.d.ts.map +0 -1
  315. package/dist/h3/_internal/operations.js +0 -268
  316. package/dist/h3/_internal/operations.js.map +0 -1
  317. package/dist/h3/_internal/references.d.ts +0 -24
  318. package/dist/h3/_internal/references.d.ts.map +0 -1
  319. package/dist/h3/_internal/references.js +0 -309
  320. package/dist/h3/_internal/references.js.map +0 -1
  321. package/dist/h3/_internal/request.d.ts +0 -21
  322. package/dist/h3/_internal/request.d.ts.map +0 -1
  323. package/dist/h3/_internal/request.js +0 -97
  324. package/dist/h3/_internal/request.js.map +0 -1
  325. package/dist/h3/_internal/retained.d.ts +0 -22
  326. package/dist/h3/_internal/retained.d.ts.map +0 -1
  327. package/dist/h3/_internal/retained.js +0 -89
  328. package/dist/h3/_internal/retained.js.map +0 -1
  329. package/dist/h3/_internal/state.d.ts +0 -44
  330. package/dist/h3/_internal/state.d.ts.map +0 -1
  331. package/dist/h3/_internal/state.js +0 -283
  332. package/dist/h3/_internal/state.js.map +0 -1
  333. package/dist/h3/index.d.ts +0 -10
  334. package/dist/h3/index.d.ts.map +0 -1
  335. package/dist/h3/index.js +0 -7
  336. package/dist/h3/index.js.map +0 -1
  337. package/dist/h3/messages.d.ts.map +0 -1
  338. package/dist/h3/messages.js.map +0 -1
  339. package/dist/h3/profile.d.ts.map +0 -1
  340. package/dist/h3/profile.js.map +0 -1
  341. package/dist/h3/types.d.ts +0 -291
  342. package/dist/h3/types.d.ts.map +0 -1
  343. package/dist/h3/types.js +0 -2
  344. package/dist/h3/types.js.map +0 -1
  345. package/dist/host.d.ts +0 -26
  346. package/dist/host.d.ts.map +0 -1
  347. package/dist/host.js +0 -20
  348. package/dist/host.js.map +0 -1
  349. package/dist/json.d.ts +0 -25
  350. package/dist/json.d.ts.map +0 -1
  351. package/dist/json.js +0 -143
  352. package/dist/json.js.map +0 -1
  353. package/dist/media-stream.d.ts +0 -10
  354. package/dist/media-stream.d.ts.map +0 -1
  355. package/dist/media-stream.js +0 -18
  356. package/dist/media-stream.js.map +0 -1
  357. package/dist/observation.d.ts +0 -38
  358. package/dist/observation.d.ts.map +0 -1
  359. package/dist/observation.js +0 -113
  360. package/dist/observation.js.map +0 -1
  361. package/dist/orchestration/elapsed.d.ts +0 -9
  362. package/dist/orchestration/elapsed.d.ts.map +0 -1
  363. package/dist/orchestration/elapsed.js +0 -8
  364. package/dist/orchestration/elapsed.js.map +0 -1
  365. package/dist/orchestration/h3-source.d.ts +0 -58
  366. package/dist/orchestration/h3-source.d.ts.map +0 -1
  367. package/dist/orchestration/h3-source.js +0 -362
  368. package/dist/orchestration/h3-source.js.map +0 -1
  369. package/dist/orchestration/index.d.ts +0 -17
  370. package/dist/orchestration/index.d.ts.map +0 -1
  371. package/dist/orchestration/index.js +0 -12
  372. package/dist/orchestration/index.js.map +0 -1
  373. package/dist/orchestration/media-buffer.d.ts +0 -32
  374. package/dist/orchestration/media-buffer.d.ts.map +0 -1
  375. package/dist/orchestration/media-buffer.js +0 -94
  376. package/dist/orchestration/media-buffer.js.map +0 -1
  377. package/dist/orchestration/open-h3.d.ts +0 -101
  378. package/dist/orchestration/open-h3.d.ts.map +0 -1
  379. package/dist/orchestration/open-h3.js +0 -127
  380. package/dist/orchestration/open-h3.js.map +0 -1
  381. package/dist/orchestration/queries.d.ts +0 -10
  382. package/dist/orchestration/queries.d.ts.map +0 -1
  383. package/dist/orchestration/queries.js +0 -43
  384. package/dist/orchestration/queries.js.map +0 -1
  385. package/dist/orchestration/references.d.ts +0 -18
  386. package/dist/orchestration/references.d.ts.map +0 -1
  387. package/dist/orchestration/references.js +0 -79
  388. package/dist/orchestration/references.js.map +0 -1
  389. package/dist/orchestration/renewal-state.d.ts +0 -84
  390. package/dist/orchestration/renewal-state.d.ts.map +0 -1
  391. package/dist/orchestration/renewal-state.js +0 -95
  392. package/dist/orchestration/renewal-state.js.map +0 -1
  393. package/dist/orchestration/renewal.d.ts +0 -103
  394. package/dist/orchestration/renewal.d.ts.map +0 -1
  395. package/dist/orchestration/renewal.js +0 -1099
  396. package/dist/orchestration/renewal.js.map +0 -1
  397. package/dist/orchestration/request.d.ts +0 -65
  398. package/dist/orchestration/request.d.ts.map +0 -1
  399. package/dist/orchestration/request.js +0 -134
  400. package/dist/orchestration/request.js.map +0 -1
  401. package/dist/orchestration/retention.d.ts +0 -100
  402. package/dist/orchestration/retention.d.ts.map +0 -1
  403. package/dist/orchestration/retention.js +0 -134
  404. package/dist/orchestration/retention.js.map +0 -1
  405. package/dist/orchestration/routing.d.ts +0 -21
  406. package/dist/orchestration/routing.d.ts.map +0 -1
  407. package/dist/orchestration/routing.js +0 -93
  408. package/dist/orchestration/routing.js.map +0 -1
  409. package/dist/orchestration/scheduler-key.d.ts +0 -14
  410. package/dist/orchestration/scheduler-key.d.ts.map +0 -1
  411. package/dist/orchestration/scheduler-key.js +0 -62
  412. package/dist/orchestration/scheduler-key.js.map +0 -1
  413. package/dist/orchestration/scheduler-policy.d.ts +0 -246
  414. package/dist/orchestration/scheduler-policy.d.ts.map +0 -1
  415. package/dist/orchestration/scheduler-policy.js +0 -668
  416. package/dist/orchestration/scheduler-policy.js.map +0 -1
  417. package/dist/orchestration/scheduler.d.ts +0 -393
  418. package/dist/orchestration/scheduler.d.ts.map +0 -1
  419. package/dist/orchestration/scheduler.js +0 -2621
  420. package/dist/orchestration/scheduler.js.map +0 -1
  421. package/dist/orchestration/source-slot.d.ts +0 -124
  422. package/dist/orchestration/source-slot.d.ts.map +0 -1
  423. package/dist/orchestration/source-slot.js +0 -348
  424. package/dist/orchestration/source-slot.js.map +0 -1
  425. package/dist/orchestration/types.d.ts +0 -1462
  426. package/dist/orchestration/types.d.ts.map +0 -1
  427. package/dist/orchestration/types.js +0 -135
  428. package/dist/orchestration/types.js.map +0 -1
  429. package/dist/protobuf.d.ts +0 -63
  430. package/dist/protobuf.d.ts.map +0 -1
  431. package/dist/protobuf.js +0 -252
  432. package/dist/protobuf.js.map +0 -1
  433. package/dist/session/_internal/acquire.d.ts +0 -21
  434. package/dist/session/_internal/acquire.d.ts.map +0 -1
  435. package/dist/session/_internal/acquire.js +0 -168
  436. package/dist/session/_internal/acquire.js.map +0 -1
  437. package/dist/session/_internal/cleanup.d.ts +0 -19
  438. package/dist/session/_internal/cleanup.d.ts.map +0 -1
  439. package/dist/session/_internal/cleanup.js +0 -102
  440. package/dist/session/_internal/cleanup.js.map +0 -1
  441. package/dist/session/_internal/lifecycle.d.ts +0 -67
  442. package/dist/session/_internal/lifecycle.d.ts.map +0 -1
  443. package/dist/session/_internal/lifecycle.js +0 -142
  444. package/dist/session/_internal/lifecycle.js.map +0 -1
  445. package/dist/session/_internal/remote.d.ts +0 -28
  446. package/dist/session/_internal/remote.d.ts.map +0 -1
  447. package/dist/session/_internal/remote.js +0 -71
  448. package/dist/session/_internal/remote.js.map +0 -1
  449. package/dist/session/_internal/uploads.d.ts +0 -7
  450. package/dist/session/_internal/uploads.d.ts.map +0 -1
  451. package/dist/session/_internal/uploads.js +0 -31
  452. package/dist/session/_internal/uploads.js.map +0 -1
  453. package/dist/session/commands.d.ts +0 -2
  454. package/dist/session/commands.d.ts.map +0 -1
  455. package/dist/session/commands.js +0 -2
  456. package/dist/session/commands.js.map +0 -1
  457. package/dist/session/files.d.ts +0 -21
  458. package/dist/session/files.d.ts.map +0 -1
  459. package/dist/session/files.js +0 -49
  460. package/dist/session/files.js.map +0 -1
  461. package/dist/session/index.d.ts +0 -84
  462. package/dist/session/index.d.ts.map +0 -1
  463. package/dist/session/index.js +0 -16
  464. package/dist/session/index.js.map +0 -1
  465. package/dist/session/media.d.ts +0 -114
  466. package/dist/session/media.d.ts.map +0 -1
  467. package/dist/session/media.js +0 -2
  468. package/dist/session/media.js.map +0 -1
  469. package/dist/session/recorder.d.ts +0 -24
  470. package/dist/session/recorder.d.ts.map +0 -1
  471. package/dist/session/recorder.js +0 -19
  472. package/dist/session/recorder.js.map +0 -1
  473. package/dist/session.d.ts +0 -105
  474. package/dist/session.d.ts.map +0 -1
  475. package/dist/session.js +0 -976
  476. package/dist/session.js.map +0 -1
  477. package/dist/simulation/_internal/source.d.ts +0 -12
  478. package/dist/simulation/_internal/source.d.ts.map +0 -1
  479. package/dist/simulation/_internal/source.js +0 -513
  480. package/dist/simulation/_internal/source.js.map +0 -1
  481. package/dist/simulation/index.d.ts +0 -13
  482. package/dist/simulation/index.d.ts.map +0 -1
  483. package/dist/simulation/index.js +0 -12
  484. package/dist/simulation/index.js.map +0 -1
  485. package/dist/simulation/types.d.ts +0 -39
  486. package/dist/simulation/types.d.ts.map +0 -1
  487. package/dist/simulation/types.js +0 -2
  488. package/dist/simulation/types.js.map +0 -1
  489. package/dist/stats.d.ts.map +0 -1
  490. package/dist/stats.js +0 -205
  491. package/dist/stats.js.map +0 -1
  492. package/dist/testing/Faults.d.ts +0 -4
  493. package/dist/testing/Faults.d.ts.map +0 -1
  494. package/dist/testing/Faults.js +0 -7
  495. package/dist/testing/Faults.js.map +0 -1
  496. package/dist/testing/Png.d.ts +0 -3
  497. package/dist/testing/Png.d.ts.map +0 -1
  498. package/dist/testing/Png.js.map +0 -1
  499. package/dist/testing/Wav.d.ts +0 -14
  500. package/dist/testing/Wav.d.ts.map +0 -1
  501. package/dist/testing/Wav.js +0 -37
  502. package/dist/testing/Wav.js.map +0 -1
  503. package/dist/testing/index.d.ts +0 -5
  504. package/dist/testing/index.d.ts.map +0 -1
  505. package/dist/testing/index.js +0 -4
  506. package/dist/testing/index.js.map +0 -1
  507. package/dist/wire.d.ts +0 -7
  508. package/dist/wire.d.ts.map +0 -1
  509. package/dist/wire.generated.d.ts +0 -305
  510. package/dist/wire.generated.d.ts.map +0 -1
  511. package/dist/wire.generated.js +0 -1257
  512. package/dist/wire.generated.js.map +0 -1
  513. package/dist/wire.js +0 -5
  514. package/dist/wire.js.map +0 -1
@@ -0,0 +1,766 @@
1
+ /**
2
+ * The playout's shell around its pure policy. One fiber owns the policy state:
3
+ * it takes an input (a caller's edit, a session's evidence, a command's result)
4
+ * or wakes at the policy's next deadline, runs `step`, and carries out what the
5
+ * step asks. Each session's provider commands go through a worker of its own,
6
+ * one at a time and in order, so a slow command holds up only its own
7
+ * session's; session opens and closes run in their own fibers. Each reports
8
+ * back through the inbox.
9
+ */
10
+ import * as Cause from "effect/Cause";
11
+ import * as Clock from "effect/Clock";
12
+ import * as Deferred from "effect/Deferred";
13
+ import * as Duration from "effect/Duration";
14
+ import * as Effect from "effect/Effect";
15
+ import * as ErrorReporter from "effect/ErrorReporter";
16
+ import * as Exit from "effect/Exit";
17
+ import * as Option from "effect/Option";
18
+ import * as Predicate from "effect/Predicate";
19
+ import * as PubSub from "effect/PubSub";
20
+ import * as Queue from "effect/Queue";
21
+ import * as Ref from "effect/Ref";
22
+ import * as Result from "effect/Result";
23
+ import * as Schema from "effect/Schema";
24
+ import * as SchemaIssue from "effect/SchemaIssue";
25
+ import * as Scope from "effect/Scope";
26
+ import * as Stream from "effect/Stream";
27
+ import * as SubscriptionRef from "effect/SubscriptionRef";
28
+ import { metadataMaxChars, requestSeconds } from "../h3/profile.js";
29
+ import { validateAudioReference, validateReference } from "../h3/references.js";
30
+ import { Request } from "../h3/request.js";
31
+ import { take } from "../queue.js";
32
+ import { AcquisitionFailure, CommandFailure, ReactorError } from "../../ReactorError.js";
33
+ import { mayStillBill } from "../../Session.js";
34
+ import { InvalidFiller, InvalidItem, ItemKey, KeyMismatch, LaneBusy, PlayoutClosed, WouldMissDeadline, } from "./errors.js";
35
+ import * as Policy from "./policy.js";
36
+ import * as Tag from "./tag.js";
37
+ /** Close reports kept beyond the unconfirmed ones. */
38
+ const retainedReports = 8;
39
+ const millis = (input, fallback) => input === undefined ? fallback : Duration.toMillis(Duration.fromInputUnsafe(input));
40
+ const monotonic = Effect.map(Clock.monotonicTimeNanos, (nanos) => Number(nanos) / 1_000_000);
41
+ /**
42
+ * The wait until a wake `ms` away, in whole nanoseconds rounded up: the clock counts whole
43
+ * nanoseconds, and a wake between two of them comes at the later one.
44
+ */
45
+ const untilWake = (ms) => Duration.nanos(BigInt(Math.max(0, Math.ceil(ms * 1_000_000))));
46
+ /**
47
+ * Reports the defects of `cause`, whose failure decides what it was for. A defect beside a
48
+ * failure, such as a finalizer's that died as the effect failed, is still one; the failure, which
49
+ * the plan handles, is not reported.
50
+ */
51
+ const reportDefects = (cause) => {
52
+ const dies = cause.reasons.filter(Cause.isDieReason);
53
+ return dies.length > 0 ? ErrorReporter.report(Cause.fromReasons(dies)) : Effect.void;
54
+ };
55
+ /**
56
+ * Closes `scope` with `exit`. A finalizer that dies is reported, and what follows the close goes
57
+ * on: a failed open still says it failed.
58
+ */
59
+ const closeScope = (scope, exit) => Scope.close(scope, exit).pipe(Effect.catchCause(reportDefects));
60
+ /**
61
+ * Where a request for the clip `tag` names falls outside H3's documented
62
+ * limits, field by field, or undefined within them: its metadata counted as
63
+ * sent, wrapped with the tag and H3's own identity. Each issue names its field
64
+ * and the limit, never the value, which may be a prompt.
65
+ */
66
+ const requestIssues = (request, tag) => {
67
+ const decoded = Schema.decodeResult(Request)(request, { errors: "all" });
68
+ const refused = (field, index) => (error) => [
69
+ { path: [field, String(index)], message: error.message },
70
+ ];
71
+ const issues = Result.isFailure(decoded)
72
+ ? SchemaIssue.makeFormatterStandardSchemaV1()(decoded.failure.issue).issues.map((issue) => ({
73
+ path: (issue.path ?? []).map((segment) => String(Predicate.isObject(segment) ? segment.key : segment)),
74
+ message: issue.message,
75
+ }))
76
+ : [
77
+ ...(decoded.success.references ?? []).flatMap((reference, index) => Result.match(validateReference(reference), {
78
+ onFailure: refused("references", index),
79
+ onSuccess: () => [],
80
+ })),
81
+ ...(decoded.success.audio ?? []).flatMap((reference, index) => Result.match(validateAudioReference(reference), {
82
+ onFailure: refused("audio", index),
83
+ onSuccess: () => [],
84
+ })),
85
+ ...(Tag.fits({ tag, metadata: decoded.success.metadata })
86
+ ? []
87
+ : [
88
+ {
89
+ path: ["metadata"],
90
+ message: `exceeds ${String(metadataMaxChars)} characters once wrapped as sent`,
91
+ },
92
+ ]),
93
+ ];
94
+ if (issues.length === 0)
95
+ return undefined;
96
+ return issues
97
+ .map(({ path, message }) => (path.length === 0 ? message : `${path.join(".")}: ${message}`))
98
+ .join("; ");
99
+ };
100
+ /** A stable fingerprint of a spec: byte payloads by length and a checksum, never by content. */
101
+ const fingerprint = (value) => JSON.stringify(value, (_, field) => {
102
+ if (field instanceof Uint8Array) {
103
+ let sum = 0;
104
+ for (const byte of field)
105
+ sum = (sum * 31 + byte) >>> 0;
106
+ return `bytes:${field.length}:${sum}`;
107
+ }
108
+ return typeof field === "bigint" ? field.toString() : field;
109
+ });
110
+ export const make = Effect.fnUntraced(function* (options) {
111
+ const config = {
112
+ lanes: options.lanes.map((lane) => ({
113
+ name: lane.name,
114
+ conflict: lane.conflict ?? "queue",
115
+ cut: lane.cut ?? false,
116
+ })),
117
+ filler: options.filler === undefined
118
+ ? undefined
119
+ : {
120
+ floor: millis(options.filler.runway.floor, 0) / 1000,
121
+ target: millis(options.filler.runway.target, 0) / 1000,
122
+ clip: options.filler.clip,
123
+ lengths: options.filler.lengths ?? requestSeconds,
124
+ invalid: (request, index) => {
125
+ const issues = requestIssues(request, { _tag: "Filler", index });
126
+ return issues === undefined
127
+ ? undefined
128
+ : `filler clip ${String(index)} asked for a request outside H3's documented limits: ${issues}`;
129
+ },
130
+ protect: options.filler.protect ?? "air",
131
+ },
132
+ maxBuildsInFlight: options.maxBuildsInFlight ?? 1,
133
+ maxHistory: options.maxHistory ?? 4096,
134
+ unknownTimeoutMs: millis(options.unknownTimeout, 60_000),
135
+ leadMs: millis(options.renewal?.lead, 30_000),
136
+ graceMs: millis(options.renewal?.grace, 250),
137
+ maxSetupFailures: options.renewal?.maxSetupFailures ?? 3,
138
+ maxModerations: options.maxModerations ?? 2,
139
+ };
140
+ /** An open must finish within this, the wait for a GPU and the connection included. */
141
+ const openTimeout = options.renewal?.openTimeout ?? "3 minutes";
142
+ const scope = yield* Effect.scope;
143
+ const context = yield* Effect.context();
144
+ const inbox = yield* Queue.unbounded();
145
+ const events = yield* PubSub.unbounded();
146
+ const state = yield* Ref.make(Policy.initial);
147
+ const ids = yield* Ref.make(0);
148
+ // What callers wait for, each resolved once and then forgotten: an edit's reply, a batch's
149
+ // commit, a batch withdrawal's outcome, a drain.
150
+ const replies = yield* Ref.make(new Map());
151
+ const commits = yield* Ref.make(new Map());
152
+ const withdrawals = yield* Ref.make(new Map());
153
+ const drains = yield* Ref.make(new Map());
154
+ const handles = yield* Ref.make(new Map());
155
+ // Each live session's source, the scope it lives in, and its lane: the commands waiting there.
156
+ const sources = yield* Ref.make(new Map());
157
+ const onAir = yield* SubscriptionRef.make(undefined);
158
+ // Why the playout stopped; it dies with a defect that stopped it.
159
+ const failure = yield* Deferred.make();
160
+ /** Completes once the playout has stopped, however it stopped. */
161
+ const stopped = Deferred.await(failure).pipe(Effect.exit);
162
+ // Why the latest open failed while no open has succeeded since, and why the latest session was
163
+ // lost: the error, or the defect when there was no error.
164
+ const lastOpenError = yield* Ref.make(undefined);
165
+ const lastLostError = yield* Ref.make(undefined);
166
+ const cleanup = yield* Ref.make({ sessions: 0, retained: [] });
167
+ const now = Effect.all({ mono: monotonic, wall: Clock.currentTimeMillis });
168
+ const nextId = Ref.modify(ids, (id) => [id + 1, id + 1]);
169
+ const offer = (input) => Queue.offer(inbox, input);
170
+ const handle = (key) => Effect.gen(function* () {
171
+ const existing = (yield* Ref.get(handles)).get(key);
172
+ if (existing !== undefined)
173
+ return existing;
174
+ const created = {
175
+ started: yield* Deferred.make(),
176
+ outcome: yield* Deferred.make(),
177
+ };
178
+ yield* Ref.update(handles, (all) => new Map(all).set(key, created));
179
+ return created;
180
+ });
181
+ const itemHandle = (key) => Effect.map(handle(key), (value) => ({
182
+ key,
183
+ started: Deferred.await(value.started),
184
+ outcome: Deferred.await(value.outcome),
185
+ }));
186
+ /** Registers `deferred` under `id` until it is taken, once, to be resolved. */
187
+ const register = (registry, id, deferred) => Ref.update(registry, (all) => new Map(all).set(id, deferred));
188
+ const claim = (registry, id) => Ref.modify(registry, (all) => {
189
+ const found = all.get(id);
190
+ if (found === undefined)
191
+ return [undefined, all];
192
+ const next = new Map(all);
193
+ next.delete(id);
194
+ return [found, next];
195
+ });
196
+ /**
197
+ * Waits for `deferred`, or ends with `closed` once the playout has stopped
198
+ * without resolving it; what it resolved first still wins.
199
+ */
200
+ const unlessStopped = (deferred, closed) => {
201
+ const settled = Deferred.await(deferred);
202
+ const done = Effect.andThen(stopped, Effect.flatMap(Deferred.isDone(deferred), (done) => done ? settled : closed));
203
+ return Effect.raceFirst(settled, done);
204
+ };
205
+ const record = (report) => Ref.update(cleanup, (value) => {
206
+ const all = [...value.retained, report];
207
+ const settled = all.filter((entry) => !mayStillBill(entry)).slice(-retainedReports);
208
+ return {
209
+ sessions: value.sessions + 1,
210
+ retained: all.filter((entry) => mayStillBill(entry) || settled.includes(entry)),
211
+ };
212
+ });
213
+ /** Closes `source` and records its report. A close that dies leaves none: it is reported. */
214
+ const closeRecorded = (source) => Effect.flatMap(Effect.exit(source.close), (closed) => Exit.isSuccess(closed) ? record(closed.value) : reportDefects(closed.cause));
215
+ const closeSource = (sessionId) => Effect.gen(function* () {
216
+ const entry = (yield* Ref.get(sources)).get(sessionId);
217
+ if (entry === undefined)
218
+ return;
219
+ yield* Ref.update(sources, (all) => {
220
+ const next = new Map(all);
221
+ next.delete(sessionId);
222
+ return next;
223
+ });
224
+ yield* closeRecorded(entry.source);
225
+ yield* closeScope(entry.scope, Exit.void);
226
+ });
227
+ /** What a command for a session already gone gets: it was never sent. */
228
+ const gone = (command) => ({
229
+ _tag: "Failed",
230
+ cause: CommandFailure.from(ReactorError.fromCode("InvalidState", "the session is gone"), {
231
+ operation: command._tag,
232
+ outcome: "not-submitted",
233
+ }),
234
+ });
235
+ const run = (action) => Effect.gen(function* () {
236
+ const entry = (yield* Ref.get(sources)).get(action.sessionId);
237
+ if (entry === undefined)
238
+ return gone(action.command);
239
+ const source = entry.source;
240
+ const command = action.command;
241
+ // A method that throws when called, rather than returning an effect, dies here as its
242
+ // effect would have: its lane carries on.
243
+ const result = Effect.suspend(() => {
244
+ switch (command._tag) {
245
+ case "Enqueue":
246
+ return source.enqueue(command.request, command.tag, command.continueFrom);
247
+ case "Remove":
248
+ return source.remove(command.clipId);
249
+ case "Move":
250
+ return source.move(command.clipId, command.position);
251
+ case "Autoplay":
252
+ return source.setAutoplay(command.enabled);
253
+ case "Stop":
254
+ return source.stop(command.clipId);
255
+ case "Play":
256
+ return source.play(command.clipId);
257
+ }
258
+ });
259
+ const exit = yield* Effect.exit(result);
260
+ if (Exit.isSuccess(exit))
261
+ return {
262
+ _tag: "Done",
263
+ clipId: Predicate.isString(exit.value) ? exit.value : undefined,
264
+ };
265
+ const error = Exit.findErrorOption(exit);
266
+ if (Option.isSome(error)) {
267
+ yield* reportDefects(exit.cause);
268
+ return { _tag: "Failed", cause: error.value };
269
+ }
270
+ // Whether the command went out can't be told: the plan treats it as unknown.
271
+ yield* ErrorReporter.report(exit.cause);
272
+ return { _tag: "Died" };
273
+ });
274
+ const open = Effect.gen(function* () {
275
+ const child = yield* Scope.fork(scope);
276
+ const opened = yield* options.open.pipe(Effect.timeoutOrElse({
277
+ duration: openTimeout,
278
+ orElse: () => Effect.fail(ReactorError.fromCode("Timeout", "opening a session took too long")),
279
+ }), Scope.provide(child), Effect.provide(context), Effect.exit);
280
+ if (Exit.isFailure(opened)) {
281
+ yield* closeScope(child, opened);
282
+ const found = Cause.findError(opened.cause);
283
+ yield* Ref.set(lastOpenError, found);
284
+ if (Result.isFailure(found))
285
+ yield* ErrorReporter.report(opened.cause);
286
+ else
287
+ yield* reportDefects(opened.cause);
288
+ const error = Result.getOrUndefined(found);
289
+ // A failed acquisition still reports what it allocated, and that may still bill. Any other
290
+ // failure, a timeout or a defect among them, may have allocated unseen.
291
+ const allocated = !AcquisitionFailure.is(error) || error.cleanup.allocation !== "none";
292
+ if (AcquisitionFailure.is(error) && allocated)
293
+ yield* record(error.cleanup);
294
+ const retryAfter = error?.retryAfter;
295
+ return yield* offer({
296
+ _tag: "OpenFailed",
297
+ reason: error?.message ?? "opening a session died",
298
+ fatal: false,
299
+ allocated,
300
+ ...(retryAfter === undefined ? {} : { retryAfterMs: Duration.toMillis(retryAfter) }),
301
+ });
302
+ }
303
+ const source = opened.value;
304
+ if ((yield* Ref.get(sources)).has(source.sessionId)) {
305
+ // The plan knows a session by its id: a second live source under one would be taken for
306
+ // the first. It is closed unused, and the playout fails, since opening again gives the same.
307
+ yield* closeRecorded(source);
308
+ yield* closeScope(child, Exit.void);
309
+ const duplicate = ReactorError.fromCode("InvalidState", "an opened source's session id is already in use");
310
+ yield* Ref.set(lastOpenError, Result.succeed(duplicate));
311
+ return yield* offer({
312
+ _tag: "OpenFailed",
313
+ reason: duplicate.message,
314
+ fatal: true,
315
+ allocated: true,
316
+ });
317
+ }
318
+ yield* Ref.set(lastOpenError, undefined);
319
+ // The session's commands, one at a time and in order. Its worker lives in the session's
320
+ // scope, so the lane ends with the session.
321
+ const lane = yield* Queue.unbounded();
322
+ yield* Effect.forever(Effect.flatMap(take(lane), (action) => Effect.flatMap(run(action), (result) => offer({ _tag: "Result", id: action.id, result })))).pipe(Effect.forkIn(child));
323
+ yield* Ref.update(sources, (all) => new Map(all).set(source.sessionId, { source, scope: child, lane }));
324
+ const lifetimeMs = Duration.toMillis(source.lifetime);
325
+ yield* offer({
326
+ _tag: "Opened",
327
+ sessionId: source.sessionId,
328
+ lifetimeMs: Number.isFinite(lifetimeMs) ? lifetimeMs : Infinity,
329
+ });
330
+ yield* source.events.pipe(Stream.runForEach((event) => offer({ _tag: "Source", sessionId: source.sessionId, event })), Effect.exit, Effect.flatMap((exit) => Effect.gen(function* () {
331
+ const found = Exit.isSuccess(exit) ? undefined : Cause.findError(exit.cause);
332
+ yield* Ref.set(lastLostError, found);
333
+ if (Exit.isFailure(exit) && found !== undefined) {
334
+ if (Result.isFailure(found))
335
+ yield* ErrorReporter.report(exit.cause);
336
+ else
337
+ yield* reportDefects(exit.cause);
338
+ }
339
+ const error = found === undefined ? undefined : Result.getOrUndefined(found);
340
+ yield* offer({
341
+ _tag: "Lost",
342
+ sessionId: source.sessionId,
343
+ reason: found === undefined
344
+ ? "the session ended"
345
+ : (error?.message ?? "the session's events died"),
346
+ });
347
+ })), Effect.forkIn(child));
348
+ });
349
+ /**
350
+ * Why the plan failed the playout: the error behind a failed open or a loss,
351
+ * or the defect when there was no error.
352
+ */
353
+ const failureOf = Effect.fnUntraced(function* (action) {
354
+ switch (action.cause) {
355
+ case "filler":
356
+ return Result.succeed(InvalidFiller.make({ index: action.index, message: action.reason }));
357
+ case "moderation":
358
+ return Result.succeed(ReactorError.fromCode("Moderated", action.reason));
359
+ case "open":
360
+ return ((yield* Ref.get(lastOpenError)) ??
361
+ Result.succeed(ReactorError.fromCode("InvalidState", action.reason)));
362
+ case "lost":
363
+ return ((yield* Ref.get(lastLostError)) ??
364
+ Result.succeed(ReactorError.fromCode("InvalidState", action.reason)));
365
+ }
366
+ });
367
+ const act = (action) => Effect.gen(function* () {
368
+ switch (action._tag) {
369
+ case "Command": {
370
+ const entry = (yield* Ref.get(sources)).get(action.sessionId);
371
+ if (entry !== undefined)
372
+ return yield* Queue.offer(entry.lane, action);
373
+ return yield* offer({ _tag: "Result", id: action.id, result: gone(action.command) });
374
+ }
375
+ case "Open":
376
+ return yield* Effect.forkIn(open, scope);
377
+ case "Close":
378
+ return yield* Effect.forkIn(closeSource(action.sessionId), scope);
379
+ case "OnAir": {
380
+ const entry = (yield* Ref.get(sources)).get(action.sessionId);
381
+ return yield* SubscriptionRef.set(onAir, entry?.source);
382
+ }
383
+ case "Emit": {
384
+ // Published before any handle resolves, so a subscriber has the event queued by the
385
+ // time a caller waiting on the handle carries on.
386
+ yield* PubSub.publish(events, action.event);
387
+ if (action.event._tag === "AsRun") {
388
+ const { key, status } = action.event.event;
389
+ const value = yield* handle(key);
390
+ const decided = Policy.decides(status);
391
+ if (decided.started !== undefined)
392
+ yield* Deferred.succeed(value.started, decided.started);
393
+ if (decided.outcome !== undefined)
394
+ yield* Deferred.succeed(value.outcome, decided.outcome);
395
+ }
396
+ return;
397
+ }
398
+ case "Accepted":
399
+ case "Refused": {
400
+ const reply = yield* claim(replies, action.id);
401
+ const answer = action._tag === "Accepted"
402
+ ? { _tag: "Accepted", results: action.results }
403
+ : { _tag: "Refused", refusal: action.refusal };
404
+ if (reply !== undefined)
405
+ yield* Deferred.succeed(reply, answer);
406
+ // A batch refused, at admission or when the playout closes, never commits.
407
+ const commit = action._tag === "Refused" ? yield* claim(commits, action.id) : undefined;
408
+ if (commit !== undefined)
409
+ yield* Deferred.fail(commit, PlayoutClosed.make({}));
410
+ return;
411
+ }
412
+ case "Committed": {
413
+ const commit = yield* claim(commits, action.id);
414
+ if (commit !== undefined)
415
+ yield* Deferred.succeed(commit, undefined);
416
+ return;
417
+ }
418
+ case "Withdrawn": {
419
+ const waiting = yield* claim(withdrawals, `${action.id}:${action.index}`);
420
+ if (waiting !== undefined)
421
+ yield* Deferred.succeed(waiting, action.outcome);
422
+ return;
423
+ }
424
+ case "Drained": {
425
+ const drain = yield* claim(drains, action.id);
426
+ if (drain !== undefined)
427
+ yield* Deferred.succeed(drain, undefined);
428
+ return;
429
+ }
430
+ case "Forget":
431
+ return yield* Ref.update(handles, (all) => {
432
+ const next = new Map(all);
433
+ for (const key of action.keys)
434
+ next.delete(key);
435
+ return next;
436
+ });
437
+ case "Fail": {
438
+ const why = yield* failureOf(action);
439
+ yield* Result.isSuccess(why)
440
+ ? Deferred.succeed(failure, why.success)
441
+ : Deferred.failCause(failure, why.failure);
442
+ // A playout that failed for good closes its sessions at once: an owned one would bill off air.
443
+ yield* Effect.forEach([...(yield* Ref.get(sources)).keys()], closeSource, {
444
+ discard: true,
445
+ }).pipe(Effect.forkIn(scope));
446
+ return yield* offer({ _tag: "Close" });
447
+ }
448
+ }
449
+ });
450
+ const apply = (input) => Effect.gen(function* () {
451
+ const result = Policy.step(config, yield* Ref.get(state), input, yield* now);
452
+ yield* Ref.set(state, result.state);
453
+ yield* Effect.forEach(result.actions, act, { discard: true });
454
+ return result.wake;
455
+ });
456
+ // When the scope closes: the loop stops first, then every waiting item settles and each session closes.
457
+ yield* Effect.addFinalizer(() => Effect.gen(function* () {
458
+ yield* apply({ _tag: "Close" });
459
+ yield* Deferred.succeed(failure, ReactorError.fromCode("Closed", "the playout closed"));
460
+ for (const sessionId of (yield* Ref.get(sources)).keys())
461
+ yield* closeSource(sessionId);
462
+ }));
463
+ /**
464
+ * The loop died of a defect, such as a throwing `filler.clip`: the playout
465
+ * dies with it, settles what it can, and closes every session, so nothing
466
+ * waits on a loop that is gone and no owned session bills on. The defect is
467
+ * reported, and its text never becomes a message of the library's.
468
+ */
469
+ const crashed = (cause) => Effect.gen(function* () {
470
+ yield* ErrorReporter.report(cause);
471
+ yield* Deferred.failCause(failure, cause);
472
+ yield* apply({ _tag: "Close" }).pipe(Effect.catchCause(() => Effect.void));
473
+ for (const value of (yield* Ref.get(handles)).values()) {
474
+ yield* Deferred.succeed(value.started, Policy.indeterminate);
475
+ yield* Deferred.succeed(value.outcome, Policy.indeterminate);
476
+ }
477
+ yield* Effect.forEach([...(yield* Ref.get(sources)).keys()], closeSource, { discard: true });
478
+ });
479
+ yield* Effect.gen(function* () {
480
+ let wake = yield* apply({ _tag: "Tick" });
481
+ while (true) {
482
+ const mono = yield* monotonic;
483
+ const input = wake === undefined
484
+ ? Option.some(yield* take(inbox))
485
+ : yield* take(inbox).pipe(Effect.timeoutOption(untilWake(wake - mono)));
486
+ // Nothing falls due before the wake: a wait that ends short of it, on a clock coarser than
487
+ // the wake, waits on.
488
+ if (Option.isNone(input) && wake !== undefined && (yield* monotonic) < wake)
489
+ continue;
490
+ wake = yield* apply(Option.getOrElse(input, () => ({ _tag: "Tick" })));
491
+ }
492
+ }).pipe(Effect.catchCauseIf((cause) => !Cause.hasInterruptsOnly(cause), crashed), Effect.forkIn(scope));
493
+ // ---------------------------------------------------------------------------
494
+ // Caller operations
495
+ // ---------------------------------------------------------------------------
496
+ const refusal = (refused) => {
497
+ switch (refused._tag) {
498
+ case "KeyMismatch":
499
+ return KeyMismatch.make({ key: refused.key });
500
+ case "WouldMissDeadline":
501
+ return WouldMissDeadline.make({ key: refused.key });
502
+ case "LaneBusy":
503
+ return LaneBusy.make({ key: refused.key, lane: config.lanes[refused.lane]?.name ?? "" });
504
+ case "InvalidItem":
505
+ return InvalidItem.make({ key: refused.key, message: refused.message });
506
+ case "PlayoutClosed":
507
+ return PlayoutClosed.make({});
508
+ }
509
+ };
510
+ const lane = (key, name) => {
511
+ const index = config.lanes.findIndex((value) => value.name === name);
512
+ return index < 0
513
+ ? Effect.fail(InvalidItem.make({ key, message: `no lane is named ${name}` }))
514
+ : Effect.succeed(index);
515
+ };
516
+ const itemKey = (key) => Effect.fromOption(ItemKey.makeOption(key)).pipe(Effect.mapError(() => InvalidItem.make({ key, message: "a key must be a nonempty string" })));
517
+ const spec = (input, laneIndex) => Effect.gen(function* () {
518
+ const key = yield* itemKey(input.key);
519
+ const bad = (message) => InvalidItem.make({ key, message });
520
+ const issues = requestIssues(input.request, { _tag: "Item", key });
521
+ if (issues !== undefined)
522
+ return yield* bad(`the request is outside H3's documented limits: ${issues}`);
523
+ const duration = (value) => value === undefined
524
+ ? Effect.undefined
525
+ : Effect.fromOption(Duration.fromInput(value)).pipe(Effect.mapBoth({
526
+ onFailure: () => bad("a duration is malformed"),
527
+ onSuccess: Duration.toMillis,
528
+ }));
529
+ const start = input.start ?? { _tag: "Follow" };
530
+ const late = start._tag !== "At"
531
+ ? undefined
532
+ : start.late._tag === "skipIfLaterThan"
533
+ ? { skipAfterMs: (yield* duration(start.late.by)) ?? 0 }
534
+ : start.late._tag;
535
+ const cues = yield* Effect.forEach(input.cues ?? [], (cue) => Effect.map(duration(cue.at.offset), (offsetMs) => ({
536
+ name: cue.name,
537
+ from: cue.at.from,
538
+ offsetMs: offsetMs ?? 0,
539
+ })));
540
+ const notBeforeMs = yield* duration(input.window?.notBefore);
541
+ const startByMs = yield* duration(input.window?.startBy);
542
+ const seconds = input.request.seconds ?? requestSeconds.min;
543
+ const window = input.window === undefined
544
+ ? undefined
545
+ : {
546
+ firm: input.window.firm,
547
+ ...(notBeforeMs === undefined ? {} : { notBeforeMs }),
548
+ ...(startByMs === undefined ? {} : { startByMs }),
549
+ };
550
+ const normalized = start._tag === "At"
551
+ ? { _tag: "At", time: start.time, late: late ?? "nextBoundary" }
552
+ : { _tag: start._tag };
553
+ const result = {
554
+ key,
555
+ lane: laneIndex,
556
+ request: input.request,
557
+ seconds,
558
+ fingerprint: fingerprint([
559
+ laneIndex,
560
+ input.request,
561
+ cues,
562
+ input.continuity,
563
+ window,
564
+ normalized,
565
+ ]),
566
+ cues,
567
+ continuity: input.continuity === "previous",
568
+ ...(window === undefined ? {} : { window }),
569
+ start: normalized,
570
+ };
571
+ return result;
572
+ });
573
+ const closed = Effect.fail(PlayoutClosed.make({}));
574
+ /**
575
+ * Sends one edit batch. Its commit and each withdrawal's outcome are
576
+ * registered first, since the policy may settle them in the step that accepts it.
577
+ */
578
+ const submitEdits = (edits, batch) => Effect.gen(function* () {
579
+ const id = yield* nextId;
580
+ const reply = yield* Deferred.make();
581
+ yield* register(replies, id, reply);
582
+ const commit = yield* Deferred.make();
583
+ if (batch)
584
+ yield* register(commits, id, commit);
585
+ const outcomes = new Map();
586
+ for (const [index, edit] of edits.entries())
587
+ if (edit._tag === "Withdraw") {
588
+ const outcome = yield* Deferred.make();
589
+ outcomes.set(index, outcome);
590
+ yield* register(withdrawals, `${id}:${index}`, outcome);
591
+ }
592
+ // A refused or unanswered batch will settle none of what was registered for it.
593
+ const forget = Effect.forEach([...outcomes.keys()], (index) => claim(withdrawals, `${id}:${index}`), { discard: true }).pipe(Effect.andThen(claim(commits, id)));
594
+ yield* offer({ _tag: "Edit", id, edits, batch });
595
+ const answer = yield* unlessStopped(reply, closed).pipe(Effect.ensuring(claim(replies, id)), Effect.onError(() => forget));
596
+ if (answer._tag === "Refused") {
597
+ yield* forget;
598
+ return yield* refusal(answer.refusal);
599
+ }
600
+ return { commit, outcomes, results: answer.results };
601
+ });
602
+ /**
603
+ * What a withdrawal of `key` would have found once the playout stopped: the
604
+ * recorded fate of its item, or of a group's parts.
605
+ */
606
+ const stoppedOutcome = (key) => Effect.map(Ref.get(state), (value) => Policy.fate(value, key));
607
+ const toEdit = (edit) => Effect.gen(function* () {
608
+ switch (edit._tag) {
609
+ case "Submit": {
610
+ const index = yield* lane(edit.item.key, edit.item.lane);
611
+ return { _tag: "Submit", spec: yield* spec(edit.item, index) };
612
+ }
613
+ case "SubmitGroup": {
614
+ const index = yield* lane(edit.group.key, edit.group.lane);
615
+ const parts = yield* Effect.forEach(edit.group.parts, (part, partIndex) => spec({
616
+ ...part,
617
+ ...(partIndex === 0 && edit.group.window !== undefined
618
+ ? { window: edit.group.window }
619
+ : {}),
620
+ }, index));
621
+ return {
622
+ _tag: "SubmitGroup",
623
+ key: yield* itemKey(edit.group.key),
624
+ lane: index,
625
+ parts,
626
+ fingerprint: fingerprint(parts.map((part) => part.fingerprint)),
627
+ };
628
+ }
629
+ case "Insert": {
630
+ const anchor = edit.insert.before ?? edit.insert.after;
631
+ if (anchor === undefined ||
632
+ (edit.insert.before !== undefined && edit.insert.after !== undefined))
633
+ return yield* InvalidItem.make({
634
+ key: edit.insert.key,
635
+ message: "give exactly one of before and after",
636
+ });
637
+ return {
638
+ _tag: "Insert",
639
+ spec: yield* spec(edit.insert, 0),
640
+ anchor: yield* itemKey(anchor),
641
+ side: edit.insert.before === undefined ? "after" : "before",
642
+ };
643
+ }
644
+ case "Replace":
645
+ return {
646
+ _tag: "Replace",
647
+ key: yield* itemKey(edit.key),
648
+ spec: yield* spec(edit.next, 0),
649
+ };
650
+ case "Withdraw":
651
+ return { _tag: "Withdraw", key: yield* itemKey(edit.key) };
652
+ }
653
+ });
654
+ const edit = (input, batch) => Effect.gen(function* () {
655
+ const edits = yield* Effect.forEach(input, toEdit);
656
+ const { commit, outcomes, results } = yield* submitEdits(edits, batch);
657
+ const mapped = yield* Effect.forEach(results, (result, index) => {
658
+ switch (result._tag) {
659
+ case "Added":
660
+ return Effect.map(itemHandle(result.key), (value) => ({
661
+ _tag: "Added",
662
+ handle: value,
663
+ }));
664
+ case "AddedGroup":
665
+ return Effect.map(Effect.forEach(result.parts, itemHandle), (parts) => ({
666
+ _tag: "AddedGroup",
667
+ handle: {
668
+ key: result.key,
669
+ parts: parts,
670
+ },
671
+ }));
672
+ case "Withdrawal": {
673
+ const outcome = outcomes.get(index);
674
+ const key = edits[index]?._tag === "Withdraw" ? edits[index].key : undefined;
675
+ const stopped = key === undefined ? Effect.succeed("not-found") : stoppedOutcome(key);
676
+ return Effect.succeed({
677
+ _tag: "Withdrawal",
678
+ outcome: outcome === undefined ? stopped : unlessStopped(outcome, stopped),
679
+ });
680
+ }
681
+ }
682
+ });
683
+ return { commit, results: mapped };
684
+ });
685
+ const service = {
686
+ submit: Effect.fn("Playout.submit")(function* (item) {
687
+ const { results } = yield* edit([{ _tag: "Submit", item }], false);
688
+ const [first] = results;
689
+ return first?._tag === "Added"
690
+ ? first.handle
691
+ : yield* Effect.die("a submit returned no handle");
692
+ }),
693
+ submitGroup: Effect.fn("Playout.submitGroup")(function* (group) {
694
+ const { results } = yield* edit([{ _tag: "SubmitGroup", group }], false);
695
+ const [first] = results;
696
+ return first?._tag === "AddedGroup"
697
+ ? first.handle
698
+ : yield* Effect.die("a group submit returned no handle");
699
+ }),
700
+ insert: Effect.fn("Playout.insert")(function* (insert) {
701
+ const { results } = yield* edit([{ _tag: "Insert", insert }], false);
702
+ const [first] = results;
703
+ return first?._tag === "Added"
704
+ ? first.handle
705
+ : yield* Effect.die("an insert returned no handle");
706
+ }),
707
+ replace: Effect.fn("Playout.replace")(function* (key, next) {
708
+ const { results } = yield* edit([{ _tag: "Replace", key, next }], false);
709
+ const [first] = results;
710
+ return first?._tag === "Added"
711
+ ? first.handle
712
+ : yield* Effect.die("a replace returned no handle");
713
+ }),
714
+ edit: Effect.fn("Playout.edit")(function* (edits) {
715
+ const { commit, results } = yield* edit(edits, true);
716
+ return { results, committed: unlessStopped(commit, closed) };
717
+ }),
718
+ release: Effect.fn("Playout.release")(function* (key) {
719
+ const id = yield* nextId;
720
+ const reply = yield* Deferred.make();
721
+ yield* register(replies, id, reply);
722
+ yield* offer({ _tag: "Release", id, key });
723
+ const answer = yield* unlessStopped(reply, Effect.fail(InvalidItem.make({ key, message: "the playout has stopped" }))).pipe(Effect.ensuring(claim(replies, id)));
724
+ if (answer._tag === "Refused")
725
+ return yield* InvalidItem.make({
726
+ key,
727
+ message: answer.refusal._tag === "InvalidItem" ? answer.refusal.message : "not released",
728
+ });
729
+ }),
730
+ withdraw: Effect.fn("Playout.withdraw")(function* (key) {
731
+ const none = Effect.succeed({ results: [] });
732
+ const { results } = yield* edit([{ _tag: "Withdraw", key }], false).pipe(
733
+ // A malformed key names nothing; a stopped playout answers from the item's recorded
734
+ // fate. A withdrawal admits nothing, so no other refusal can come back.
735
+ Effect.catchTags({
736
+ InvalidItem: () => none,
737
+ PlayoutClosed: () => none,
738
+ KeyMismatch: Effect.die,
739
+ LaneBusy: Effect.die,
740
+ WouldMissDeadline: Effect.die,
741
+ }));
742
+ const [first] = results;
743
+ if (first?._tag === "Withdrawal")
744
+ return yield* first.outcome;
745
+ return yield* stoppedOutcome(key);
746
+ }),
747
+ drain: Effect.fn("Playout.drain")(function* (drainOptions) {
748
+ if (yield* Deferred.isDone(failure))
749
+ return yield* PlayoutClosed.make({});
750
+ const id = yield* nextId;
751
+ const drained = yield* Deferred.make();
752
+ yield* register(drains, id, drained);
753
+ yield* offer({ _tag: "Drain", id, finish: drainOptions?.finish ?? "playing" });
754
+ yield* unlessStopped(drained, closed).pipe(Effect.ensuring(claim(drains, id)));
755
+ }),
756
+ state: Effect.flatMap(Ref.get(state), (value) => Effect.map(now, (at) => Policy.view(config, value, at))),
757
+ events: Stream.fromPubSub(events),
758
+ asRun: Stream.fromPubSub(events).pipe(Stream.filter((event) => event._tag === "AsRun"), Stream.map((event) => event.event)),
759
+ video: SubscriptionRef.changes(onAir).pipe(Stream.switchMap((source) => source?.video ?? Stream.never), Stream.interruptWhen(stopped)),
760
+ audio: SubscriptionRef.changes(onAir).pipe(Stream.switchMap((source) => source?.audio ?? Stream.never), Stream.interruptWhen(stopped)),
761
+ failure: Deferred.await(failure),
762
+ cleanup: Ref.get(cleanup),
763
+ };
764
+ return service;
765
+ });
766
+ //# sourceMappingURL=runtime.js.map