@spine-event-engine/server 2.0.0-snapshot.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +569 -0
  3. package/REFERENCE.md +488 -0
  4. package/dist/bus/command-bus.d.ts +61 -0
  5. package/dist/bus/command-bus.d.ts.map +1 -0
  6. package/dist/bus/command-bus.js +201 -0
  7. package/dist/bus/command-bus.js.map +1 -0
  8. package/dist/bus/command-dispatcher-registry.d.ts +33 -0
  9. package/dist/bus/command-dispatcher-registry.d.ts.map +1 -0
  10. package/dist/bus/command-dispatcher-registry.js +75 -0
  11. package/dist/bus/command-dispatcher-registry.js.map +1 -0
  12. package/dist/bus/command-dispatcher.d.ts +25 -0
  13. package/dist/bus/command-dispatcher.d.ts.map +1 -0
  14. package/dist/bus/command-dispatcher.js +15 -0
  15. package/dist/bus/command-dispatcher.js.map +1 -0
  16. package/dist/bus/command-errors.d.ts +23 -0
  17. package/dist/bus/command-errors.d.ts.map +1 -0
  18. package/dist/bus/command-errors.js +52 -0
  19. package/dist/bus/command-errors.js.map +1 -0
  20. package/dist/bus/event-bus.d.ts +113 -0
  21. package/dist/bus/event-bus.d.ts.map +1 -0
  22. package/dist/bus/event-bus.js +518 -0
  23. package/dist/bus/event-bus.js.map +1 -0
  24. package/dist/bus/event-dispatcher-origin-schemas.d.ts +17 -0
  25. package/dist/bus/event-dispatcher-origin-schemas.d.ts.map +1 -0
  26. package/dist/bus/event-dispatcher-origin-schemas.js +32 -0
  27. package/dist/bus/event-dispatcher-origin-schemas.js.map +1 -0
  28. package/dist/bus/event-dispatcher-registry.d.ts +48 -0
  29. package/dist/bus/event-dispatcher-registry.d.ts.map +1 -0
  30. package/dist/bus/event-dispatcher-registry.js +176 -0
  31. package/dist/bus/event-dispatcher-registry.js.map +1 -0
  32. package/dist/bus/event-dispatcher.d.ts +48 -0
  33. package/dist/bus/event-dispatcher.d.ts.map +1 -0
  34. package/dist/bus/event-dispatcher.js +15 -0
  35. package/dist/bus/event-dispatcher.js.map +1 -0
  36. package/dist/context/bounded-context.d.ts +606 -0
  37. package/dist/context/bounded-context.d.ts.map +1 -0
  38. package/dist/context/bounded-context.js +1780 -0
  39. package/dist/context/bounded-context.js.map +1 -0
  40. package/dist/context/entity-inbox.d.ts +63 -0
  41. package/dist/context/entity-inbox.d.ts.map +1 -0
  42. package/dist/context/entity-inbox.js +380 -0
  43. package/dist/context/entity-inbox.js.map +1 -0
  44. package/dist/context/local-inbox-handoff.d.ts +244 -0
  45. package/dist/context/local-inbox-handoff.d.ts.map +1 -0
  46. package/dist/context/local-inbox-handoff.js +334 -0
  47. package/dist/context/local-inbox-handoff.js.map +1 -0
  48. package/dist/context/projection-handoff.d.ts +46 -0
  49. package/dist/context/projection-handoff.d.ts.map +1 -0
  50. package/dist/context/projection-handoff.js +172 -0
  51. package/dist/context/projection-handoff.js.map +1 -0
  52. package/dist/context/tenant-index.d.ts +41 -0
  53. package/dist/context/tenant-index.d.ts.map +1 -0
  54. package/dist/context/tenant-index.js +92 -0
  55. package/dist/context/tenant-index.js.map +1 -0
  56. package/dist/delivery/conditional-pickup.d.ts +25 -0
  57. package/dist/delivery/conditional-pickup.d.ts.map +1 -0
  58. package/dist/delivery/conditional-pickup.js +26 -0
  59. package/dist/delivery/conditional-pickup.js.map +1 -0
  60. package/dist/delivery/delivery-builder.d.ts +216 -0
  61. package/dist/delivery/delivery-builder.d.ts.map +1 -0
  62. package/dist/delivery/delivery-builder.js +323 -0
  63. package/dist/delivery/delivery-builder.js.map +1 -0
  64. package/dist/delivery/delivery-lease.d.ts +15 -0
  65. package/dist/delivery/delivery-lease.d.ts.map +1 -0
  66. package/dist/delivery/delivery-lease.js +44 -0
  67. package/dist/delivery/delivery-lease.js.map +1 -0
  68. package/dist/delivery/delivery-loop.d.ts +113 -0
  69. package/dist/delivery/delivery-loop.d.ts.map +1 -0
  70. package/dist/delivery/delivery-loop.js +119 -0
  71. package/dist/delivery/delivery-loop.js.map +1 -0
  72. package/dist/delivery/delivery-monitor.d.ts +165 -0
  73. package/dist/delivery/delivery-monitor.d.ts.map +1 -0
  74. package/dist/delivery/delivery-monitor.js +168 -0
  75. package/dist/delivery/delivery-monitor.js.map +1 -0
  76. package/dist/delivery/delivery-ports.d.ts +141 -0
  77. package/dist/delivery/delivery-ports.d.ts.map +1 -0
  78. package/dist/delivery/delivery-ports.js +15 -0
  79. package/dist/delivery/delivery-ports.js.map +1 -0
  80. package/dist/delivery/delivery-run-control.d.ts +50 -0
  81. package/dist/delivery/delivery-run-control.d.ts.map +1 -0
  82. package/dist/delivery/delivery-run-control.js +66 -0
  83. package/dist/delivery/delivery-run-control.js.map +1 -0
  84. package/dist/delivery/delivery-run-coordinator.d.ts +218 -0
  85. package/dist/delivery/delivery-run-coordinator.d.ts.map +1 -0
  86. package/dist/delivery/delivery-run-coordinator.js +609 -0
  87. package/dist/delivery/delivery-run-coordinator.js.map +1 -0
  88. package/dist/delivery/delivery-storage-error.d.ts +13 -0
  89. package/dist/delivery/delivery-storage-error.d.ts.map +1 -0
  90. package/dist/delivery/delivery-storage-error.js +30 -0
  91. package/dist/delivery/delivery-storage-error.js.map +1 -0
  92. package/dist/delivery/delivery-supervisor.d.ts +175 -0
  93. package/dist/delivery/delivery-supervisor.d.ts.map +1 -0
  94. package/dist/delivery/delivery-supervisor.js +469 -0
  95. package/dist/delivery/delivery-supervisor.js.map +1 -0
  96. package/dist/delivery/delivery-worker.d.ts +180 -0
  97. package/dist/delivery/delivery-worker.d.ts.map +1 -0
  98. package/dist/delivery/delivery-worker.js +232 -0
  99. package/dist/delivery/delivery-worker.js.map +1 -0
  100. package/dist/delivery/delivery.d.ts +238 -0
  101. package/dist/delivery/delivery.d.ts.map +1 -0
  102. package/dist/delivery/delivery.js +400 -0
  103. package/dist/delivery/delivery.js.map +1 -0
  104. package/dist/delivery/inbox-records.d.ts +19 -0
  105. package/dist/delivery/inbox-records.d.ts.map +1 -0
  106. package/dist/delivery/inbox-records.js +291 -0
  107. package/dist/delivery/inbox-records.js.map +1 -0
  108. package/dist/delivery/inbox-storage.d.ts +81 -0
  109. package/dist/delivery/inbox-storage.d.ts.map +1 -0
  110. package/dist/delivery/inbox-storage.js +353 -0
  111. package/dist/delivery/inbox-storage.js.map +1 -0
  112. package/dist/delivery/inbox.d.ts +263 -0
  113. package/dist/delivery/inbox.d.ts.map +1 -0
  114. package/dist/delivery/inbox.js +172 -0
  115. package/dist/delivery/inbox.js.map +1 -0
  116. package/dist/delivery/parked-delivery-obligations.d.ts +182 -0
  117. package/dist/delivery/parked-delivery-obligations.d.ts.map +1 -0
  118. package/dist/delivery/parked-delivery-obligations.js +390 -0
  119. package/dist/delivery/parked-delivery-obligations.js.map +1 -0
  120. package/dist/delivery/shard-index.d.ts +41 -0
  121. package/dist/delivery/shard-index.d.ts.map +1 -0
  122. package/dist/delivery/shard-index.js +67 -0
  123. package/dist/delivery/shard-index.js.map +1 -0
  124. package/dist/delivery/sharded-work-registry.d.ts +114 -0
  125. package/dist/delivery/sharded-work-registry.d.ts.map +1 -0
  126. package/dist/delivery/sharded-work-registry.js +360 -0
  127. package/dist/delivery/sharded-work-registry.js.map +1 -0
  128. package/dist/entity/entity-metadata.d.ts +173 -0
  129. package/dist/entity/entity-metadata.d.ts.map +1 -0
  130. package/dist/entity/entity-metadata.js +187 -0
  131. package/dist/entity/entity-metadata.js.map +1 -0
  132. package/dist/entity/entity-storage-descriptor.d.ts +64 -0
  133. package/dist/entity/entity-storage-descriptor.d.ts.map +1 -0
  134. package/dist/entity/entity-storage-descriptor.js +227 -0
  135. package/dist/entity/entity-storage-descriptor.js.map +1 -0
  136. package/dist/entity/entity-transaction.d.ts +372 -0
  137. package/dist/entity/entity-transaction.d.ts.map +1 -0
  138. package/dist/entity/entity-transaction.js +413 -0
  139. package/dist/entity/entity-transaction.js.map +1 -0
  140. package/dist/entity/entity-transition-validation.d.ts +47 -0
  141. package/dist/entity/entity-transition-validation.d.ts.map +1 -0
  142. package/dist/entity/entity-transition-validation.js +327 -0
  143. package/dist/entity/entity-transition-validation.js.map +1 -0
  144. package/dist/entity/entity.d.ts +499 -0
  145. package/dist/entity/entity.d.ts.map +1 -0
  146. package/dist/entity/entity.js +829 -0
  147. package/dist/entity/entity.js.map +1 -0
  148. package/dist/entity/implicit-required-id.d.ts +15 -0
  149. package/dist/entity/implicit-required-id.d.ts.map +1 -0
  150. package/dist/entity/implicit-required-id.js +123 -0
  151. package/dist/entity/implicit-required-id.js.map +1 -0
  152. package/dist/entity/spec-scanner.d.ts +14 -0
  153. package/dist/entity/spec-scanner.d.ts.map +1 -0
  154. package/dist/entity/spec-scanner.js +37 -0
  155. package/dist/entity/spec-scanner.js.map +1 -0
  156. package/dist/handler/build-time-handler-analyzer.d.ts +150 -0
  157. package/dist/handler/build-time-handler-analyzer.d.ts.map +1 -0
  158. package/dist/handler/build-time-handler-analyzer.js +1101 -0
  159. package/dist/handler/build-time-handler-analyzer.js.map +1 -0
  160. package/dist/handler/command-registration-readiness.d.ts +99 -0
  161. package/dist/handler/command-registration-readiness.d.ts.map +1 -0
  162. package/dist/handler/command-registration-readiness.js +118 -0
  163. package/dist/handler/command-registration-readiness.js.map +1 -0
  164. package/dist/handler/event-handler-filter.d.ts +43 -0
  165. package/dist/handler/event-handler-filter.d.ts.map +1 -0
  166. package/dist/handler/event-handler-filter.js +128 -0
  167. package/dist/handler/event-handler-filter.js.map +1 -0
  168. package/dist/handler/event-registration-readiness.d.ts +196 -0
  169. package/dist/handler/event-registration-readiness.d.ts.map +1 -0
  170. package/dist/handler/event-registration-readiness.js +187 -0
  171. package/dist/handler/event-registration-readiness.js.map +1 -0
  172. package/dist/handler/external.d.ts +10 -0
  173. package/dist/handler/external.d.ts.map +1 -0
  174. package/dist/handler/external.js +15 -0
  175. package/dist/handler/external.js.map +1 -0
  176. package/dist/handler/generated-handler-registry.d.ts +154 -0
  177. package/dist/handler/generated-handler-registry.d.ts.map +1 -0
  178. package/dist/handler/generated-handler-registry.js +223 -0
  179. package/dist/handler/generated-handler-registry.js.map +1 -0
  180. package/dist/handler/generated-registry-discovery.d.ts +94 -0
  181. package/dist/handler/generated-registry-discovery.d.ts.map +1 -0
  182. package/dist/handler/generated-registry-discovery.js +228 -0
  183. package/dist/handler/generated-registry-discovery.js.map +1 -0
  184. package/dist/handler/generated-registry-writer.d.ts +58 -0
  185. package/dist/handler/generated-registry-writer.d.ts.map +1 -0
  186. package/dist/handler/generated-registry-writer.js +458 -0
  187. package/dist/handler/generated-registry-writer.js.map +1 -0
  188. package/dist/handler/handler-codegen.d.ts +48 -0
  189. package/dist/handler/handler-codegen.d.ts.map +1 -0
  190. package/dist/handler/handler-codegen.js +214 -0
  191. package/dist/handler/handler-codegen.js.map +1 -0
  192. package/dist/handler/handler-decorators.d.ts +134 -0
  193. package/dist/handler/handler-decorators.d.ts.map +1 -0
  194. package/dist/handler/handler-decorators.js +239 -0
  195. package/dist/handler/handler-decorators.js.map +1 -0
  196. package/dist/handler/handler-metadata.d.ts +510 -0
  197. package/dist/handler/handler-metadata.d.ts.map +1 -0
  198. package/dist/handler/handler-metadata.js +391 -0
  199. package/dist/handler/handler-metadata.js.map +1 -0
  200. package/dist/handler/registration-readiness-metadata.d.ts +68 -0
  201. package/dist/handler/registration-readiness-metadata.d.ts.map +1 -0
  202. package/dist/handler/registration-readiness-metadata.js +170 -0
  203. package/dist/handler/registration-readiness-metadata.js.map +1 -0
  204. package/dist/handler/rejection-source.d.ts +11 -0
  205. package/dist/handler/rejection-source.d.ts.map +1 -0
  206. package/dist/handler/rejection-source.js +25 -0
  207. package/dist/handler/rejection-source.js.map +1 -0
  208. package/dist/index.d.ts +46 -0
  209. package/dist/index.d.ts.map +1 -0
  210. package/dist/index.js +54 -0
  211. package/dist/index.js.map +1 -0
  212. package/dist/integration/external-messages.d.ts +49 -0
  213. package/dist/integration/external-messages.d.ts.map +1 -0
  214. package/dist/integration/external-messages.js +112 -0
  215. package/dist/integration/external-messages.js.map +1 -0
  216. package/dist/integration/integration-broker.d.ts +74 -0
  217. package/dist/integration/integration-broker.d.ts.map +1 -0
  218. package/dist/integration/integration-broker.js +444 -0
  219. package/dist/integration/integration-broker.js.map +1 -0
  220. package/dist/integration/third-party-context.d.ts +56 -0
  221. package/dist/integration/third-party-context.d.ts.map +1 -0
  222. package/dist/integration/third-party-context.js +130 -0
  223. package/dist/integration/third-party-context.js.map +1 -0
  224. package/dist/repository/command-errors.d.ts +25 -0
  225. package/dist/repository/command-errors.d.ts.map +1 -0
  226. package/dist/repository/command-errors.js +43 -0
  227. package/dist/repository/command-errors.js.map +1 -0
  228. package/dist/repository/command-routing.d.ts +72 -0
  229. package/dist/repository/command-routing.d.ts.map +1 -0
  230. package/dist/repository/command-routing.js +98 -0
  231. package/dist/repository/command-routing.js.map +1 -0
  232. package/dist/repository/commit-fence.d.ts +22 -0
  233. package/dist/repository/commit-fence.d.ts.map +1 -0
  234. package/dist/repository/commit-fence.js +37 -0
  235. package/dist/repository/commit-fence.js.map +1 -0
  236. package/dist/repository/event-routing.d.ts +71 -0
  237. package/dist/repository/event-routing.d.ts.map +1 -0
  238. package/dist/repository/event-routing.js +96 -0
  239. package/dist/repository/event-routing.js.map +1 -0
  240. package/dist/repository/primitive-id.d.ts +86 -0
  241. package/dist/repository/primitive-id.d.ts.map +1 -0
  242. package/dist/repository/primitive-id.js +110 -0
  243. package/dist/repository/primitive-id.js.map +1 -0
  244. package/dist/repository/repository.d.ts +670 -0
  245. package/dist/repository/repository.d.ts.map +1 -0
  246. package/dist/repository/repository.js +3298 -0
  247. package/dist/repository/repository.js.map +1 -0
  248. package/dist/repository/routing-declarations.d.ts +75 -0
  249. package/dist/repository/routing-declarations.d.ts.map +1 -0
  250. package/dist/repository/routing-declarations.js +101 -0
  251. package/dist/repository/routing-declarations.js.map +1 -0
  252. package/dist/repository/state-update-routing.d.ts +66 -0
  253. package/dist/repository/state-update-routing.d.ts.map +1 -0
  254. package/dist/repository/state-update-routing.js +91 -0
  255. package/dist/repository/state-update-routing.js.map +1 -0
  256. package/dist/runtime/runtime.d.ts +156 -0
  257. package/dist/runtime/runtime.d.ts.map +1 -0
  258. package/dist/runtime/runtime.js +215 -0
  259. package/dist/runtime/runtime.js.map +1 -0
  260. package/dist/runtime/signal-intake.d.ts +84 -0
  261. package/dist/runtime/signal-intake.d.ts.map +1 -0
  262. package/dist/runtime/signal-intake.js +94 -0
  263. package/dist/runtime/signal-intake.js.map +1 -0
  264. package/dist/runtime/signal-metadata.d.ts +242 -0
  265. package/dist/runtime/signal-metadata.d.ts.map +1 -0
  266. package/dist/runtime/signal-metadata.js +368 -0
  267. package/dist/runtime/signal-metadata.js.map +1 -0
  268. package/dist/server/browser-server.d.ts +49 -0
  269. package/dist/server/browser-server.d.ts.map +1 -0
  270. package/dist/server/browser-server.js +633 -0
  271. package/dist/server/browser-server.js.map +1 -0
  272. package/dist/server/durable-subscription-bindings.d.ts +122 -0
  273. package/dist/server/durable-subscription-bindings.d.ts.map +1 -0
  274. package/dist/server/durable-subscription-bindings.js +524 -0
  275. package/dist/server/durable-subscription-bindings.js.map +1 -0
  276. package/dist/server/environment-attachment.d.ts +356 -0
  277. package/dist/server/environment-attachment.d.ts.map +1 -0
  278. package/dist/server/environment-attachment.js +2061 -0
  279. package/dist/server/environment-attachment.js.map +1 -0
  280. package/dist/server/environment-delivery-records.d.ts +77 -0
  281. package/dist/server/environment-delivery-records.d.ts.map +1 -0
  282. package/dist/server/environment-delivery-records.js +282 -0
  283. package/dist/server/environment-delivery-records.js.map +1 -0
  284. package/dist/server/environment-delivery-worker.d.ts +161 -0
  285. package/dist/server/environment-delivery-worker.d.ts.map +1 -0
  286. package/dist/server/environment-delivery-worker.js +664 -0
  287. package/dist/server/environment-delivery-worker.js.map +1 -0
  288. package/dist/server/environment.d.ts +43 -0
  289. package/dist/server/environment.d.ts.map +1 -0
  290. package/dist/server/environment.js +90 -0
  291. package/dist/server/environment.js.map +1 -0
  292. package/dist/server/managed-child-subscription.d.ts +11 -0
  293. package/dist/server/managed-child-subscription.d.ts.map +1 -0
  294. package/dist/server/managed-child-subscription.js +44 -0
  295. package/dist/server/managed-child-subscription.js.map +1 -0
  296. package/dist/server/managed-server-application.d.ts +324 -0
  297. package/dist/server/managed-server-application.d.ts.map +1 -0
  298. package/dist/server/managed-server-application.js +937 -0
  299. package/dist/server/managed-server-application.js.map +1 -0
  300. package/dist/server/node-coordinator.d.ts +191 -0
  301. package/dist/server/node-coordinator.d.ts.map +1 -0
  302. package/dist/server/node-coordinator.js +552 -0
  303. package/dist/server/node-coordinator.js.map +1 -0
  304. package/dist/server/process-server-coordinator.d.ts +15 -0
  305. package/dist/server/process-server-coordinator.d.ts.map +1 -0
  306. package/dist/server/process-server-coordinator.js +112 -0
  307. package/dist/server/process-server-coordinator.js.map +1 -0
  308. package/dist/server/reserved-spine-rpc-paths.json +8 -0
  309. package/dist/server/retryable-close.d.ts +28 -0
  310. package/dist/server/retryable-close.d.ts.map +1 -0
  311. package/dist/server/retryable-close.js +129 -0
  312. package/dist/server/retryable-close.js.map +1 -0
  313. package/dist/server/server-environment.d.ts +180 -0
  314. package/dist/server/server-environment.d.ts.map +1 -0
  315. package/dist/server/server-environment.js +418 -0
  316. package/dist/server/server-environment.js.map +1 -0
  317. package/dist/server/server-log.d.ts +18 -0
  318. package/dist/server/server-log.d.ts.map +1 -0
  319. package/dist/server/server-log.js +96 -0
  320. package/dist/server/server-log.js.map +1 -0
  321. package/dist/server/server.d.ts +389 -0
  322. package/dist/server/server.d.ts.map +1 -0
  323. package/dist/server/server.js +752 -0
  324. package/dist/server/server.js.map +1 -0
  325. package/dist/services/spine-services.d.ts +88 -0
  326. package/dist/services/spine-services.d.ts.map +1 -0
  327. package/dist/services/spine-services.js +1586 -0
  328. package/dist/services/spine-services.js.map +1 -0
  329. package/dist/stand/stand.d.ts +294 -0
  330. package/dist/stand/stand.d.ts.map +1 -0
  331. package/dist/stand/stand.js +680 -0
  332. package/dist/stand/stand.js.map +1 -0
  333. package/dist/stand/subscription-observer.d.ts +53 -0
  334. package/dist/stand/subscription-observer.d.ts.map +1 -0
  335. package/dist/stand/subscription-observer.js +444 -0
  336. package/dist/stand/subscription-observer.js.map +1 -0
  337. package/dist/stand/subscription-records.d.ts +12 -0
  338. package/dist/stand/subscription-records.d.ts.map +1 -0
  339. package/dist/stand/subscription-records.js +99 -0
  340. package/dist/stand/subscription-records.js.map +1 -0
  341. package/dist/stand/subscription-registry.d.ts +285 -0
  342. package/dist/stand/subscription-registry.d.ts.map +1 -0
  343. package/dist/stand/subscription-registry.js +403 -0
  344. package/dist/stand/subscription-registry.js.map +1 -0
  345. package/dist/stand/subscription-runtime.d.ts +102 -0
  346. package/dist/stand/subscription-runtime.d.ts.map +1 -0
  347. package/dist/stand/subscription-runtime.js +380 -0
  348. package/dist/stand/subscription-runtime.js.map +1 -0
  349. package/dist/testing/index.d.ts +14 -0
  350. package/dist/testing/index.d.ts.map +1 -0
  351. package/dist/testing/index.js +34 -0
  352. package/dist/testing/index.js.map +1 -0
  353. package/dist/tsconfig.tsbuildinfo +1 -0
  354. package/package.json +65 -0
