@hotmeshio/long-tail 0.26.0 → 0.28.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 (392) hide show
  1. package/README.md +9 -2
  2. package/build/api/settings.d.ts +4 -1
  3. package/build/api/settings.js +7 -1
  4. package/build/index.d.ts +4 -0
  5. package/build/index.js +35 -8
  6. package/build/lib/db/config-lock.d.ts +10 -0
  7. package/build/lib/db/config-lock.js +28 -0
  8. package/build/lib/db/schemas/041_machine_lines.sql +26 -0
  9. package/build/lib/events/browser-view.js +8 -2
  10. package/build/lib/events/nats.d.ts +11 -0
  11. package/build/lib/events/nats.js +33 -2
  12. package/build/lib/events/publish.d.ts +33 -0
  13. package/build/lib/events/publish.js +52 -1
  14. package/build/lib/machines/index.d.ts +1 -0
  15. package/build/lib/machines/index.js +1 -0
  16. package/build/lib/machines/line.d.ts +4 -1
  17. package/build/lib/machines/line.js +18 -1
  18. package/build/lib/machines/protocol/codec.d.ts +24 -0
  19. package/build/lib/machines/protocol/codec.js +10 -0
  20. package/build/lib/machines/protocol/constants.d.ts +1 -1
  21. package/build/lib/machines/protocol/constants.js +1 -1
  22. package/build/lib/machines/protocol/contract.js +12 -3
  23. package/build/lib/machines/site/edge-account.d.ts +11 -0
  24. package/build/lib/machines/site/edge-account.js +24 -0
  25. package/build/lib/machines/site/mosquitto-conf.d.ts +5 -4
  26. package/build/lib/machines/site/mosquitto-conf.js +31 -16
  27. package/build/lib/machines/site/site-conf.d.ts +16 -6
  28. package/build/lib/machines/site/site-conf.js +39 -13
  29. package/build/lib/machines/transport/callback-feed.d.ts +1 -0
  30. package/build/lib/machines/transport/callback-feed.js +4 -1
  31. package/build/lib/machines/transport/delivery.d.ts +3 -4
  32. package/build/lib/machines/transport/delivery.js +3 -8
  33. package/build/lib/machines/transport/index.d.ts +2 -0
  34. package/build/lib/machines/transport/index.js +2 -0
  35. package/build/lib/machines/transport/memory.d.ts +2 -0
  36. package/build/lib/machines/transport/memory.js +6 -0
  37. package/build/lib/machines/transport/mqtt-bus.d.ts +2 -0
  38. package/build/lib/machines/transport/mqtt-bus.js +4 -0
  39. package/build/lib/machines/transport/nats-bus.d.ts +8 -13
  40. package/build/lib/machines/transport/nats-bus.js +26 -43
  41. package/build/lib/machines/transport/nats-feed.d.ts +1 -0
  42. package/build/lib/machines/transport/nats-feed.js +6 -3
  43. package/build/lib/machines/transport/pubsub-feed.d.ts +18 -0
  44. package/build/lib/machines/transport/pubsub-feed.js +42 -0
  45. package/build/lib/machines/transport/stream-bus.d.ts +42 -0
  46. package/build/lib/machines/transport/stream-bus.js +61 -0
  47. package/build/lib/machines/transport/streams.d.ts +10 -14
  48. package/build/lib/machines/transport/streams.js +18 -61
  49. package/build/lib/messaging/config.d.ts +25 -0
  50. package/build/lib/messaging/config.js +55 -0
  51. package/build/lib/messaging/constants.d.ts +26 -0
  52. package/build/lib/messaging/constants.js +26 -0
  53. package/build/lib/messaging/index.d.ts +24 -0
  54. package/build/lib/messaging/index.js +65 -0
  55. package/build/lib/messaging/memory.d.ts +16 -0
  56. package/build/lib/messaging/memory.js +147 -0
  57. package/build/lib/messaging/nats/permissions.d.ts +13 -0
  58. package/build/lib/messaging/nats/permissions.js +22 -0
  59. package/build/lib/messaging/nats/provider.d.ts +30 -0
  60. package/build/lib/messaging/nats/provider.js +77 -0
  61. package/build/lib/messaging/nats/render-conf.d.ts +68 -0
  62. package/build/lib/messaging/nats/render-conf.js +58 -0
  63. package/build/lib/messaging/nats/streams.d.ts +26 -0
  64. package/build/lib/messaging/nats/streams.js +97 -0
  65. package/build/lib/messaging/subjects.d.ts +8 -0
  66. package/build/lib/messaging/subjects.js +25 -0
  67. package/build/modules/machines.d.ts +8 -0
  68. package/build/modules/machines.js +16 -0
  69. package/build/routes/index.js +2 -0
  70. package/build/routes/machines.d.ts +2 -0
  71. package/build/routes/machines.js +220 -0
  72. package/build/scripts/bambu-boat.d.ts +17 -0
  73. package/build/scripts/bambu-boat.js +134 -0
  74. package/build/scripts/bambu-print.d.ts +18 -0
  75. package/build/scripts/bambu-print.js +114 -0
  76. package/build/services/machines/commands.d.ts +5 -5
  77. package/build/services/machines/commands.js +3 -2
  78. package/build/services/machines/config.d.ts +8 -1
  79. package/build/services/machines/config.js +17 -7
  80. package/build/services/machines/contracts.d.ts +29 -2
  81. package/build/services/machines/contracts.js +12 -3
  82. package/build/services/machines/gateway/actions.d.ts +2 -1
  83. package/build/services/machines/gateway/admission.d.ts +15 -3
  84. package/build/services/machines/gateway/admission.js +29 -14
  85. package/build/services/machines/gateway/dispatcher.d.ts +19 -3
  86. package/build/services/machines/gateway/dispatcher.js +61 -13
  87. package/build/services/machines/gateway/executor.d.ts +18 -4
  88. package/build/services/machines/gateway/executor.js +99 -34
  89. package/build/services/machines/gateway/gateway.d.ts +22 -1
  90. package/build/services/machines/gateway/gateway.js +83 -28
  91. package/build/services/machines/gateway/index.d.ts +3 -0
  92. package/build/services/machines/gateway/index.js +3 -0
  93. package/build/services/machines/gateway/inspect.d.ts +17 -0
  94. package/build/services/machines/gateway/inspect.js +68 -0
  95. package/build/services/machines/gateway/lifecycle.d.ts +21 -0
  96. package/build/services/machines/gateway/lifecycle.js +89 -0
  97. package/build/services/machines/gateway/log.d.ts +8 -0
  98. package/build/services/machines/gateway/log.js +18 -0
  99. package/build/services/machines/gateway/pacing.d.ts +14 -0
  100. package/build/services/machines/gateway/pacing.js +27 -2
  101. package/build/services/machines/gateway/plan-escalation.js +21 -7
  102. package/build/services/machines/gateway/plan-machine.d.ts +5 -4
  103. package/build/services/machines/gateway/plan-machine.js +70 -19
  104. package/build/services/machines/gateway/project.d.ts +9 -0
  105. package/build/services/machines/gateway/project.js +55 -0
  106. package/build/services/machines/gateway/receipts.d.ts +3 -0
  107. package/build/services/machines/gateway/receipts.js +3 -1
  108. package/build/services/machines/gateway/reconcile.d.ts +2 -0
  109. package/build/services/machines/gateway/reconcile.js +16 -3
  110. package/build/services/machines/gateway/registration.js +1 -1
  111. package/build/services/machines/gateway/reply-waiter.d.ts +6 -3
  112. package/build/services/machines/gateway/reply-waiter.js +37 -16
  113. package/build/services/machines/gateway/state.d.ts +50 -4
  114. package/build/services/machines/gateway/state.js +77 -10
  115. package/build/services/machines/gateway/wire.d.ts +58 -0
  116. package/build/services/machines/gateway/wire.js +171 -0
  117. package/build/services/machines/index.d.ts +3 -0
  118. package/build/services/machines/index.js +2 -0
  119. package/build/services/machines/leadership.d.ts +17 -4
  120. package/build/services/machines/leadership.js +43 -18
  121. package/build/services/machines/line-index.d.ts +16 -0
  122. package/build/services/machines/line-index.js +39 -0
  123. package/build/services/machines/registry-sql.d.ts +31 -0
  124. package/build/services/machines/registry-sql.js +110 -0
  125. package/build/services/machines/registry-sync.d.ts +31 -0
  126. package/build/services/machines/registry-sync.js +81 -0
  127. package/build/services/machines/registry.d.ts +77 -0
  128. package/build/services/machines/registry.js +158 -0
  129. package/build/services/machines/rows.js +26 -2
  130. package/build/services/machines/select.d.ts +9 -2
  131. package/build/services/machines/select.js +20 -7
  132. package/build/services/machines/surface.d.ts +45 -5
  133. package/build/services/machines/surface.js +102 -16
  134. package/build/services/machines/testing/fake-long-tail.d.ts +1 -0
  135. package/build/services/machines/testing/fake-long-tail.js +6 -3
  136. package/build/start/adapters.js +11 -2
  137. package/build/start/apply-report.d.ts +1 -1
  138. package/build/start/apply-report.js +3 -25
  139. package/build/start/index.js +23 -5
  140. package/build/system/index.js +13 -0
  141. package/build/system/mcp-servers/admin/schemas.d.ts +22 -22
  142. package/build/system/mcp-servers/human-queue-schemas.d.ts +7 -7
  143. package/build/system/mcp-servers/machines-schemas.d.ts +35 -0
  144. package/build/system/mcp-servers/machines-schemas.js +35 -0
  145. package/build/system/mcp-servers/machines.d.ts +20 -0
  146. package/build/system/mcp-servers/machines.js +154 -0
  147. package/build/system/seed/tool-manifests-machines.d.ts +2 -0
  148. package/build/system/seed/tool-manifests-machines.js +88 -0
  149. package/build/tsconfig.tsbuildinfo +1 -1
  150. package/build/types/events.d.ts +6 -1
  151. package/build/types/index.d.ts +2 -0
  152. package/build/types/machines-view.d.ts +159 -0
  153. package/build/types/machines-view.js +7 -0
  154. package/build/types/machines.d.ts +6 -1
  155. package/build/types/messaging.d.ts +72 -0
  156. package/build/types/messaging.js +11 -0
  157. package/build/types/startup.d.ts +26 -1
  158. package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js → AdminDashboard-Bm7VG65H.js} +2 -2
  159. package/dashboard/dist/assets/{AdminDashboard-DlItqxFS.js.map → AdminDashboard-Bm7VG65H.js.map} +1 -1
  160. package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js → AgentConfigPage-aJF7Sdbc.js} +6 -6
  161. package/dashboard/dist/assets/{AgentConfigPage-BUmT4a7n.js.map → AgentConfigPage-aJF7Sdbc.js.map} +1 -1
  162. package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js → AgentDetailPage-GwwghhxT.js} +3 -3
  163. package/dashboard/dist/assets/{AgentDetailPage-Cww8rlBi.js.map → AgentDetailPage-GwwghhxT.js.map} +1 -1
  164. package/dashboard/dist/assets/AgentsPage-DVvCzZyg.js +2 -0
  165. package/dashboard/dist/assets/{AgentsPage-C9UuUKhr.js.map → AgentsPage-DVvCzZyg.js.map} +1 -1
  166. package/dashboard/dist/assets/AvailableEscalationsPage-Cxmcji_K.js +2 -0
  167. package/dashboard/dist/assets/{AvailableEscalationsPage-DrvfXz70.js.map → AvailableEscalationsPage-Cxmcji_K.js.map} +1 -1
  168. package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js → BotPicker-CofRxk4L.js} +2 -2
  169. package/dashboard/dist/assets/{BotPicker-CDq9XRMp.js.map → BotPicker-CofRxk4L.js.map} +1 -1
  170. package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js → BulkAssignModal-BARWuz4L.js} +2 -2
  171. package/dashboard/dist/assets/{BulkAssignModal-jsvqtrEA.js.map → BulkAssignModal-BARWuz4L.js.map} +1 -1
  172. package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js → CapabilitiesPage-BJAWVNEx.js} +2 -2
  173. package/dashboard/dist/assets/{CapabilitiesPage-CSCrI6B1.js.map → CapabilitiesPage-BJAWVNEx.js.map} +1 -1
  174. package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js → CollapsibleSection-CtgoaG75.js} +2 -2
  175. package/dashboard/dist/assets/{CollapsibleSection-uD9mn-CQ.js.map → CollapsibleSection-CtgoaG75.js.map} +1 -1
  176. package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js → ConfirmDeleteModal-BYXXBWs6.js} +2 -2
  177. package/dashboard/dist/assets/{ConfirmDeleteModal-BRmx2hA4.js.map → ConfirmDeleteModal-BYXXBWs6.js.map} +1 -1
  178. package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js → ConnectedAppsPage-D0JkzWa7.js} +2 -2
  179. package/dashboard/dist/assets/{ConnectedAppsPage-DlMzE5a-.js.map → ConnectedAppsPage-D0JkzWa7.js.map} +1 -1
  180. package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js → CountdownTimer-BcFxdZYN.js} +2 -2
  181. package/dashboard/dist/assets/{CountdownTimer-sRuM4eM5.js.map → CountdownTimer-BcFxdZYN.js.map} +1 -1
  182. package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js → CredentialsPage-DPSY20rV.js} +2 -2
  183. package/dashboard/dist/assets/{CredentialsPage-bLYydwqa.js.map → CredentialsPage-DPSY20rV.js.map} +1 -1
  184. package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js → CronLabel-Dg_Oew_Y.js} +2 -2
  185. package/dashboard/dist/assets/{CronLabel-D_ATDL2N.js.map → CronLabel-Dg_Oew_Y.js.map} +1 -1
  186. package/dashboard/dist/assets/{DropZone-u1JGfR9G.js → DropZone-Cl_Flb16.js} +2 -2
  187. package/dashboard/dist/assets/{DropZone-u1JGfR9G.js.map → DropZone-Cl_Flb16.js.map} +1 -1
  188. package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js → ElapsedCell-Dm3G5fK2.js} +2 -2
  189. package/dashboard/dist/assets/{ElapsedCell-groSMfqB.js.map → ElapsedCell-Dm3G5fK2.js.map} +1 -1
  190. package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js → EntityTimelinePanel-CrEEP04e.js} +2 -2
  191. package/dashboard/dist/assets/{EntityTimelinePanel-D-F3_A9m.js.map → EntityTimelinePanel-CrEEP04e.js.map} +1 -1
  192. package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js → EscalationListSchemaPage-wOInXcjs.js} +3 -3
  193. package/dashboard/dist/assets/{EscalationListSchemaPage-Bad6Jrmr.js.map → EscalationListSchemaPage-wOInXcjs.js.map} +1 -1
  194. package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js → EscalationSchemaPage-CrIj_g9d.js} +3 -3
  195. package/dashboard/dist/assets/{EscalationSchemaPage-BKi_npI9.js.map → EscalationSchemaPage-CrIj_g9d.js.map} +1 -1
  196. package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js → EscalationTimeline-CeAsl5IT.js} +2 -2
  197. package/dashboard/dist/assets/{EscalationTimeline-DQUUm3b1.js.map → EscalationTimeline-CeAsl5IT.js.map} +1 -1
  198. package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js → EscalationTitleSelect-D8qpCYiy.js} +2 -2
  199. package/dashboard/dist/assets/{EscalationTitleSelect-3mhXh77a.js.map → EscalationTitleSelect-D8qpCYiy.js.map} +1 -1
  200. package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js → EscalationsOverview-CvaqVPsr.js} +2 -2
  201. package/dashboard/dist/assets/{EscalationsOverview-Qaov-uML.js.map → EscalationsOverview-CvaqVPsr.js.map} +1 -1
  202. package/dashboard/dist/assets/{EventTable-V4RF_n58.js → EventTable-Be0JuEl6.js} +2 -2
  203. package/dashboard/dist/assets/{EventTable-V4RF_n58.js.map → EventTable-Be0JuEl6.js.map} +1 -1
  204. package/dashboard/dist/assets/FilterBar-BVyAjIgv.js +2 -0
  205. package/dashboard/dist/assets/FilterBar-BVyAjIgv.js.map +1 -0
  206. package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js → GraphInvokePage-D_QigJeD.js} +2 -2
  207. package/dashboard/dist/assets/{GraphInvokePage-Djslhf96.js.map → GraphInvokePage-D_QigJeD.js.map} +1 -1
  208. package/dashboard/dist/assets/{HomePage-EjcNxlKx.js → HomePage-C1haeuNy.js} +2 -2
  209. package/dashboard/dist/assets/{HomePage-EjcNxlKx.js.map → HomePage-C1haeuNy.js.map} +1 -1
  210. package/dashboard/dist/assets/LinePage-CWD5pv1g.js +5 -0
  211. package/dashboard/dist/assets/LinePage-CWD5pv1g.js.map +1 -0
  212. package/dashboard/dist/assets/LinesPage-NqChsKcO.js +3 -0
  213. package/dashboard/dist/assets/LinesPage-NqChsKcO.js.map +1 -0
  214. package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js → ListToolbar-BZCNrTh6.js} +2 -2
  215. package/dashboard/dist/assets/{ListToolbar-RrEAePOX.js.map → ListToolbar-BZCNrTh6.js.map} +1 -1
  216. package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js → McpOverview-yJTYnh1z.js} +2 -2
  217. package/dashboard/dist/assets/{McpOverview-8gqiL3Vj.js.map → McpOverview-yJTYnh1z.js.map} +1 -1
  218. package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js → McpQueryDetailPage-ChuLpJ4u.js} +3 -3
  219. package/dashboard/dist/assets/{McpQueryDetailPage-COyn6Ak5.js.map → McpQueryDetailPage-ChuLpJ4u.js.map} +1 -1
  220. package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js → McpQueryPage-9S-v9soF.js} +2 -2
  221. package/dashboard/dist/assets/{McpQueryPage-Dj6Qj72w.js.map → McpQueryPage-9S-v9soF.js.map} +1 -1
  222. package/dashboard/dist/assets/McpRunDetailPage-BhrcfxD5.js +2 -0
  223. package/dashboard/dist/assets/{McpRunDetailPage-80fQn9iX.js.map → McpRunDetailPage-BhrcfxD5.js.map} +1 -1
  224. package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js → McpRunsPage-C5_i8_Zx.js} +2 -2
  225. package/dashboard/dist/assets/{McpRunsPage-DaSsI-EM.js.map → McpRunsPage-C5_i8_Zx.js.map} +1 -1
  226. package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js → NamespacePill-OTZD2hzt.js} +2 -2
  227. package/dashboard/dist/assets/{NamespacePill-C5epAgq6.js.map → NamespacePill-OTZD2hzt.js.map} +1 -1
  228. package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js → OperationsPage-C03CeU5P.js} +2 -2
  229. package/dashboard/dist/assets/{OperationsPage-BSu1o2gB.js.map → OperationsPage-C03CeU5P.js.map} +1 -1
  230. package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js → OperatorDashboard-BzC134Jt.js} +2 -2
  231. package/dashboard/dist/assets/{OperatorDashboard-HFI4WGIV.js.map → OperatorDashboard-BzC134Jt.js.map} +1 -1
  232. package/dashboard/dist/assets/{PageHeader-BSWIspNB.js → PageHeader-Hx8APPwE.js} +2 -2
  233. package/dashboard/dist/assets/{PageHeader-BSWIspNB.js.map → PageHeader-Hx8APPwE.js.map} +1 -1
  234. package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js → PageHeaderWithStats-BEQYYBJv.js} +2 -2
  235. package/dashboard/dist/assets/{PageHeaderWithStats-DDjopQ-k.js.map → PageHeaderWithStats-BEQYYBJv.js.map} +1 -1
  236. package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js → PersonaDetailPage-D0mY9L6j.js} +2 -2
  237. package/dashboard/dist/assets/{PersonaDetailPage-D0qlBuGi.js.map → PersonaDetailPage-D0mY9L6j.js.map} +1 -1
  238. package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js → PersonasPage-FFlm5Eug.js} +2 -2
  239. package/dashboard/dist/assets/{PersonasPage-BJClu-5H.js.map → PersonasPage-FFlm5Eug.js.map} +1 -1
  240. package/dashboard/dist/assets/{PortalPage-CucNZn_w.js → PortalPage-Cpc25uO-.js} +2 -2
  241. package/dashboard/dist/assets/{PortalPage-CucNZn_w.js.map → PortalPage-Cpc25uO-.js.map} +1 -1
  242. package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js → ProcessDetailPage-Di2J7KwY.js} +2 -2
  243. package/dashboard/dist/assets/{ProcessDetailPage-B9wMw0RV.js.map → ProcessDetailPage-Di2J7KwY.js.map} +1 -1
  244. package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js → ProcessesListPage-BEXwU3Z0.js} +2 -2
  245. package/dashboard/dist/assets/{ProcessesListPage-B6k4RpmR.js.map → ProcessesListPage-BEXwU3Z0.js.map} +1 -1
  246. package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js → ResolverForm-2ks-3jXC.js} +6 -6
  247. package/dashboard/dist/assets/{ResolverForm-ZVufJ4G-.js.map → ResolverForm-2ks-3jXC.js.map} +1 -1
  248. package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js → RoleDetailPage-DqoOk0xc.js} +3 -3
  249. package/dashboard/dist/assets/{RoleDetailPage-CTbq0mz4.js.map → RoleDetailPage-DqoOk0xc.js.map} +1 -1
  250. package/dashboard/dist/assets/{RolePill-CoETDpjF.js → RolePill-R5_ctGFy.js} +2 -2
  251. package/dashboard/dist/assets/{RolePill-CoETDpjF.js.map → RolePill-R5_ctGFy.js.map} +1 -1
  252. package/dashboard/dist/assets/{RolesPage-DBKxeam4.js → RolesPage-CPmo8Srr.js} +2 -2
  253. package/dashboard/dist/assets/{RolesPage-DBKxeam4.js.map → RolesPage-CPmo8Srr.js.map} +1 -1
  254. package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js → RosterWidget-D2yovCKw.js} +2 -2
  255. package/dashboard/dist/assets/{RosterWidget-BkLAwEYB.js.map → RosterWidget-D2yovCKw.js.map} +1 -1
  256. package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js → RunAsSelector-CMv96On6.js} +2 -2
  257. package/dashboard/dist/assets/{RunAsSelector-D2DC4iDf.js.map → RunAsSelector-CMv96On6.js.map} +1 -1
  258. package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js → ScanCodesPage-CA6cTT-M.js} +2 -2
  259. package/dashboard/dist/assets/{ScanCodesPage-BlKleaT0.js.map → ScanCodesPage-CA6cTT-M.js.map} +1 -1
  260. package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js → ScanSchemeDetailPage-DnctN5-H.js} +2 -2
  261. package/dashboard/dist/assets/{ScanSchemeDetailPage-CTW6gofi.js.map → ScanSchemeDetailPage-DnctN5-H.js.map} +1 -1
  262. package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js → ScanStationPage-Bk8RwkKL.js} +2 -2
  263. package/dashboard/dist/assets/{ScanStationPage-DPRjSPyT.js.map → ScanStationPage-Bk8RwkKL.js.map} +1 -1
  264. package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js → ScopeBadge-BXZ084nD.js} +2 -2
  265. package/dashboard/dist/assets/{ScopeBadge-CGsTtqFr.js.map → ScopeBadge-BXZ084nD.js.map} +1 -1
  266. package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js → StickyPagination-B0FSuUgs.js} +2 -2
  267. package/dashboard/dist/assets/{StickyPagination-CkmX3-Gu.js.map → StickyPagination-B0FSuUgs.js.map} +1 -1
  268. package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js → StreamMessageDetail-BwZEvMpP.js} +2 -2
  269. package/dashboard/dist/assets/{StreamMessageDetail-Xm_n510s.js.map → StreamMessageDetail-BwZEvMpP.js.map} +1 -1
  270. package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js → SwimlaneTimeline-BDVQEaMw.js} +2 -2
  271. package/dashboard/dist/assets/{SwimlaneTimeline-De48aJan.js.map → SwimlaneTimeline-BDVQEaMw.js.map} +1 -1
  272. package/dashboard/dist/assets/{TagInput-S7UuVT_M.js → TagInput-DjPUDp2M.js} +2 -2
  273. package/dashboard/dist/assets/{TagInput-S7UuVT_M.js.map → TagInput-DjPUDp2M.js.map} +1 -1
  274. package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js → TaskDetailPage-BOlv3iGB.js} +2 -2
  275. package/dashboard/dist/assets/{TaskDetailPage-HycMx3O9.js.map → TaskDetailPage-BOlv3iGB.js.map} +1 -1
  276. package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js → TaskQueuePill-D-4Ynf3K.js} +2 -2
  277. package/dashboard/dist/assets/{TaskQueuePill-BlHNpYiZ.js.map → TaskQueuePill-D-4Ynf3K.js.map} +1 -1
  278. package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js → TasksListPage-e2teY0bD.js} +2 -2
  279. package/dashboard/dist/assets/{TasksListPage-OIcFFp1C.js.map → TasksListPage-e2teY0bD.js.map} +1 -1
  280. package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js → TimeAgo-Cvkpf_b3.js} +2 -2
  281. package/dashboard/dist/assets/{TimeAgo-OTC_55oZ.js.map → TimeAgo-Cvkpf_b3.js.map} +1 -1
  282. package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js → TimestampCell-B3btAV0N.js} +2 -2
  283. package/dashboard/dist/assets/{TimestampCell-CAwIj_AI.js.map → TimestampCell-B3btAV0N.js.map} +1 -1
  284. package/dashboard/dist/assets/{ToolPill-D40uLM_v.js → ToolPill-GsKQ80CO.js} +2 -2
  285. package/dashboard/dist/assets/{ToolPill-D40uLM_v.js.map → ToolPill-GsKQ80CO.js.map} +1 -1
  286. package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js → ToolTestPanel-B03nebR7.js} +2 -2
  287. package/dashboard/dist/assets/{ToolTestPanel-8Vf6pfw4.js.map → ToolTestPanel-B03nebR7.js.map} +1 -1
  288. package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js → TopicDetailPage-DBRWne3O.js} +3 -3
  289. package/dashboard/dist/assets/{TopicDetailPage-iZW8rK9L.js.map → TopicDetailPage-DBRWne3O.js.map} +1 -1
  290. package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js → TopicsPage-CVe2M9HD.js} +2 -2
  291. package/dashboard/dist/assets/{TopicsPage-CqiEcj-W.js.map → TopicsPage-CVe2M9HD.js.map} +1 -1
  292. package/dashboard/dist/assets/{UserName-DQFjuoib.js → UserName-B_q_qp6V.js} +2 -2
  293. package/dashboard/dist/assets/{UserName-DQFjuoib.js.map → UserName-B_q_qp6V.js.map} +1 -1
  294. package/dashboard/dist/assets/WorkflowExecutionPage-Bh_dr9tM.js +2 -0
  295. package/dashboard/dist/assets/{WorkflowExecutionPage-Di08wCbs.js.map → WorkflowExecutionPage-Bh_dr9tM.js.map} +1 -1
  296. package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js → WorkflowPill-D7244fKp.js} +2 -2
  297. package/dashboard/dist/assets/{WorkflowPill-DJLcK_CM.js.map → WorkflowPill-D7244fKp.js.map} +1 -1
  298. package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js → WorkflowsDashboard-DA6Mj7qH.js} +2 -2
  299. package/dashboard/dist/assets/{WorkflowsDashboard-Bb8HlrTJ.js.map → WorkflowsDashboard-DA6Mj7qH.js.map} +1 -1
  300. package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js → WorkflowsOverview-B1kBLj-a.js} +2 -2
  301. package/dashboard/dist/assets/{WorkflowsOverview-Dta1kurk.js.map → WorkflowsOverview-B1kBLj-a.js.map} +1 -1
  302. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js → YamlWorkflowDetailPage-6GJM8QIX.js} +8 -8
  303. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CfAajg68.js.map → YamlWorkflowDetailPage-6GJM8QIX.js.map} +1 -1
  304. package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js → YamlWorkflowsPage-Bu811C7f.js} +2 -2
  305. package/dashboard/dist/assets/{YamlWorkflowsPage-CQFUzT4t.js.map → YamlWorkflowsPage-Bu811C7f.js.map} +1 -1
  306. package/dashboard/dist/assets/{agents-PuftRTB2.js → agents-MPk_GnYz.js} +2 -2
  307. package/dashboard/dist/assets/{agents-PuftRTB2.js.map → agents-MPk_GnYz.js.map} +1 -1
  308. package/dashboard/dist/assets/{bots-BmEiPAWY.js → bots-2RihE2Tc.js} +2 -2
  309. package/dashboard/dist/assets/{bots-BmEiPAWY.js.map → bots-2RihE2Tc.js.map} +1 -1
  310. package/dashboard/dist/assets/{capabilities-CRii4Soa.js → capabilities-CC4iwJ1P.js} +2 -2
  311. package/dashboard/dist/assets/{capabilities-CRii4Soa.js.map → capabilities-CC4iwJ1P.js.map} +1 -1
  312. package/dashboard/dist/assets/{controlplane-DO_czaYo.js → controlplane-Bmkic8BH.js} +2 -2
  313. package/dashboard/dist/assets/{controlplane-DO_czaYo.js.map → controlplane-Bmkic8BH.js.map} +1 -1
  314. package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js → escalation-columns-B0lhUUrQ.js} +2 -2
  315. package/dashboard/dist/assets/{escalation-columns-CzCquCPh.js.map → escalation-columns-B0lhUUrQ.js.map} +1 -1
  316. package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js → escalation-items-7WFpPo46.js} +2 -2
  317. package/dashboard/dist/assets/{escalation-items-Cy0ZgJqV.js.map → escalation-items-7WFpPo46.js.map} +1 -1
  318. package/dashboard/dist/assets/index-B9uv-euR.css +1 -0
  319. package/dashboard/dist/assets/{index-DhSCCpqM.js → index-B_XV1rwu.js} +2 -2
  320. package/dashboard/dist/assets/{index-DhSCCpqM.js.map → index-B_XV1rwu.js.map} +1 -1
  321. package/dashboard/dist/assets/{index-Cx8xb-oU.js → index-C2CLfGwL.js} +2 -2
  322. package/dashboard/dist/assets/{index-Cx8xb-oU.js.map → index-C2CLfGwL.js.map} +1 -1
  323. package/dashboard/dist/assets/{index-Cga5IW3D.js → index-C3AeFihz.js} +2 -2
  324. package/dashboard/dist/assets/{index-Cga5IW3D.js.map → index-C3AeFihz.js.map} +1 -1
  325. package/dashboard/dist/assets/{index-DiaRlFYI.js → index-CBri8fYM.js} +2 -2
  326. package/dashboard/dist/assets/{index-DiaRlFYI.js.map → index-CBri8fYM.js.map} +1 -1
  327. package/dashboard/dist/assets/{index-CL_1VpGb.js → index-CRWsB7ZC.js} +2 -2
  328. package/dashboard/dist/assets/{index-CL_1VpGb.js.map → index-CRWsB7ZC.js.map} +1 -1
  329. package/dashboard/dist/assets/{index-XntldBd0.js → index-CTOv3G7a.js} +2 -2
  330. package/dashboard/dist/assets/{index-XntldBd0.js.map → index-CTOv3G7a.js.map} +1 -1
  331. package/dashboard/dist/assets/{index-CfP2nKRc.js → index-CcArGkzI.js} +3 -3
  332. package/dashboard/dist/assets/{index-CfP2nKRc.js.map → index-CcArGkzI.js.map} +1 -1
  333. package/dashboard/dist/assets/{index-Dz6R8-Dw.js → index-CkMHS-hG.js} +25 -25
  334. package/dashboard/dist/assets/index-CkMHS-hG.js.map +1 -0
  335. package/dashboard/dist/assets/index-CmsmwCyv.js +2 -0
  336. package/dashboard/dist/assets/{index-4YaDUcKd.js.map → index-CmsmwCyv.js.map} +1 -1
  337. package/dashboard/dist/assets/{index-2SM2_onB.js → index-CvJsvqIc.js} +2 -2
  338. package/dashboard/dist/assets/{index-2SM2_onB.js.map → index-CvJsvqIc.js.map} +1 -1
  339. package/dashboard/dist/assets/{index-Rwqrflm-.js → index-D-ilRyfy.js} +2 -2
  340. package/dashboard/dist/assets/{index-Rwqrflm-.js.map → index-D-ilRyfy.js.map} +1 -1
  341. package/dashboard/dist/assets/{index-CZ7A3AcD.js → index-DSUtfDXx.js} +2 -2
  342. package/dashboard/dist/assets/{index-CZ7A3AcD.js.map → index-DSUtfDXx.js.map} +1 -1
  343. package/dashboard/dist/assets/{index-jL2K6us4.js → index-Da6ycKyf.js} +2 -2
  344. package/dashboard/dist/assets/{index-jL2K6us4.js.map → index-Da6ycKyf.js.map} +1 -1
  345. package/dashboard/dist/assets/{knowledge-CeUqGPuo.js → knowledge-Bpbg20DC.js} +2 -2
  346. package/dashboard/dist/assets/{knowledge-CeUqGPuo.js.map → knowledge-Bpbg20DC.js.map} +1 -1
  347. package/dashboard/dist/assets/machines-BqOZZU-3.js +2 -0
  348. package/dashboard/dist/assets/machines-BqOZZU-3.js.map +1 -0
  349. package/dashboard/dist/assets/{mcp-Cx96NTeD.js → mcp-CmcUXYce.js} +2 -2
  350. package/dashboard/dist/assets/{mcp-Cx96NTeD.js.map → mcp-CmcUXYce.js.map} +1 -1
  351. package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js → mcp-query-C8buQxN9.js} +2 -2
  352. package/dashboard/dist/assets/{mcp-query-XAzWl0gm.js.map → mcp-query-C8buQxN9.js.map} +1 -1
  353. package/dashboard/dist/assets/{personas--4kjwyOw.js → personas-C2n5oDmY.js} +2 -2
  354. package/dashboard/dist/assets/{personas--4kjwyOw.js.map → personas-C2n5oDmY.js.map} +1 -1
  355. package/dashboard/dist/assets/{pipelines-PgkwvG7f.js → pipelines-RKpSkFz7.js} +2 -2
  356. package/dashboard/dist/assets/{pipelines-PgkwvG7f.js.map → pipelines-RKpSkFz7.js.map} +1 -1
  357. package/dashboard/dist/assets/{tasks-CcYxdBa3.js → tasks-Dab4hExW.js} +2 -2
  358. package/dashboard/dist/assets/{tasks-CcYxdBa3.js.map → tasks-Dab4hExW.js.map} +1 -1
  359. package/dashboard/dist/assets/{topics-_lik7cNY.js → topics-FTMNP7r3.js} +2 -2
  360. package/dashboard/dist/assets/{topics-_lik7cNY.js.map → topics-FTMNP7r3.js.map} +1 -1
  361. package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js → useDebouncedValue-B_1u1YIk.js} +2 -2
  362. package/dashboard/dist/assets/{useDebouncedValue-Bm_AoxVx.js.map → useDebouncedValue-B_1u1YIk.js.map} +1 -1
  363. package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js → useNamespace-HUeAI7Qb.js} +2 -2
  364. package/dashboard/dist/assets/{useNamespace-DgXXKdx5.js.map → useNamespace-HUeAI7Qb.js.map} +1 -1
  365. package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js → useYamlActivityEvents-Cax54qHH.js} +2 -2
  366. package/dashboard/dist/assets/{useYamlActivityEvents-Dj2qtGSd.js.map → useYamlActivityEvents-Cax54qHH.js.map} +1 -1
  367. package/dashboard/dist/assets/{validate-FlXCBBT6.js → validate-DxOaV7QS.js} +2 -2
  368. package/dashboard/dist/assets/{validate-FlXCBBT6.js.map → validate-DxOaV7QS.js.map} +1 -1
  369. package/dashboard/dist/assets/{vendor-icons-DUYcKTjP.js → vendor-icons-fxBvvHBi.js} +187 -182
  370. package/dashboard/dist/assets/vendor-icons-fxBvvHBi.js.map +1 -0
  371. package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js → yaml-workflows-BgY1XHJx.js} +2 -2
  372. package/dashboard/dist/assets/{yaml-workflows-B0_JxRYQ.js.map → yaml-workflows-BgY1XHJx.js.map} +1 -1
  373. package/dashboard/dist/index.html +3 -3
  374. package/docs/architecture.md +1 -0
  375. package/docs/code-owned-configuration.md +6 -0
  376. package/docs/dashboard.md +1 -0
  377. package/docs/events.md +83 -4
  378. package/docs/machines.md +129 -23
  379. package/docs/mcp.md +19 -0
  380. package/package.json +3 -1
  381. package/build/lib/machines/transport/nats-durable.d.ts +0 -11
  382. package/build/lib/machines/transport/nats-durable.js +0 -28
  383. package/dashboard/dist/assets/AgentsPage-C9UuUKhr.js +0 -2
  384. package/dashboard/dist/assets/AvailableEscalationsPage-DrvfXz70.js +0 -2
  385. package/dashboard/dist/assets/FilterBar-BygWrnB1.js +0 -2
  386. package/dashboard/dist/assets/FilterBar-BygWrnB1.js.map +0 -1
  387. package/dashboard/dist/assets/McpRunDetailPage-80fQn9iX.js +0 -2
  388. package/dashboard/dist/assets/WorkflowExecutionPage-Di08wCbs.js +0 -2
  389. package/dashboard/dist/assets/index-4YaDUcKd.js +0 -2
  390. package/dashboard/dist/assets/index-CnU7Jjz3.css +0 -1
  391. package/dashboard/dist/assets/index-Dz6R8-Dw.js.map +0 -1
  392. package/dashboard/dist/assets/vendor-icons-DUYcKTjP.js.map +0 -1