package/REFERENCE.md ADDED
@@ -0,0 +1,488 @@
1
+ # @spine-event-engine/server reference
2
+
3
+ This reference describes the public server contracts for coding agents.
4
+
5
+ ## Integration broker and event origin
6
+
7
+ Each `BoundedContext` creates and closes exactly one private integration broker.
8
+ The broker has distinct status, configuration, and event exchanges. Event
9
+ export is requested-only: a context installs a domestic publisher only for
10
+ event types requested by another context, and withdrawal removes only that
11
+ requester's interest. The broker does not enforce ownership; the supported
12
+ shape is many consumers and one domain producer per event type at a time.
13
+
14
+ The status exchange announces `BoundedContextOnline`; observing a foreign
15
+ announcement resends the local complete wanted-event document. The
16
+ configuration exchange treats each `ExternalEventsWanted` as a complete
17
+ replacement, installs producer publication on the first requester, avoids
18
+ duplicate unchanged broadcasts, and removes publication after the last
19
+ withdrawal. The event exchange uses one logical channel per event message type
20
+ and retains the original Event ID and complete Event. Self-origin and paired
21
+ domain/System Context messages are ignored.
22
+
23
+ `External<T>` is exported as a transparent type alias (`type External<T> = T`)
24
+ and has no runtime value or brand. The build-time handler analyzer recognizes
25
+ the canonical server declaration only when it is the direct first receptor
26
+ parameter. Missing markers mean `domestic`; a valid marker means `external`.
27
+ External commands are rejected, while external event/rejection handlers and
28
+ the supported state-subscription path are filtered by `EventContext.external`.
29
+ Repository selection applies the filter per handler, including mixed-origin
30
+ repositories. This is also the loop rule: domestic publication and origin
31
+ filtering prevent self-origin and paired-context traffic; no hop count, origin
32
+ ledger, Inbox, retry, replay, deduplication, cursor, fencing, or election is
33
+ added.
34
+
35
+ Incoming broker frames must contain a valid `ExternalMessage` wrapper and a
36
+ complete `Event`. The server unpacks and validates the event, obtains the
37
+ tenant from its explicit event origin, validates that tenant at the existing
38
+ boundary, copies only `EventContext.external = true`, and posts the ordinary
39
+ domain `EventBus`, whose admitted schemas are the destination's authority for
40
+ incoming payload decoding. Unknown or malformed received payloads are logged safely,
41
+ dropped, and do not stop the broker loop. Zero-byte control messages are valid
42
+ where the Proto contract permits an empty payload.
43
+
44
+ Malformed, unknown-schema, or undecodable received events emit the fixed ERROR
45
+ message `Dropped corrupt external event.` with safe `contextName`, `eventType`,
46
+ `operation: external-event-intake`, and
47
+ `reasonCode: corrupt_external_event`; the callback resolves, the event is
48
+ dropped, and later valid events continue. Application intake failures after a
49
+ valid decode remain observable.
50
+
51
+ Context readiness includes broker open. Close gates new EventBus intake before
52
+ awaiting transport work, broadcasts an empty wanted document, detaches domestic
53
+ publishers and external subscribers, drains accepted work, and closes acquired
54
+ channels. Failed cleanup remains retryable and concurrent close callers share
55
+ one attempt.
56
+
57
+ `ThirdPartyContext` is the sole public third-party import API. Its
58
+ `singleTenant()` form forbids an actor tenant; `multitenant()` requires one.
59
+ `emittedEvent(event, actor)` accepts a registered generated Protobuf message used as an event
60
+ payload and `ActorContext` (or a
61
+ `UserId` in the single-tenant form), preserves actor identity and timestamp,
62
+ and publishes through its hidden context. An unknown local schema throws; a
63
+ valid event with no interested external receptor is simply not delivered.
64
+
65
+ ## Server environment facilities
66
+
67
+ `ServerEnvironment.instance()` is a process-wide singleton. Production
68
+ resolution requires storage and the complete application schema registry:
69
+
70
+ ```ts
71
+ import { EnvironmentType, ServerEnvironment } from "@spine-event-engine/server";
72
+ import type { TypeRegistryLookup } from "@spine-event-engine/core";
73
+ import type { StorageFactory } from "@spine-event-engine/storage";
74
+
75
+ declare const storageFactory: StorageFactory;
76
+ declare const typeRegistry: TypeRegistryLookup;
77
+
78
+ ServerEnvironment.when(EnvironmentType.Production).use({
79
+ storageFactory,
80
+ typeRegistry,
81
+ });
82
+ ```
83
+
84
+ `storageFactory` supplies records and events. `typeRegistry` is the complete
85
+ application schema universe used by `ThirdPartyContext` to encode outgoing
86
+ imported events. An optional `integrationChannelFactory` overrides the
87
+ process-wide private
88
+ integration message channel factory. When it is absent, all local bounded
89
+ contexts share one in-memory factory, including in production. Local and test
90
+ environments default storage in memory and use the core registry only as a
91
+ fallback; those defaults are not production configuration.
92
+
93
+ To override the default channel factory, add
94
+ `integrationChannelFactory: customFactory` to the same settings object.
95
+
96
+ ## Routing lifecycle
97
+
98
+ Event, command, and state-update routing accepts exact schemas and nominal
99
+ message-interface tokens. It selects exact, first registered matching token,
100
+ then replacement/default. The route runs once at accepted admission; its
101
+ validated typed targets are stored and reused for retries. The legacy-named
102
+ local `catchUpReadSide()` helper is unrelated to retry: it resets and replays
103
+ the whole local read side, and is not Projection catch-up.
104
+
105
+ ## Handler routing and operations
106
+
107
+ Generated handler metadata routes a command, event, or state update by its
108
+ exact generated message type. A declared default route is considered only when
109
+ there is no exact route. This is TypeScript routing; it does not consume
110
+ `(is).java_type` or `(every_is).java_type`, and it has no decorator-based
111
+ route registration API.
112
+
113
+ One `@Where({ eventField, equals })` equality filter may narrow an event- or
114
+ rejection-consuming `@Subscribe`, `@React`, or `@Command` handler after type
115
+ routing. `eventField` and `equals` are typed string literals; invalid or
116
+ repeated declarations fail closed. It is not an alternative routing mechanism.
117
+
118
+ Configure logging through `ServerEnvironment` when assembling the server. The
119
+ server installs that logger into its runtime components, where warnings and
120
+ failures carry operation context. Durable facts belong in events or storage.
121
+ Entity Inbox replay sends persisted accepted work through the normal handler
122
+ path, so handler effects must be replay-safe.
123
+
124
+ ## Context assembly and entities
125
+
126
+ Create a context with `BoundedContext.singleTenant(name)` or
127
+ `BoundedContext.multitenant(name)`. Names are immutable. Use
128
+ `withStorageFactory(factory)` to supply record/event storage.
129
+ `withGeneratedRegistryRoot(root)` enables framework discovery of the generated
130
+ handler registry for classes registered with `add(EntityClass)`;
131
+ `buildAsync()` performs that discovery and assembly. `build()` remains for
132
+ explicit `Repository` registration. A built context contains `CommandBus`,
133
+ `EventBus`, `Stand`, repositories, and its storage lifecycle.
134
+
135
+ ### Stand subscription registry
136
+
137
+ Each built context also has one `StandSubscriptionRegistry`. By default the
138
+ builder creates a storage-backed registry from the resolved context
139
+ `StorageFactory` (including the `ServerEnvironment` factory used for a builder
140
+ added to a server). It stores one `spine.client.SubscriptionRecord` under each
141
+ explicit `SubscriptionId`. A complete custom implementation can instead be
142
+ supplied with `withSubscriptionRegistry(registry)`; responsibility transfers to
143
+ the builder on the first build attempt.
144
+
145
+ `SubscriptionService` streams are live best-effort notifications, not replay,
146
+ ordering, or completeness contracts. A standalone Server defaults to the
147
+ persistent registry. In a managed complete-replica cohort, the framework owns
148
+ each child Server and accepts only every context's actual
149
+ `InMemorySubscriptionRegistry`; a persistent or custom registry is rejected
150
+ and the assembled child is closed before READY. Durable logical bindings remain
151
+ Gateway-only. The Coordinator fans each logical definition to ready children,
152
+ merges updates, propagates cancellation, and carries no subscription payload on
153
+ parent/child IPC. A late or replacement child synchronizes retained definitions
154
+ before it is eligible for normal requests. Active definitions attach their
155
+ child streams before admission; subscribed but inactive definitions do not
156
+ block readiness. Each child observes application-configured remote/shared
157
+ Delivery directly. During DRAINING, new unary and shard admission stops while
158
+ active Delivery and its subscription updates finish before child close. The
159
+ application owns Delivery facility and shard-strategy selection; managed mode
160
+ does not infer or certify configuration provenance.
161
+
162
+ Create records begin `pending` and expire after 30 seconds unless activated.
163
+ Active records have no framework TTL. Cancellation physically deletes the
164
+ definition; no tombstone remains. A stored definition is at most 1 MiB
165
+ (1,048,576 bytes). Its physical provider columns are `status` and
166
+ `when_activation_expires`. `cleanup()` asks the provider for 26 pending rows
167
+ ordered by `when_activation_expires` then ID, validates that finite result,
168
+ deletes at most 25 expired definitions, and reports `more` only when its
169
+ observed 26th row is expired. Cleanup can run idempotently on every node.
170
+
171
+ Context close drains and closes Stand before its registry, then closes tenant,
172
+ repository, and storage resources; it attempts every close and reports
173
+ aggregate failures. An in-memory registry reports `persistent === false`.
174
+ Attaching such a context to a production `ServerEnvironment` emits one
175
+ context-name-only warning without failing startup; Local environments do not
176
+ warn.
177
+
178
+ Creation writes the pending record only when that ID is absent. Activation
179
+ replaces that pending record only when it remains unchanged. Cancellation and
180
+ expiry cleanup delete the observed record only when it remains unchanged. Each
181
+ node reconciles its local snapshot immediately after context assembly and then
182
+ every ten seconds. Physical deletion detaches the local observer after its next
183
+ completed cycle. This is best-effort per-node convergence, not a
184
+ cluster-completeness, replay, ordering, gap-repair, or exactly-once guarantee.
185
+
186
+ The registry accepts only a generated `SubscriptionId` for activate, get, and
187
+ delete. `create(subscription)` returns `{ kind: "created", entry }` or
188
+ `{ kind: "existing", entry }`; the latter requires byte-equivalent canonical
189
+ content and a different definition with the same ID throws `StandConflictError`.
190
+ `activate(id)` returns `activated`, `active`, `missing`, or `expired`.
191
+ `delete(id)` returns `deleted` or `missing`. Blank IDs or topics and malformed
192
+ durable records fail closed.
193
+
194
+ Entries and nested subscriptions returned by create, activate, get, and
195
+ snapshot are clone-safe views. Protobuf byte arrays remain mutable runtime
196
+ views but are cloned so they never alias caller storage. Snapshots are ordered
197
+ by identifier. A durable provider must implement atomic compare-and-set for
198
+ `SubscriptionRecord`; construction rejects a provider that cannot. MySQL table
199
+ configuration and Datastore custom record storage registered for
200
+ `SubscriptionRecord` are used by the registry. The registry uses one
201
+ record-storage handle, while the context closes the registry.
202
+
203
+ `Entity` is the state base class. `Aggregate`, `Projection`, and
204
+ `ProcessManager` identify the three entity families. Handler decorators are
205
+ `@Assign`, `@Command`, `@React`, `@Subscribe`, and `@Apply`. In a transactional
206
+ handler, `update(mutator)` changes the active draft and returns the draft;
207
+ `tryUpdate(mutator)` validates a scratch draft and returns violations without
208
+ applying an invalid change. Entity lifecycle and version changes are committed
209
+ only after the transaction accepts.
210
+
211
+ ## Signals, validation, and rejection behavior
212
+
213
+ `CommandBus` validates every accepted command from Proto validation options
214
+ before dispatcher or repository handler code runs. It raises the framework's
215
+ command-validation failure, which `SpineServices` maps to
216
+ `COMMAND_VALIDATION_ERROR` with a packed `spine.validation.ValidationError`.
217
+ Entity transition validation failures map to
218
+ `COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type.
219
+
220
+ An application handler throws a generated core `RejectionThrowable` for a
221
+ domain rejection. The repository rolls back state, version, lifecycle, and
222
+ output; it schedules the typed rejection event independently. Command service
223
+ acknowledgement remains an accepted `Ack`. Rejection-event posting can be
224
+ unobserved by inactive, full, or closed subscriptions and a posting failure is
225
+ an internal diagnostic, not a retry guarantee.
226
+
227
+ Every domain context has an internal paired System Context. Domain events use
228
+ the domain `EventBus` and domain `EventStore`. System events use only the
229
+ System Context `EventBus`, so they never enter the domain EventStore. System
230
+ event persistence is optional: `persistSystemEvents()` enables the paired
231
+ System Context's separate storage; otherwise the bus validates, dispatches,
232
+ and notifies without appending. Schemas may come from an external dispatcher or
233
+ a registered internal repository producer. A producer-only schema is not
234
+ thereby an external dispatch route.
235
+
236
+ ## Services, reads, and lifecycle
237
+
238
+ `SpineServices({ contexts }).register(router)` registers the JVM-compatible
239
+ CommandService, QueryService, and SubscriptionService contracts. `Server`
240
+ opens the local Node HTTP/2 listener; default host is `127.0.0.1`. Set
241
+ `readMaxBytes` and `writeMaxBytes` only to integers 1–4294967295; defaults are 4194304. `RunningServer.close()` stops intake, closes sessions, waits for active
242
+ work to stop using dependencies, then closes contexts. Caller-managed `start()`
243
+ does not close global process facilities; close `ServerEnvironment.instance()`
244
+ separately when used. The final run-managed `run()` close closes its environment.
245
+
246
+ `Stand` registers entity state for point/list reads, updates current state, and
247
+ offers in-process subscriptions. The legacy-named local reset/replay helper
248
+ `catchUpReadSide(options?)` clears every registered Projection state and replays
249
+ the whole stored event history through matching Projection subscribers; it does
250
+ not append events. Single-tenant contexts reject a tenant option; multitenant
251
+ contexts require one. It cannot target a Projection repository, entity IDs, or
252
+ a starting time, and has no durable operation identity, progress, Inbox
253
+ catch-up delivery, restart, resumption, or historical/live coordination. It is
254
+ not JVM-equivalent Projection catch-up.
255
+
256
+ Active subscription streams and queues are process-local. `Stand` serves
257
+ authoritative queries from current state and Entity subscriptions observe
258
+ committed `EntityStateChanged` messages on the paired System Context EventBus,
259
+ so a direct Stand write alone does not produce a subscription update. Consumer
260
+ callback failures are isolated from post-commit observation and other
261
+ consumers. The package does not guarantee cluster-complete observations,
262
+ subscription replay, event-gap repair, or exactly-once effects.
263
+
264
+ ### Standalone and browser hosting
265
+
266
+ `Server.start()` installs no process signal handlers, never closes its
267
+ environment, and shares only a caller-managed active generation. `Server.run()`
268
+ coalesces concurrent calls on one builder, shares a run-managed generation with
269
+ other `run()` servers, and rejects mixed admission before listener open. The
270
+ coordinator uses one `SIGINT`/`SIGTERM` listener pair, closes servers in reverse
271
+ successful-start order, retains failed final environment closure for later
272
+ signal or explicit-close retry, and sets `process.exitCode` to `1` after a
273
+ signal-driven failure.
274
+
275
+ `ManagedServerApplication.run()` is the Node-only deployment entrypoint for a
276
+ complete-replica process cohort when the framework owns process shutdown.
277
+ `ManagedServerApplication.start()` starts the same cohort for an embedding host
278
+ and installs no process signal handlers; that host closes the returned handle.
279
+ Both require a positive safe-integer
280
+ `processCount` and an ESM `moduleUrl`; it never derives a process count from
281
+ the machine. Its optional `host` and required nonzero `port` bind the public
282
+ Coordinator listener. Every child executes that same module and calls its own
283
+ `createServer({ host: "127.0.0.1", port: 0 })`. The child reports its actual
284
+ loopback endpoint only after its local readiness gates settle. The parent
285
+ initially waits until every configured child is ready. Afterwards it is ready
286
+ while at least one child is ready; it remains alive and keeps replacing while
287
+ degraded, and reports unready if no child is ready. It replaces an unexpected
288
+ child exit after a bounded exponential delay (250 ms initially, capped at 30 s;
289
+ reset after 60 s READY). It does not restart a child being closed. Restart
290
+ values are optional `restart` settings and must be positive safe integers;
291
+ concurrent starts default to `min(4, processCount)`. `run()` parent `SIGINT`
292
+ and `SIGTERM` use the same shared child-close path; `start()` leaves those
293
+ signals to its caller. This private lifecycle channel
294
+ does not transport application signals. The Coordinator forwards generated
295
+ Command and Query unary calls once to a READY child; process count does not
296
+ inspect CPU availability and does not constrain the application's independently
297
+ chosen `DeliveryStrategy` or shard count. Direct `Server.run()` and browser
298
+ hosting remain independent of managed Node deployment.
299
+
300
+ If no child is READY, Command and Query return gRPC `UNAVAILABLE`. The
301
+ Coordinator does not enter application intake and does not retry the selected
302
+ call on a sibling child. Subscription fan-out follows current READY members;
303
+ later and replacement members attach the retained subscription before managed
304
+ admission.
305
+
306
+ `ServerOptions.browser` changes the public listener, not the bounded-context
307
+ services. The native HTTP/2 backend binds to an ephemeral loopback port and is
308
+ never returned. After it is ready, the server creates `UnaryGateway`,
309
+ `SubscriptionGateway`, and native gateway services, then binds one HTTP/1.1
310
+ Connect/gRPC-Web listener. A public bind failure closes subscription resources
311
+ and the native backend; multiple rollback failures are aggregated.
312
+
313
+ Browser unary gateway admission has a fixed 1 MiB (1,048,576-byte) request
314
+ limit. A larger unary gateway request is rejected with `ResourceExhausted`.
315
+ This is an additional boundary: `readMaxBytes` still limits the Connect or
316
+ gRPC-Web transport message accepted by the public listener, so the effective
317
+ inbound limit is the stricter applicable limit. `writeMaxBytes` limits public
318
+ transport responses independently.
319
+
320
+ Browser origins must be unique canonical HTTP(S) origins with no path, query,
321
+ fragment, or trailing slash. Requests without an allowed exact `Origin` receive
322
+ 403 before RPC handling. Allowed responses include credentialed exact-origin
323
+ CORS, `Vary: Origin`, protocol request headers, and exposed gRPC status headers.
324
+
325
+ Supplying `browser.backend.baseUrl` selects standalone mode. It is one canonical
326
+ HTTP(S) origin for a Spine TS or JVM backend; the gateway never closes
327
+ that backend. Every standalone mode, including local development and tests,
328
+ requires explicit subscription bindings; production additionally requires an
329
+ application type registry and named durable bindings. `ResolveContext` stays in the gateway;
330
+ Post, Read, Subscribe, Activate, and Cancel use the same authenticated policy,
331
+ context-replacement, and native descriptors before reaching the backend.
332
+
333
+ `browser.backend.baseUrls` is exclusive with `baseUrl` and configures a
334
+ non-empty ordered unique static node set. Unary calls use bounded round-robin
335
+ without retry; native streams fan out best-effort. Durable bindings retain only
336
+ logical definitions, not topology. Clients
337
+ re-query authoritative state after duplicate updates or generic loss notices.
338
+
339
+ `browser.authRoutes` is deliberately a bounded callback seam, not a router.
340
+ Each registration has one exact `GET` or `POST` canonical path, one method per
341
+ path, exact canonical origins, finite request bytes, and a finite timeout. A
342
+ missing Origin is rejected unless that route explicitly permits it for an OAuth
343
+ callback. Unknown paths, method/origin failures, body overflow, timeout, and
344
+ handler failure return fixed 404, 405, 403, 413, 504, and 500 responses without
345
+ calling application code on rejected input. The 404 unknown-path result applies
346
+ only after framework Origin admission. Auth admission is bounded to 64 active
347
+ requests by default or a configured positive `maxActiveAuthRequests`; excess
348
+ requests receive 503 before handler invocation and capacity returns when work
349
+ settles. The route deadline covers body intake, handler work, and response
350
+ transfer. Response bodies use `writeMaxBytes`; overflow returns 413 before any
351
+ application status or headers are committed. Listener close ultimately aborts
352
+ an active request through its disconnect signal.
353
+
354
+ With `cookies`, `OpaqueSessionCookies` performs strict bearer-first or
355
+ CSRF-protected cookie extraction. A strict rejection becomes an unusable
356
+ credential and never falls back to permissive header parsing. Without cookies,
357
+ the host accepts exactly one non-whitespace bearer token. Credentials and raw
358
+ transport metadata do not reach the private backend. The application-supplied
359
+ context resolver replaces caller actor and tenant facts before forwarding.
360
+
361
+ Browser close stops new listener intake, closes subscription admission and
362
+ bindings so active streams settle, awaits listener closure, then closes the
363
+ native backend. Concurrent calls share an attempt; a failed unfinished phase
364
+ can be retried without repeating completed native cleanup.
365
+
366
+ Browser subscription bindings are separate from service subscription records.
367
+ `BrowserAdmission` selects their ownership. Authenticated mode supplies
368
+ `sessions` and may supply `BrowserServerOptions.bindings`; production then
369
+ requires the Server package's `DurableSubscriptionBindings` and rejects a
370
+ missing or in-memory binding store before listener open. Public mode supplies
371
+ `publicAccess: true`, cannot supply bindings, and uses framework-owned
372
+ process-local bindings. The durable registry receives an explicit application
373
+ namespace, storage factory, identifier source, and cleanup callback. It closes
374
+ only its independently opened record-storage handle, not the application
375
+ storage factory or a Spine JVM/TS backend. It stores canonical public
376
+ Subscription definitions, never backend envelopes or membership topology, and
377
+ never returns private native data through public subscription responses.
378
+
379
+ The durable registry preserves one approved `GatewayAuthenticatedSubscription`
380
+ per public subscription through a process restart. It validates the record ID,
381
+ full Subscription, and expiry before use. The trusted Actor and Tenant remain
382
+ inside the stored Topic and are checked for Activate and Cancel. Create assigns
383
+ the public ID directly; no quota, reservation, fingerprint, or lease is
384
+ persisted. Cleanup remains bounded and restart-safe at the record level. It
385
+ cleans the backend definition before deleting its record. It is not a cleaner
386
+ lease or fence: this direct store supports one Gateway process. Active streams do not resume,
387
+ updates are not replayed, and the registry provides neither exactly-once
388
+ delivery, global update ordering, nor cluster-complete notification delivery.
389
+
390
+ ## Delivery and environment
391
+
392
+ `Inbox`, `InboxStorage`, `ShardIndex`, and `ShardedWorkRegistry` provide the
393
+ local durable-row abstraction. Read limits are 1–1000; work leases are
394
+ 1000–2147483647 ms. Framework replay supports command handling, projection
395
+ updates, and process-manager reactions. Callbacks are at-least-once/replay-safe:
396
+ lost renewal can prevent stale finalization but cannot undo a callback already
397
+ run. The package exposes no general raw worker callback API.
398
+
399
+ Shard ownership is the only delivery exclusion mechanism and excludes
400
+ concurrent delivery within that shard. Pending and delivered `InboxMessage`
401
+ rows are direct records; a delivered row is the deduplication fact. A handler
402
+ effect and the exact pending-to-delivered compare-and-set are not one
403
+ transaction, so a lost acknowledgement can redeliver after restart. Downstream
404
+ signal handling must be idempotent. A customized `DeliveryWorkRegistry`
405
+ implements `validateOwnership()` so delivery can validate before dispatch, at
406
+ repository commit time, and before acknowledgement. Validation is a fence
407
+ against an observed takeover, not a distributed transaction with handler
408
+ storage.
409
+
410
+ `keepUntil` is the optional deduplication-protection deadline, not a second
411
+ retention setting. A delivered row is cleanup-eligible when that deadline is
412
+ absent or elapsed. Under current shard ownership, environment delivery performs
413
+ one bounded cleanup page, plus at most one continuation after a full protected
414
+ page makes no removal. Each removal atomically verifies ownership and the exact
415
+ delivered snapshot. Pending, retryable, non-delivered, and still-protected rows
416
+ remain. There is no additional retention configuration, timer, or scheduler.
417
+
418
+ `BoundedContextBuilder.withDeliveryStrategy(strategy)` snapshots a validated
419
+ immutable strategy for its Entity Inbox; the default is one shard. For example,
420
+ use the public builder chain:
421
+
422
+ ```ts
423
+ import { BoundedContext, UniformAcrossAllShards } from "@spine-event-engine/server";
424
+
425
+ const context = BoundedContext.singleTenant("Tasks")
426
+ .withDeliveryStrategy(UniformAcrossAllShards.forNumber(3))
427
+ .build();
428
+ ```
429
+
430
+ Aggregate commands and Process Manager commands/events derive their target shard
431
+ internally and persist their envelope in the target Entity Inbox before any
432
+ handler runs. Delivery is never a post-request callback: local and remote
433
+ handler runs. Local intake can directly drain the persisted Inbox in the
434
+ current request path. Attached `ServerEnvironment` ports acknowledge admission
435
+ and delivery workers replay it through the same path. Projection rows remain
436
+ separate.
437
+
438
+ `DeliveryBuilder` constructs a controlled `Delivery`; `DeliverySupervisor`
439
+ receives `{ source, delivery, onMessage }`, manages bounded shard notifications
440
+ from that structural source, and must start after endpoints are ready and close
441
+ before source client/storage. `DeliverySource` is not configured on
442
+ `DeliveryBuilder`. The supervisor does not promise
443
+ durable supervisor state, topology failover, exactly-once effects, or automatic
444
+ retry of unknown remote mutations.
445
+
446
+ Each drain operation is bounded to one page. That bound limits a single
447
+ operation, not the total pending work: an active lease owner can take another
448
+ page while its policy retains the shard. The 30-second Inbox deduplication
449
+ window controls duplicate admission only; it is not a replay-retention period.
450
+ Persisted accepted rows follow their delivery lifecycle and may be replayed
451
+ according to that lifecycle after the deduplication window has elapsed.
452
+
453
+ `DeliveryMonitor` is an instantiable, customizable policy seam exposing
454
+ asynchronous continuation, start/completion, failed-reception, pickup-failure,
455
+ and already-picked hooks.
456
+ `FailedReception` supplies only `markDelivered()` and one immediate
457
+ `repeatDispatching()` action; the framework adds no attempt history, timer,
458
+ backoff, quarantine, dead-letter, receipt, marker, or scheduler policy. A failed
459
+ durable acknowledgement keeps that row pending, blocks later rows for its
460
+ target during the run, and does not prevent independent targets from running.
461
+
462
+ `Environment` resolves the Node `local` or `production` profile once from
463
+ `NODE_ENV`. `ServerEnvironment` resolves configured facilities once for that
464
+ profile and exposes its `storageFactory`, optional `delivery`, optional
465
+ `tracerFactory`, `nodeId`, and `close()` lifecycle. Applications do
466
+ not manage internal server attachments through this public API. Neither API
467
+ authenticates requests or supplies a production scheduler, remote topology,
468
+ storage adapter, or deployment policy.
469
+
470
+ `ServerEnvironmentDelivery` extends the existing closeable facility shape with
471
+ `open()` plus generic `inbox` and `workRegistry` ports. After readiness, the
472
+ environment supplies those ports to both existing delivery paths: direct finite
473
+ `Delivery` construction and the supervisor's `DeliveryBuilder`. The environment
474
+ invokes `open()` once before attachment admission and coalesces concurrent
475
+ callers; rejection admits no attachment and a later attempt retries open. A
476
+ close-only local delivery remains source-compatible. After attachments retire,
477
+ environment close runs delivery, tracer, then storage and preserves retry
478
+ checkpoints for failed phases.
479
+
480
+ `ServerEnvironmentDelivery.source` is optional. When present, its Admin source
481
+ is used by the environment supervisor for remote snapshots and
482
+ shard-update hints; when absent, the existing local source remains the fallback.
483
+ Applications configure and close only the delivery facility through the
484
+ environment: attachment supervisors and their source reads belong to that facility.
485
+
486
+ # Dynamic unary discovery
487
+
488
+ `BrowserServerOptions.discovery` may supply changing complete application-node snapshots alongside fixed `backend` configuration. Both unary routing and native subscription streams use the same current membership. Empty membership retains durable definitions and later nodes reactivate them; a new backend-dependent subscription is unavailable until a node exists.
@@ -0,0 +1,61 @@
1
+ import { type Command } from "@spine-event-engine/proto";
2
+ import type { CommandDispatcher } from "./command-dispatcher.js";
3
+ interface CommandBusAccess {
4
+ postInternal(commandBus: CommandBus, command: Command): Promise<void>;
5
+ beginClose(commandBus: CommandBus): void;
6
+ drain(commandBus: CommandBus): Promise<void>;
7
+ finishClose(commandBus: CommandBus): Promise<void>;
8
+ acceptedWorkCount(commandBus: CommandBus): number;
9
+ }
10
+ /**
11
+ * Small single-process unicast command bus.
12
+ *
13
+ * Commands are accepted asynchronously through `post()` and routed by enclosed
14
+ * message type URL to exactly one registered dispatcher.
15
+ */
16
+ export declare class CommandBus {
17
+ #private;
18
+ /**
19
+ * Creates a bus and registers its initial dispatchers.
20
+ *
21
+ * @param dispatchers the dispatchers to register.
22
+ */
23
+ constructor(dispatchers?: Iterable<CommandDispatcher>);
24
+ /**
25
+ * Registers a dispatcher.
26
+ *
27
+ * @param dispatcher the dispatcher to register.
28
+ * @returns the registered dispatcher.
29
+ */
30
+ register<Dispatcher extends CommandDispatcher>(dispatcher: Dispatcher): Dispatcher;
31
+ /**
32
+ * Lists command type URLs accepted by registered dispatchers.
33
+ *
34
+ * @returns the accepted command type URLs.
35
+ */
36
+ acceptedCommandTypes(): readonly string[];
37
+ /**
38
+ * Posts a command for asynchronous dispatch.
39
+ *
40
+ * @param command the command envelope to post.
41
+ * @returns A promise that settles after queued command dispatch completes and may reject.
42
+ */
43
+ post(command: Command): Promise<void>;
44
+ /**
45
+ * Stops accepting new command work and waits for accepted work to settle.
46
+ *
47
+ * Close is idempotent and returns the same close outcome on repeated calls.
48
+ * Runtime close failures reject the returned promise.
49
+ * @returns A promise that settles after the command bus closes.
50
+ *
51
+ */
52
+ close(): Promise<void>;
53
+ }
54
+ /**
55
+ * Provides framework-owned command posting and coordinated close access.
56
+ *
57
+ * @internal
58
+ */
59
+ export declare const commandBusAccess: CommandBusAccess;
60
+ export {};
61
+ //# sourceMappingURL=command-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-bus.d.ts","sourceRoot":"","sources":["../../src/bus/command-bus.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAUxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAQjE,UAAU,gBAAgB;IACxB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACzC,KAAK,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;CACnD;AAID;;;;;GAKG;AACH,qBAAa,UAAU;;IAQrB;;;;OAIG;gBACS,WAAW,GAAE,QAAQ,CAAC,iBAAiB,CAAM;IAezD;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,SAAS,iBAAiB,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU;IAKlF;;;;OAIG;IACH,oBAAoB,IAAI,SAAS,MAAM,EAAE;IAIzC;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrC;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CA6EvB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAkD7B,CAAC"}