@@ -3,7 +3,8 @@
3
3
  * Runs the planner's actions: escalation verbs through LineEscalations,
4
4
  * dispatches and commands through the Dispatcher, alarm and machine rows,
5
5
  * and the offline debounce. A verb that fails for real throws, so the message that
6
- * caused it is delivered again.
6
+ * caused it is delivered again. What ran comes back as wire actions, for the
7
+ * record of the message that caused it.
7
8
  */
8
9
  Object.defineProperty(exports, "__esModule", { value: true });
9
10
  exports.Executor = void 0;
@@ -15,18 +16,29 @@ const escalations_1 = require("./escalations");
15
16
  const log_1 = require("./log");
16
17
  const dispatcher_1 = require("./dispatcher");
17
18
  const plan_shared_1 = require("./plan-shared");
19
+ const state_1 = require("./state");
20
+ const wire_1 = require("./wire");
18
21
  const NOT_FOUND = 404;
19
22
  const CONFLICT = 409;
23
+ /** A verb's outcome as the wire records it: done, already done, or refused by Long Tail. */
24
+ function outcomeOf(verb, rowId, result) {
25
+ const refused = result.outcome === escalations_1.VERB_OUTCOME.INVALID || result.status === NOT_FOUND || result.status === CONFLICT;
26
+ if (refused)
27
+ return { verb: 'refuse', rowId, detail: `${verb}: ${result.detail ?? result.outcome}` };
28
+ return { verb, rowId, ...(result.outcome === escalations_1.VERB_OUTCOME.ALREADY ? { detail: result.detail ?? 'already ended' } : {}) };
29
+ }
20
30
  class Executor {
21
31
  constructor(d) {
22
32
  this.d = d;
23
33
  this.inflight = new Set();
24
34
  this.quietPending = new Set();
25
35
  this.timers = new Set();
36
+ this.stopped = false;
26
37
  this.dispatcher = new dispatcher_1.Dispatcher(d);
27
38
  }
28
39
  /** Dispatches and commands run detached so one slow reply never holds up the feed. */
29
40
  async apply(actions) {
41
+ const done = [];
30
42
  for (const action of actions) {
31
43
  if (action.kind === 'dispatch')
32
44
  this.track(this.dispatcher.dispatch(action));
@@ -34,75 +46,110 @@ class Executor {
34
46
  this.track(this.dispatcher.command(action));
35
47
  else if (action.kind === 'control')
36
48
  this.track(this.dispatcher.control(action));
37
- else
38
- await this.run(action);
49
+ else {
50
+ done.push(...await this.run(action));
51
+ continue;
52
+ }
53
+ done.push((0, wire_1.plannedAction)(action));
39
54
  }
55
+ return done;
40
56
  }
41
57
  /** Resolves when every detached dispatch has finished. */
42
58
  async idle() {
43
59
  while (this.inflight.size)
44
60
  await Promise.all([...this.inflight]);
45
61
  }
62
+ /** Work still running sends nothing more and raises no row; the next leader takes it up from the message or the row. */
46
63
  stop() {
64
+ this.stopped = true;
47
65
  for (const t of this.timers)
48
66
  clearTimeout(t);
49
67
  this.timers.clear();
68
+ this.dispatcher.stop();
50
69
  this.d.replies.cancelAll();
51
70
  }
71
+ /** A row raised after stop() would be raised again by the next leader, so the message is nak'd instead. */
72
+ live() {
73
+ if (this.stopped)
74
+ throw new dispatcher_1.GatewayStopped();
75
+ }
52
76
  track(work) {
53
- const tracked = work.catch((err) => this.d.log.error(log_1.GATEWAY_LOG.VERB_FAILED, { error: String(err?.message ?? err) }))
77
+ const tracked = work.catch((err) => {
78
+ if (!(err instanceof dispatcher_1.GatewayStopped))
79
+ this.d.log.error(log_1.GATEWAY_LOG.VERB_FAILED, { error: String(err?.message ?? err) });
80
+ })
54
81
  .finally(() => this.inflight.delete(tracked));
55
82
  this.inflight.add(tracked);
56
83
  }
57
84
  async run(a) {
58
85
  const { lt, state, replies } = this.d;
59
86
  switch (a.kind) {
60
- case 'claim':
61
- return this.check(a, await lt.claim(a.as, a.rowId));
87
+ case 'claim': {
88
+ const result = await lt.claim(a.as, a.rowId);
89
+ this.check(a, result);
90
+ return [outcomeOf('claim', a.rowId, result)];
91
+ }
62
92
  case 'accumulate':
63
93
  return this.accumulate(a);
64
- case 'resolve':
65
- this.check(a, await lt.resolve(a.as, a.rowId, a.payload));
94
+ case 'resolve': {
95
+ const result = await lt.resolve(a.as, a.rowId, a.payload);
96
+ this.check(a, result);
66
97
  state.close(a.rowId);
67
- return;
98
+ return [outcomeOf('resolve', a.rowId, result)];
99
+ }
68
100
  case 'createAlarmRow':
69
- return this.createAlarmRow(a);
101
+ return [{ verb: 'create-row', rowId: await this.createAlarmRow(a), detail: `${a.row.type} ${a.alarmId} at ${a.machineId}` }];
70
102
  case 'createRow': {
103
+ this.live();
71
104
  const { id } = await lt.create(actions_1.CONTROLLER, a.row);
72
105
  this.d.log.info(log_1.GATEWAY_LOG.VIOLATION_ROW, { row: id, type: a.row.type });
73
- return;
106
+ return [{ verb: 'create-row', rowId: id, detail: a.row.type }];
74
107
  }
75
108
  case 'watchOffline':
76
- return this.watchOffline(a.machineId);
109
+ this.watchOffline(a.machineId);
110
+ return [(0, wire_1.plannedAction)(a)];
77
111
  case 'settleReply':
78
- if (!replies.settle({ cmdId: a.cmdId, status: a.status, reason: a.reason }))
79
- await this.lateReply(a);
80
- return;
112
+ if (replies.settle({ cmdId: a.cmdId, status: a.status, reason: a.reason, ...(a.code ? { code: a.code } : {}) }))
113
+ return [(0, wire_1.plannedAction)(a)];
114
+ return [{ verb: 'ack', detail: `late ${a.status} ${a.cmdId}` }, ...await this.lateReply(a)];
81
115
  case 'settleSnapshot':
82
116
  replies.settleSnapshot(a.machineId, new Set(a.jobIds));
83
- return;
117
+ return [(0, wire_1.plannedAction)(a)];
84
118
  case 'bindAddress':
85
119
  await this.d.addresses.bind(a.machineId, a.address);
86
120
  state.bindAddress(a.machineId, a.address);
87
121
  this.d.log.info(log_1.GATEWAY_LOG.ADDRESS_BOUND, { machine: a.machineId, address: a.address, ...(a.by ? { approvedBy: a.by } : {}) });
88
- return;
122
+ return [{ verb: 'ack', detail: `bound ${a.machineId} to ${a.address}` }];
89
123
  case 'refuseBinding':
90
124
  this.d.log.warn(log_1.GATEWAY_LOG.ADDRESS_REFUSED, { machine: a.machineId, address: a.address, reason: a.reason });
125
+ return [(0, wire_1.plannedAction)(a)];
91
126
  }
92
127
  }
93
- /** A dispatch's second reply: ready, or a failure to prepare that ends the handoff. */
128
+ /**
129
+ * A dispatch's second reply: ready, or a failure to prepare that ends the
130
+ * handoff. When the handoff into the machine has already ended, as one
131
+ * dispatched on arrival does at acceptance, the failure ends the handoff
132
+ * carrying the units out of it.
133
+ */
94
134
  async lateReply(a) {
95
- const row = this.d.state.rowForDispatch(a.cmdId);
96
- if (!row?.toMachine)
97
- return;
98
- const context = { row: row.id, machine: row.toMachine, cmdId: a.cmdId, reason: a.reason };
99
- if (a.status === protocol_1.REPLY_STATUS.COMPLETED)
100
- return this.d.log.info(log_1.GATEWAY_LOG.DISPATCH_READY, context);
135
+ const { state, log } = this.d;
136
+ const into = state.rowForDispatch(a.cmdId);
137
+ const m = into?.toMachine;
138
+ if (!into || !m)
139
+ return [];
140
+ const context = { row: into.id, machine: m, cmdId: a.cmdId, reason: a.reason };
141
+ if (a.status === protocol_1.REPLY_STATUS.COMPLETED) {
142
+ log.info(log_1.GATEWAY_LOG.DISPATCH_READY, context);
143
+ return [];
144
+ }
101
145
  if (a.status !== protocol_1.REPLY_STATUS.FAILED)
102
- return;
103
- this.d.log.warn(log_1.GATEWAY_LOG.DISPATCH_FAILED, context);
104
- await this.apply((0, plan_shared_1.failHandoff)(this.d.state, row, row.toMachine, {
105
- received: false, errorCode: contracts_1.HANDOFF_ERROR.DISPATCH_FAILED, detail: `${row.toMachine} could not prepare the job: ${a.reason}`,
146
+ return [];
147
+ const row = into.ended ? onwardRow(state, into, m) : into;
148
+ log.warn(log_1.GATEWAY_LOG.DISPATCH_FAILED, { ...context, ...(into.ended ? { onward: row?.id ?? null } : {}) });
149
+ if (!row)
150
+ return [];
151
+ return this.apply((0, plan_shared_1.failHandoff)(state, row, m, {
152
+ received: false, errorCode: contracts_1.HANDOFF_ERROR.DISPATCH_FAILED, detail: `${m} could not prepare the job: ${a.reason}`, ...(a.code ? { code: a.code } : {}),
106
153
  }));
107
154
  }
108
155
  /** Add the item; when the row then holds every key the action waits for, resolve it. */
@@ -110,15 +157,18 @@ class Executor {
110
157
  const { lt, state } = this.d;
111
158
  const result = await lt.accumulate(a.as, a.rowId, a.itemKey, a.payload, a.metadata);
112
159
  this.check(a, result);
160
+ const added = { ...outcomeOf('accumulate', a.rowId, result), itemKey: a.itemKey };
113
161
  if (!a.complete || result.outcome === escalations_1.VERB_OUTCOME.INVALID)
114
- return;
162
+ return [added];
115
163
  const held = new Set(result.itemKeys ?? await lt.itemKeys(a.rowId));
116
164
  if (!a.complete.keys.every((k) => held.has(k)))
117
- return;
165
+ return [added];
118
166
  if (a.complete.then)
119
- return this.apply(a.complete.then);
120
- this.check(a, await lt.resolve(a.as, a.rowId, a.complete.payload ?? {}));
167
+ return [added, ...await this.apply(a.complete.then)];
168
+ const resolved = await lt.resolve(a.as, a.rowId, a.complete.payload ?? {});
169
+ this.check(a, resolved);
121
170
  state.close(a.rowId);
171
+ return [added, outcomeOf('resolve', a.rowId, resolved)];
122
172
  }
123
173
  check(a, result) {
124
174
  const rowId = a.rowId;
@@ -133,17 +183,19 @@ class Executor {
133
183
  }
134
184
  }
135
185
  async createAlarmRow(a) {
186
+ this.live();
136
187
  const { id } = await this.d.lt.create(actions_1.CONTROLLER, { ...a.row, role: (0, line_1.operatorRole)(this.d.line) });
137
188
  this.d.log.info(log_1.GATEWAY_LOG.ALARM_ROW, { row: id, machine: a.machineId, alarm: a.alarmId });
138
189
  const track = this.d.state.alarms.get(this.d.state.alarmKey(a.machineId, a.alarmId));
139
190
  const raisedAt = a.row.metadata?.raisedAt;
140
191
  if (track && (!track.raisedAt || !raisedAt || track.raisedAt === raisedAt)) {
141
192
  track.rowId = id;
142
- return;
193
+ return id;
143
194
  }
144
195
  // Cleared at the machine, or raised again, while the row was being created.
145
196
  const note = track ? `${a.machineId} raised ${a.alarmId} again; this one ended` : `cleared at ${a.machineId}`;
146
197
  await this.d.lt.resolve(actions_1.CONTROLLER, id, { decision: contracts_1.DECISION.CLEARED, note });
198
+ return id;
147
199
  }
148
200
  /** Raise a quiet row for each connected machine silent longer than `quietMs`. */
149
201
  checkQuiet(machineIds, quietMs) {
@@ -157,6 +209,7 @@ class Executor {
157
209
  }
158
210
  }
159
211
  async raiseQuiet(machineId, silentMs) {
212
+ this.live();
160
213
  const { id } = await this.d.lt.create(actions_1.CONTROLLER, {
161
214
  type: contracts_1.ROW_TYPE.MACHINE_QUIET, role: (0, line_1.operatorRole)(this.d.line), priority: 2,
162
215
  description: `${machineId} is connected but has sent nothing for ${Math.round(silentMs / 1000)} s`,
@@ -179,11 +232,12 @@ class Executor {
179
232
  link.watching = false;
180
233
  if (link.online || link.rowId)
181
234
  return;
235
+ this.live();
182
236
  const since = new Date(link.since).toISOString();
183
237
  const { id } = await this.d.lt.create(actions_1.CONTROLLER, {
184
238
  type: contracts_1.ROW_TYPE.MACHINE_OFFLINE, role: (0, line_1.operatorRole)(this.d.line), priority: 2,
185
239
  description: `${machineId} has been offline since ${since}`,
186
- metadata: { siteId: this.d.line.siteId, lineId: this.d.line.lineId, machineId, offlineSince: since },
240
+ metadata: { siteId: this.d.line.siteId, lineId: this.d.line.lineId, machineId, offlineSince: since, ...(link.reason ? { reason: link.reason } : {}) },
187
241
  });
188
242
  this.d.log.info(log_1.GATEWAY_LOG.OFFLINE_ROW, { row: id, machine: machineId });
189
243
  if (!link.online)
@@ -193,3 +247,14 @@ class Executor {
193
247
  }
194
248
  }
195
249
  exports.Executor = Executor;
250
+ /** The open handoff out of `m` for units a closed handoff brought into it. */
251
+ function onwardRow(state, into, m) {
252
+ if (into.ended !== state_1.ROW_END.RESOLVED || into.dispatch !== state_1.DISPATCH_STATE.ACCEPTED)
253
+ return undefined;
254
+ for (const u of into.units) {
255
+ const row = state.openFor(u.unitId, (r) => r.fromMachine === m);
256
+ if (row)
257
+ return row;
258
+ }
259
+ return undefined;
260
+ }
@@ -3,15 +3,18 @@
3
3
  * reads escalation events (a new handoff row means "dispatch"), reads every
4
4
  * machine message on the line (a receipt means "resolve"), and performs the
5
5
  * verbs a person would, as the machine. Neither side knows about the other.
6
+ * Every message read or sent is recorded on the wire (wire.ts).
6
7
  */
7
8
  import { type HandoffRowAdapter } from '../rows';
8
9
  import { type AddressBook } from './address-book';
9
10
  import type { LineDef } from '../../../lib/machines/line';
10
11
  import { type LineCodec } from '../../../lib/machines/protocol';
11
- import { type EscalationFeed, type MachineBus } from '../../../lib/machines/transport';
12
+ import { type EscalationFeed, type InboundMessage, type MachineBus } from '../../../lib/machines/transport';
13
+ import type { InspectResult } from '../../../types/machines-view';
12
14
  import type { LineEscalations } from './escalations';
13
15
  import { type GatewayLog } from './log';
14
16
  import { GatewayState } from './state';
17
+ import { type WireSink } from './wire';
15
18
  export interface GatewaySettings {
16
19
  topicRoot: string;
17
20
  replyTimeoutMs: number;
@@ -23,6 +26,12 @@ export interface GatewaySettings {
23
26
  quietMs: number;
24
27
  /** How long confirmed message ids gather before a receipt goes out (codecs with receipts). */
25
28
  receiptDelayMs?: number;
29
+ /** Note each job's start, progress steps and pauses on the row that holds it; off unless set. */
30
+ lifecycle?: boolean;
31
+ /** With lifecycle notes, progress is noted each time it crosses this many percent; 0 notes none. */
32
+ progressStep?: number;
33
+ /** Record telemetry messages on the wire too; off unless set. */
34
+ wireTelemetry?: boolean;
26
35
  }
27
36
  export interface GatewayDeps {
28
37
  bus: MachineBus;
@@ -37,6 +46,8 @@ export interface GatewayDeps {
37
46
  codec?: LineCodec;
38
47
  /** Where a line that learns addresses keeps them; in memory by default. */
39
48
  addresses?: AddressBook;
49
+ /** Where wire records go; Long Tail's events by default. */
50
+ wire?: WireSink;
40
51
  }
41
52
  export declare class MachineGateway {
42
53
  private readonly deps;
@@ -48,12 +59,22 @@ export declare class MachineGateway {
48
59
  private readonly log;
49
60
  private readonly addresses;
50
61
  private readonly admission;
62
+ private readonly wire;
51
63
  private quietTimer?;
52
64
  constructor(deps: GatewayDeps);
53
65
  start(): Promise<void>;
66
+ /**
67
+ * Hand the line over cleanly: nothing new is raised or sent, a message
68
+ * still being handled is nak'd for the next leader if it would make a row,
69
+ * receipts for what was applied go out, then the sessions close.
70
+ */
54
71
  stop(): Promise<void>;
72
+ /** Machines that report only changes are asked for their full state once the gateway listens. */
73
+ private askEveryMachine;
55
74
  /** Resolves when no dispatch is in flight (tests). */
56
75
  idle(): Promise<void>;
76
+ /** A dry run of one message on a copy of the state: nothing is applied (inspect.ts). */
77
+ inspect(msg: Pick<InboundMessage, 'topic' | 'payload' | 'retained'>): InspectResult;
57
78
  /**
58
79
  * On taking the line: open handoff and command rows (a dispatch or command
59
80
  * interrupted by a restart is sent again with the same cmdId), the gateway's
@@ -4,6 +4,7 @@
4
4
  * reads escalation events (a new handoff row means "dispatch"), reads every
5
5
  * machine message on the line (a receipt means "resolve"), and performs the
6
6
  * verbs a person would, as the machine. Neither side knows about the other.
7
+ * Every message read or sent is recorded on the wire (wire.ts).
7
8
  */
8
9
  Object.defineProperty(exports, "__esModule", { value: true });
9
10
  exports.MachineGateway = void 0;
@@ -15,14 +16,18 @@ const address_book_1 = require("./address-book");
15
16
  const admission_1 = require("./admission");
16
17
  const protocol_1 = require("../../../lib/machines/protocol");
17
18
  const transport_1 = require("../../../lib/machines/transport");
19
+ const publish_1 = require("../../../lib/events/publish");
18
20
  const reply_waiter_1 = require("./reply-waiter");
19
21
  const executor_1 = require("./executor");
22
+ const dispatcher_1 = require("./dispatcher");
23
+ const inspect_1 = require("./inspect");
20
24
  const log_1 = require("./log");
21
25
  const plan_escalation_1 = require("./plan-escalation");
22
26
  const pacing_1 = require("./pacing");
23
27
  const plan_machine_1 = require("./plan-machine");
24
28
  const state_1 = require("./state");
25
29
  const receipts_1 = require("./receipts");
30
+ const wire_1 = require("./wire");
26
31
  class MachineGateway {
27
32
  constructor(deps) {
28
33
  this.deps = deps;
@@ -32,22 +37,30 @@ class MachineGateway {
32
37
  this.codec = deps.codec ?? (0, protocol_1.genericCodec)({ root: deps.settings.topicRoot, line: deps.line });
33
38
  this.state.unitsPerDispatch = this.codec.unitsPerDispatch;
34
39
  this.state.dispatchOnArrival = this.codec.dispatchOn === protocol_1.DISPATCH_ON.ARRIVAL;
40
+ this.state.rowOps = (0, protocol_1.declaredRowOps)(this.codec);
41
+ this.state.lifecycle = deps.settings.lifecycle === true;
42
+ this.state.retainedAlarms = this.codec.retainedAlarms === true;
43
+ this.state.progressStep = deps.settings.progressStep ?? this.state.progressStep;
35
44
  this.addresses = deps.addresses ?? new address_book_1.MemoryAddressBook();
45
+ this.wire = new wire_1.WireRecorder(deps.line, deps.wire ?? publish_1.publishMachineWireEvent, { telemetry: deps.settings.wireTelemetry === true });
36
46
  this.executor = new executor_1.Executor({
37
- addresses: this.addresses,
47
+ addresses: this.addresses, wire: this.wire,
38
48
  bus: deps.bus, lt: deps.lt, replies: new reply_waiter_1.ReplyWaiter(), state: this.state, line: deps.line,
39
49
  codec: this.codec, replyTimeoutMs: deps.settings.replyTimeoutMs,
40
50
  dispatchAttempts: deps.settings.dispatchAttempts, offlineDebounceMs: deps.settings.offlineDebounceMs, log: this.log,
41
51
  });
42
52
  this.admission = { state: this.state, line: deps.line, executor: this.executor, log: this.log, pace: () => this.pace() };
43
- this.receipts = new receipts_1.ReceiptBatcher({ bus: deps.bus, codec: this.codec, delayMs: deps.settings.receiptDelayMs ?? DEFAULT_RECEIPT_DELAY_MS, log: this.log });
53
+ this.receipts = new receipts_1.ReceiptBatcher({ bus: deps.bus, codec: this.codec, delayMs: deps.settings.receiptDelayMs ?? DEFAULT_RECEIPT_DELAY_MS, log: this.log, wire: this.wire });
44
54
  }
45
55
  async start() {
46
56
  await this.deps.bus.connect();
47
57
  await this.deps.feed.connect();
58
+ this.state.takenAt = Date.now();
48
59
  await this.reconcile();
49
60
  await this.deps.feed.consume((event) => this.onEscalation(event));
50
61
  await this.deps.bus.consume((msg) => this.onMachine(msg));
62
+ if (this.codec.snapshotOnStart)
63
+ await this.askEveryMachine();
51
64
  const { quietMs } = this.deps.settings;
52
65
  if (quietMs > 0) {
53
66
  const machines = this.deps.line.machines.map((m) => m.machineId);
@@ -55,18 +68,37 @@ class MachineGateway {
55
68
  }
56
69
  this.log.info(log_1.GATEWAY_LOG.STARTED, { site: this.deps.line.siteId, line: this.deps.line.lineId });
57
70
  }
71
+ /**
72
+ * Hand the line over cleanly: nothing new is raised or sent, a message
73
+ * still being handled is nak'd for the next leader if it would make a row,
74
+ * receipts for what was applied go out, then the sessions close.
75
+ */
58
76
  async stop() {
59
77
  if (this.quietTimer)
60
78
  clearInterval(this.quietTimer);
61
79
  this.executor.stop();
80
+ await this.deps.feed.unsubscribe();
81
+ await this.deps.bus.unsubscribe();
82
+ await this.executor.idle();
62
83
  await this.receipts.flush();
63
84
  await this.deps.feed.close();
64
85
  await this.deps.bus.close();
65
86
  }
87
+ /** Machines that report only changes are asked for their full state once the gateway listens. */
88
+ async askEveryMachine() {
89
+ const at = Date.now();
90
+ await this.executor.apply(this.deps.line.machines.map((m) => ({
91
+ kind: 'command', machineId: m.machineId, op: protocol_1.OP.SNAPSHOT, cmdId: `${m.machineId}:takeover:${at}`, args: {},
92
+ })));
93
+ }
66
94
  /** Resolves when no dispatch is in flight (tests). */
67
95
  idle() {
68
96
  return this.executor.idle();
69
97
  }
98
+ /** A dry run of one message on a copy of the state: nothing is applied (inspect.ts). */
99
+ inspect(msg) {
100
+ return (0, inspect_1.dryRun)({ state: this.state, line: this.deps.line, codec: this.codec, dispatchTtlMs: this.deps.settings.dispatchTtlMs }, { ...msg, deliveries: 1 });
101
+ }
70
102
  /**
71
103
  * On taking the line: open handoff and command rows (a dispatch or command
72
104
  * interrupted by a restart is sent again with the same cmdId), the gateway's
@@ -80,6 +112,7 @@ class MachineGateway {
80
112
  const addresses = await (0, reconcile_1.restoreAddresses)(this.state, this.addresses, this.deps.line);
81
113
  const handoffs = await this.reconcileHandoffs();
82
114
  await this.executor.apply(await (0, reconcile_1.arrivalsOnRows)(this.state, this.deps.lt, this.deps.settings.dispatchTtlMs));
115
+ await (0, reconcile_1.notesOnRows)(this.state, this.deps.lt);
83
116
  const commands = await this.reconcileCommands();
84
117
  const restored = await (0, reconcile_1.restoreLineRows)(this.state, this.deps.lt, this.deps.line);
85
118
  await this.resync();
@@ -121,18 +154,31 @@ class MachineGateway {
121
154
  async resync() {
122
155
  const { line } = this.deps;
123
156
  const active = new Set();
124
- for (const msg of await this.deps.bus.retained((0, protocol_1.lineFilter)(this.codec.root, line.siteId, line.lineId))) {
125
- for (const raw of this.decode(msg.topic, msg.payload, true)) {
126
- if (!raw.parsed)
127
- continue;
128
- const seen = await (0, admission_1.admitSender)(this.admission, msg.topic, raw);
129
- if (!('parsed' in seen) || !seen.parsed)
130
- continue;
131
- if (seen.parsed.kind === protocol_1.MESSAGE_KIND.ALARM && seen.body?.body?.active)
132
- active.add(this.state.alarmKey(seen.parsed.ident.machineId, seen.parsed.key));
133
- await this.applyMachine(msg.topic, seen.parsed, seen.body);
157
+ this.state.readingRetained = true;
158
+ try {
159
+ for (const read of await this.deps.bus.retained((0, protocol_1.lineFilter)(this.codec.root, line.siteId, line.lineId))) {
160
+ const msg = { ...read, retained: true };
161
+ for (const raw of this.decode(msg)) {
162
+ if (!raw.parsed)
163
+ continue;
164
+ const admitted = await (0, admission_1.admitSender)(this.admission, msg.topic, raw);
165
+ if (!('seen' in admitted)) {
166
+ this.wire.inbound(msg, raw, admitted, 1, admitted.sender);
167
+ continue;
168
+ }
169
+ const { seen } = admitted;
170
+ if (seen.parsed.kind === protocol_1.MESSAGE_KIND.ALARM && seen.body?.body?.active)
171
+ active.add(this.state.alarmKey(seen.parsed.ident.machineId, seen.parsed.key));
172
+ const applied = await this.applyMachine(msg.topic, seen.parsed, seen.body);
173
+ this.wire.inbound(msg, seen, { ...applied, actions: [...admitted.actions, ...applied.actions] }, 1);
174
+ }
134
175
  }
135
176
  }
177
+ finally {
178
+ this.state.readingRetained = false;
179
+ }
180
+ if (!this.state.retainedAlarms)
181
+ return;
136
182
  for (const gone of (0, reconcile_1.alarmsClearedMeanwhile)(this.state, active)) {
137
183
  this.state.alarms.delete(gone.key);
138
184
  await this.executor.apply([{ kind: 'resolve', as: actions_1.CONTROLLER, rowId: gone.rowId, payload: { decision: contracts_1.DECISION.CLEARED, note: `cleared at ${gone.machineId} while the gateway was away` } }]);
@@ -147,7 +193,8 @@ class MachineGateway {
147
193
  return transport_1.DISPOSITION.ACK;
148
194
  }
149
195
  catch (err) {
150
- this.log.error(log_1.GATEWAY_LOG.VERB_FAILED, { event: event.type, error: err.message });
196
+ if (!(err instanceof dispatcher_1.GatewayStopped))
197
+ this.log.error(log_1.GATEWAY_LOG.VERB_FAILED, { event: event.type, error: err.message });
151
198
  return transport_1.DISPOSITION.NAK;
152
199
  }
153
200
  }
@@ -165,19 +212,21 @@ class MachineGateway {
165
212
  return { ...event, role: row.role, data: row };
166
213
  }
167
214
  async onMachine(msg) {
168
- const decoded = this.decode(msg.topic, msg.payload, msg.retained);
215
+ const decoded = this.decode(msg);
169
216
  const acted = [];
170
217
  let outcome = transport_1.DISPOSITION.TERM;
171
218
  let failed = false;
172
219
  for (const raw of decoded) {
173
220
  if (!raw.parsed)
174
221
  continue;
175
- const seen = await (0, admission_1.admitSender)(this.admission, msg.topic, raw);
176
- if (!('parsed' in seen)) {
177
- failed ||= seen.failed;
178
- outcome = worse(outcome, seen.disposition);
222
+ const admitted = await (0, admission_1.admitSender)(this.admission, msg.topic, raw);
223
+ if (!('seen' in admitted)) {
224
+ failed ||= admitted.failed;
225
+ outcome = worse(outcome, admitted.disposition);
226
+ this.wire.inbound(msg, raw, admitted, msg.deliveries, admitted.sender);
179
227
  continue;
180
228
  }
229
+ const { seen } = admitted;
181
230
  acted.push(seen);
182
231
  if (seen.violations.length && msg.deliveries === 1) {
183
232
  this.log.warn(log_1.GATEWAY_LOG.CONTRACT_VIOLATION, { topic: msg.topic, violations: seen.violations });
@@ -187,9 +236,10 @@ class MachineGateway {
187
236
  : await this.applyMachine(msg.topic, seen.parsed, seen.body);
188
237
  failed ||= applied.failed;
189
238
  outcome = worse(outcome, applied.disposition);
239
+ this.wire.inbound(msg, seen, { ...applied, actions: [...admitted.actions, ...applied.actions] }, msg.deliveries);
190
240
  }
191
241
  // No row has claimed it after this many tries, so it is not racing its row: stop. A failed verb always retries.
192
- if (outcome === transport_1.DISPOSITION.NAK && !failed && msg.deliveries >= MAX_DELIVERIES) {
242
+ if (outcome === transport_1.DISPOSITION.NAK && !failed && msg.deliveries >= wire_1.MAX_DELIVERIES) {
193
243
  this.log.warn(log_1.GATEWAY_LOG.UNMATCHED, { topic: msg.topic, deliveries: msg.deliveries });
194
244
  outcome = transport_1.DISPOSITION.TERM;
195
245
  }
@@ -198,14 +248,19 @@ class MachineGateway {
198
248
  return outcome;
199
249
  }
200
250
  /** A message the codec cannot read is not retried: it is logged and has no effect. */
201
- decode(topic, payload, retained) {
251
+ decode(msg) {
252
+ let decoded;
202
253
  try {
203
- return this.codec.decode(topic, payload, retained);
254
+ decoded = this.codec.decode(msg.topic, msg.payload, msg.retained);
204
255
  }
205
256
  catch (err) {
206
- this.log.warn(log_1.GATEWAY_LOG.UNREADABLE, { topic, error: err.message });
257
+ this.log.warn(log_1.GATEWAY_LOG.UNREADABLE, { topic: msg.topic, error: err.message });
258
+ this.wire.unreadable(msg, err.message);
207
259
  return [];
208
260
  }
261
+ if (!decoded.length)
262
+ this.wire.unreadable(msg, 'not a machine message', 'none');
263
+ return decoded;
209
264
  }
210
265
  /** Done with the message: confirm each id its codec asked to confirm. */
211
266
  confirm(decoded) {
@@ -224,21 +279,21 @@ class MachineGateway {
224
279
  }
225
280
  catch (err) {
226
281
  this.log.warn(log_1.GATEWAY_LOG.UNREADABLE, { topic, error: err.message });
227
- return { disposition: transport_1.DISPOSITION.TERM, failed: false };
282
+ return { disposition: transport_1.DISPOSITION.TERM, failed: false, actions: [{ verb: 'unreadable', detail: err.message }] };
228
283
  }
229
284
  try {
230
- await this.executor.apply(plan.actions);
285
+ const actions = await this.executor.apply(plan.actions);
231
286
  await this.pace();
232
- return { disposition: plan.disposition, failed: false };
287
+ return { disposition: plan.disposition, failed: false, actions };
233
288
  }
234
289
  catch (err) {
235
- this.log.error(log_1.GATEWAY_LOG.VERB_FAILED, { topic, error: err.message });
236
- return { disposition: transport_1.DISPOSITION.NAK, failed: true };
290
+ if (!(err instanceof dispatcher_1.GatewayStopped))
291
+ this.log.error(log_1.GATEWAY_LOG.VERB_FAILED, { topic, error: err.message });
292
+ return { disposition: transport_1.DISPOSITION.NAK, failed: true, actions: [] };
237
293
  }
238
294
  }
239
295
  }
240
296
  exports.MachineGateway = MachineGateway;
241
- const MAX_DELIVERIES = 30;
242
297
  const DEFAULT_RECEIPT_DELAY_MS = 250;
243
298
  const RANK = { [transport_1.DISPOSITION.TERM]: 0, [transport_1.DISPOSITION.ACK]: 1, [transport_1.DISPOSITION.NAK]: 2 };
244
299
  /** One wire message may decode to several; any that must be retried retries the message. */
@@ -8,3 +8,6 @@ export * from './provision';
8
8
  export * from './state';
9
9
  export * from './address-book';
10
10
  export * from './registration';
11
+ export * from './wire';
12
+ export * from './project';
13
+ export * from './inspect';
@@ -24,3 +24,6 @@ __exportStar(require("./provision"), exports);
24
24
  __exportStar(require("./state"), exports);
25
25
  __exportStar(require("./address-book"), exports);
26
26
  __exportStar(require("./registration"), exports);
27
+ __exportStar(require("./wire"), exports);
28
+ __exportStar(require("./project"), exports);
29
+ __exportStar(require("./inspect"), exports);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A dry run of one wire message: what the codec reads and what the gateway
3
+ * would do, planned on a copy of the state so the line is untouched and no
4
+ * row is created or changed.
5
+ */
6
+ import type { LineDef } from '../../../lib/machines/line';
7
+ import type { LineCodec } from '../../../lib/machines/protocol';
8
+ import type { InboundMessage } from '../../../lib/machines/transport';
9
+ import type { InspectResult } from '../../../types/machines-view';
10
+ import type { GatewayState } from './state';
11
+ export interface DryRunContext {
12
+ state: GatewayState;
13
+ line: LineDef;
14
+ codec: LineCodec;
15
+ dispatchTtlMs: number;
16
+ }
17
+ export declare function dryRun(ctx: DryRunContext, msg: InboundMessage): InspectResult;