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

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 (378) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +209 -0
  3. package/REFERENCE.md +760 -0
  4. package/dist/browser/browser-server.d.ts +95 -0
  5. package/dist/browser/browser-server.d.ts.map +1 -0
  6. package/dist/browser/browser-server.js +719 -0
  7. package/dist/browser/browser-server.js.map +1 -0
  8. package/dist/browser/durable-subscription-bindings.d.ts +122 -0
  9. package/dist/browser/durable-subscription-bindings.d.ts.map +1 -0
  10. package/dist/browser/durable-subscription-bindings.js +524 -0
  11. package/dist/browser/durable-subscription-bindings.js.map +1 -0
  12. package/dist/browser/index.d.ts +12 -0
  13. package/dist/browser/index.d.ts.map +1 -0
  14. package/dist/browser/index.js +24 -0
  15. package/dist/browser/index.js.map +1 -0
  16. package/dist/browser/options.d.ts +183 -0
  17. package/dist/browser/options.d.ts.map +1 -0
  18. package/dist/browser/options.js +15 -0
  19. package/dist/browser/options.js.map +1 -0
  20. package/dist/bus/command-bus.d.ts +63 -0
  21. package/dist/bus/command-bus.d.ts.map +1 -0
  22. package/dist/bus/command-bus.js +236 -0
  23. package/dist/bus/command-bus.js.map +1 -0
  24. package/dist/bus/command-dispatcher-registry.d.ts +33 -0
  25. package/dist/bus/command-dispatcher-registry.d.ts.map +1 -0
  26. package/dist/bus/command-dispatcher-registry.js +75 -0
  27. package/dist/bus/command-dispatcher-registry.js.map +1 -0
  28. package/dist/bus/command-dispatcher.d.ts +25 -0
  29. package/dist/bus/command-dispatcher.d.ts.map +1 -0
  30. package/dist/bus/command-dispatcher.js +15 -0
  31. package/dist/bus/command-dispatcher.js.map +1 -0
  32. package/dist/bus/command-errors.d.ts +23 -0
  33. package/dist/bus/command-errors.d.ts.map +1 -0
  34. package/dist/bus/command-errors.js +52 -0
  35. package/dist/bus/command-errors.js.map +1 -0
  36. package/dist/bus/event-bus.d.ts +113 -0
  37. package/dist/bus/event-bus.d.ts.map +1 -0
  38. package/dist/bus/event-bus.js +518 -0
  39. package/dist/bus/event-bus.js.map +1 -0
  40. package/dist/bus/event-dispatcher-origin-schemas.d.ts +17 -0
  41. package/dist/bus/event-dispatcher-origin-schemas.d.ts.map +1 -0
  42. package/dist/bus/event-dispatcher-origin-schemas.js +32 -0
  43. package/dist/bus/event-dispatcher-origin-schemas.js.map +1 -0
  44. package/dist/bus/event-dispatcher-registry.d.ts +48 -0
  45. package/dist/bus/event-dispatcher-registry.d.ts.map +1 -0
  46. package/dist/bus/event-dispatcher-registry.js +176 -0
  47. package/dist/bus/event-dispatcher-registry.js.map +1 -0
  48. package/dist/bus/event-dispatcher.d.ts +48 -0
  49. package/dist/bus/event-dispatcher.d.ts.map +1 -0
  50. package/dist/bus/event-dispatcher.js +15 -0
  51. package/dist/bus/event-dispatcher.js.map +1 -0
  52. package/dist/context/bounded-context.d.ts +592 -0
  53. package/dist/context/bounded-context.d.ts.map +1 -0
  54. package/dist/context/bounded-context.js +1897 -0
  55. package/dist/context/bounded-context.js.map +1 -0
  56. package/dist/context/entity-inbox.d.ts +63 -0
  57. package/dist/context/entity-inbox.d.ts.map +1 -0
  58. package/dist/context/entity-inbox.js +387 -0
  59. package/dist/context/entity-inbox.js.map +1 -0
  60. package/dist/context/local-inbox-handoff.d.ts +248 -0
  61. package/dist/context/local-inbox-handoff.d.ts.map +1 -0
  62. package/dist/context/local-inbox-handoff.js +340 -0
  63. package/dist/context/local-inbox-handoff.js.map +1 -0
  64. package/dist/context/projection-handoff.d.ts +46 -0
  65. package/dist/context/projection-handoff.d.ts.map +1 -0
  66. package/dist/context/projection-handoff.js +177 -0
  67. package/dist/context/projection-handoff.js.map +1 -0
  68. package/dist/context/tenant-index.d.ts +41 -0
  69. package/dist/context/tenant-index.d.ts.map +1 -0
  70. package/dist/context/tenant-index.js +93 -0
  71. package/dist/context/tenant-index.js.map +1 -0
  72. package/dist/delivery/conditional-pickup.d.ts +25 -0
  73. package/dist/delivery/conditional-pickup.d.ts.map +1 -0
  74. package/dist/delivery/conditional-pickup.js +26 -0
  75. package/dist/delivery/conditional-pickup.js.map +1 -0
  76. package/dist/delivery/delivery-builder.d.ts +216 -0
  77. package/dist/delivery/delivery-builder.d.ts.map +1 -0
  78. package/dist/delivery/delivery-builder.js +323 -0
  79. package/dist/delivery/delivery-builder.js.map +1 -0
  80. package/dist/delivery/delivery-lease.d.ts +15 -0
  81. package/dist/delivery/delivery-lease.d.ts.map +1 -0
  82. package/dist/delivery/delivery-lease.js +44 -0
  83. package/dist/delivery/delivery-lease.js.map +1 -0
  84. package/dist/delivery/delivery-loop.d.ts +113 -0
  85. package/dist/delivery/delivery-loop.d.ts.map +1 -0
  86. package/dist/delivery/delivery-loop.js +119 -0
  87. package/dist/delivery/delivery-loop.js.map +1 -0
  88. package/dist/delivery/delivery-monitor.d.ts +165 -0
  89. package/dist/delivery/delivery-monitor.d.ts.map +1 -0
  90. package/dist/delivery/delivery-monitor.js +168 -0
  91. package/dist/delivery/delivery-monitor.js.map +1 -0
  92. package/dist/delivery/delivery-ports.d.ts +151 -0
  93. package/dist/delivery/delivery-ports.d.ts.map +1 -0
  94. package/dist/delivery/delivery-ports.js +15 -0
  95. package/dist/delivery/delivery-ports.js.map +1 -0
  96. package/dist/delivery/delivery-run-control.d.ts +50 -0
  97. package/dist/delivery/delivery-run-control.d.ts.map +1 -0
  98. package/dist/delivery/delivery-run-control.js +66 -0
  99. package/dist/delivery/delivery-run-control.js.map +1 -0
  100. package/dist/delivery/delivery-run-coordinator.d.ts +218 -0
  101. package/dist/delivery/delivery-run-coordinator.d.ts.map +1 -0
  102. package/dist/delivery/delivery-run-coordinator.js +609 -0
  103. package/dist/delivery/delivery-run-coordinator.js.map +1 -0
  104. package/dist/delivery/delivery-storage-error.d.ts +13 -0
  105. package/dist/delivery/delivery-storage-error.d.ts.map +1 -0
  106. package/dist/delivery/delivery-storage-error.js +30 -0
  107. package/dist/delivery/delivery-storage-error.js.map +1 -0
  108. package/dist/delivery/delivery-supervisor.d.ts +175 -0
  109. package/dist/delivery/delivery-supervisor.d.ts.map +1 -0
  110. package/dist/delivery/delivery-supervisor.js +469 -0
  111. package/dist/delivery/delivery-supervisor.js.map +1 -0
  112. package/dist/delivery/delivery-worker.d.ts +180 -0
  113. package/dist/delivery/delivery-worker.d.ts.map +1 -0
  114. package/dist/delivery/delivery-worker.js +232 -0
  115. package/dist/delivery/delivery-worker.js.map +1 -0
  116. package/dist/delivery/delivery.d.ts +236 -0
  117. package/dist/delivery/delivery.d.ts.map +1 -0
  118. package/dist/delivery/delivery.js +539 -0
  119. package/dist/delivery/delivery.js.map +1 -0
  120. package/dist/delivery/inbox-records.d.ts +19 -0
  121. package/dist/delivery/inbox-records.d.ts.map +1 -0
  122. package/dist/delivery/inbox-records.js +291 -0
  123. package/dist/delivery/inbox-records.js.map +1 -0
  124. package/dist/delivery/inbox-storage.d.ts +83 -0
  125. package/dist/delivery/inbox-storage.d.ts.map +1 -0
  126. package/dist/delivery/inbox-storage.js +336 -0
  127. package/dist/delivery/inbox-storage.js.map +1 -0
  128. package/dist/delivery/inbox.d.ts +272 -0
  129. package/dist/delivery/inbox.d.ts.map +1 -0
  130. package/dist/delivery/inbox.js +183 -0
  131. package/dist/delivery/inbox.js.map +1 -0
  132. package/dist/delivery/parked-delivery-obligations.d.ts +182 -0
  133. package/dist/delivery/parked-delivery-obligations.d.ts.map +1 -0
  134. package/dist/delivery/parked-delivery-obligations.js +390 -0
  135. package/dist/delivery/parked-delivery-obligations.js.map +1 -0
  136. package/dist/delivery/shard-index.d.ts +41 -0
  137. package/dist/delivery/shard-index.d.ts.map +1 -0
  138. package/dist/delivery/shard-index.js +67 -0
  139. package/dist/delivery/shard-index.js.map +1 -0
  140. package/dist/delivery/sharded-work-registry.d.ts +114 -0
  141. package/dist/delivery/sharded-work-registry.d.ts.map +1 -0
  142. package/dist/delivery/sharded-work-registry.js +361 -0
  143. package/dist/delivery/sharded-work-registry.js.map +1 -0
  144. package/dist/entity/entity-metadata.d.ts +173 -0
  145. package/dist/entity/entity-metadata.d.ts.map +1 -0
  146. package/dist/entity/entity-metadata.js +187 -0
  147. package/dist/entity/entity-metadata.js.map +1 -0
  148. package/dist/entity/entity-storage-descriptor.d.ts +64 -0
  149. package/dist/entity/entity-storage-descriptor.d.ts.map +1 -0
  150. package/dist/entity/entity-storage-descriptor.js +227 -0
  151. package/dist/entity/entity-storage-descriptor.js.map +1 -0
  152. package/dist/entity/entity-transaction.d.ts +372 -0
  153. package/dist/entity/entity-transaction.d.ts.map +1 -0
  154. package/dist/entity/entity-transaction.js +413 -0
  155. package/dist/entity/entity-transaction.js.map +1 -0
  156. package/dist/entity/entity-transition-validation.d.ts +47 -0
  157. package/dist/entity/entity-transition-validation.d.ts.map +1 -0
  158. package/dist/entity/entity-transition-validation.js +327 -0
  159. package/dist/entity/entity-transition-validation.js.map +1 -0
  160. package/dist/entity/entity.d.ts +605 -0
  161. package/dist/entity/entity.d.ts.map +1 -0
  162. package/dist/entity/entity.js +981 -0
  163. package/dist/entity/entity.js.map +1 -0
  164. package/dist/entity/implicit-required-id.d.ts +15 -0
  165. package/dist/entity/implicit-required-id.d.ts.map +1 -0
  166. package/dist/entity/implicit-required-id.js +123 -0
  167. package/dist/entity/implicit-required-id.js.map +1 -0
  168. package/dist/entity/spec-scanner.d.ts +14 -0
  169. package/dist/entity/spec-scanner.d.ts.map +1 -0
  170. package/dist/entity/spec-scanner.js +37 -0
  171. package/dist/entity/spec-scanner.js.map +1 -0
  172. package/dist/handler/command-registration-readiness.d.ts +99 -0
  173. package/dist/handler/command-registration-readiness.d.ts.map +1 -0
  174. package/dist/handler/command-registration-readiness.js +120 -0
  175. package/dist/handler/command-registration-readiness.js.map +1 -0
  176. package/dist/handler/declared-rejections.d.ts +11 -0
  177. package/dist/handler/declared-rejections.d.ts.map +1 -0
  178. package/dist/handler/declared-rejections.js +34 -0
  179. package/dist/handler/declared-rejections.js.map +1 -0
  180. package/dist/handler/event-handler-filter.d.ts +43 -0
  181. package/dist/handler/event-handler-filter.d.ts.map +1 -0
  182. package/dist/handler/event-handler-filter.js +128 -0
  183. package/dist/handler/event-handler-filter.js.map +1 -0
  184. package/dist/handler/event-registration-readiness.d.ts +196 -0
  185. package/dist/handler/event-registration-readiness.d.ts.map +1 -0
  186. package/dist/handler/event-registration-readiness.js +187 -0
  187. package/dist/handler/event-registration-readiness.js.map +1 -0
  188. package/dist/handler/external.d.ts +10 -0
  189. package/dist/handler/external.d.ts.map +1 -0
  190. package/dist/handler/external.js +15 -0
  191. package/dist/handler/external.js.map +1 -0
  192. package/dist/handler/generated-handler-registry.d.ts +185 -0
  193. package/dist/handler/generated-handler-registry.d.ts.map +1 -0
  194. package/dist/handler/generated-handler-registry.js +439 -0
  195. package/dist/handler/generated-handler-registry.js.map +1 -0
  196. package/dist/handler/generated-registry-discovery.d.ts +94 -0
  197. package/dist/handler/generated-registry-discovery.d.ts.map +1 -0
  198. package/dist/handler/generated-registry-discovery.js +226 -0
  199. package/dist/handler/generated-registry-discovery.js.map +1 -0
  200. package/dist/handler/handler-decorators.d.ts +151 -0
  201. package/dist/handler/handler-decorators.d.ts.map +1 -0
  202. package/dist/handler/handler-decorators.js +275 -0
  203. package/dist/handler/handler-decorators.js.map +1 -0
  204. package/dist/handler/handler-metadata.d.ts +553 -0
  205. package/dist/handler/handler-metadata.d.ts.map +1 -0
  206. package/dist/handler/handler-metadata.js +437 -0
  207. package/dist/handler/handler-metadata.js.map +1 -0
  208. package/dist/handler/registration-readiness-metadata.d.ts +68 -0
  209. package/dist/handler/registration-readiness-metadata.d.ts.map +1 -0
  210. package/dist/handler/registration-readiness-metadata.js +171 -0
  211. package/dist/handler/registration-readiness-metadata.js.map +1 -0
  212. package/dist/handler/rejection-source.d.ts +11 -0
  213. package/dist/handler/rejection-source.d.ts.map +1 -0
  214. package/dist/handler/rejection-source.js +25 -0
  215. package/dist/handler/rejection-source.js.map +1 -0
  216. package/dist/handler/standalone.d.ts +25 -0
  217. package/dist/handler/standalone.d.ts.map +1 -0
  218. package/dist/handler/standalone.js +38 -0
  219. package/dist/handler/standalone.js.map +1 -0
  220. package/dist/index.d.ts +46 -0
  221. package/dist/index.d.ts.map +1 -0
  222. package/dist/index.js +54 -0
  223. package/dist/index.js.map +1 -0
  224. package/dist/integration/external-messages.d.ts +49 -0
  225. package/dist/integration/external-messages.d.ts.map +1 -0
  226. package/dist/integration/external-messages.js +112 -0
  227. package/dist/integration/external-messages.js.map +1 -0
  228. package/dist/integration/integration-broker.d.ts +74 -0
  229. package/dist/integration/integration-broker.d.ts.map +1 -0
  230. package/dist/integration/integration-broker.js +444 -0
  231. package/dist/integration/integration-broker.js.map +1 -0
  232. package/dist/integration/third-party-context.d.ts +56 -0
  233. package/dist/integration/third-party-context.d.ts.map +1 -0
  234. package/dist/integration/third-party-context.js +130 -0
  235. package/dist/integration/third-party-context.js.map +1 -0
  236. package/dist/repository/command-errors.d.ts +25 -0
  237. package/dist/repository/command-errors.d.ts.map +1 -0
  238. package/dist/repository/command-errors.js +43 -0
  239. package/dist/repository/command-errors.js.map +1 -0
  240. package/dist/repository/command-routing.d.ts +72 -0
  241. package/dist/repository/command-routing.d.ts.map +1 -0
  242. package/dist/repository/command-routing.js +98 -0
  243. package/dist/repository/command-routing.js.map +1 -0
  244. package/dist/repository/commit-fence.d.ts +22 -0
  245. package/dist/repository/commit-fence.d.ts.map +1 -0
  246. package/dist/repository/commit-fence.js +37 -0
  247. package/dist/repository/commit-fence.js.map +1 -0
  248. package/dist/repository/event-routing.d.ts +71 -0
  249. package/dist/repository/event-routing.d.ts.map +1 -0
  250. package/dist/repository/event-routing.js +96 -0
  251. package/dist/repository/event-routing.js.map +1 -0
  252. package/dist/repository/primitive-id.d.ts +75 -0
  253. package/dist/repository/primitive-id.d.ts.map +1 -0
  254. package/dist/repository/primitive-id.js +85 -0
  255. package/dist/repository/primitive-id.js.map +1 -0
  256. package/dist/repository/repository.d.ts +667 -0
  257. package/dist/repository/repository.d.ts.map +1 -0
  258. package/dist/repository/repository.js +3510 -0
  259. package/dist/repository/repository.js.map +1 -0
  260. package/dist/repository/routing-declarations.d.ts +75 -0
  261. package/dist/repository/routing-declarations.d.ts.map +1 -0
  262. package/dist/repository/routing-declarations.js +101 -0
  263. package/dist/repository/routing-declarations.js.map +1 -0
  264. package/dist/repository/state-update-routing.d.ts +66 -0
  265. package/dist/repository/state-update-routing.d.ts.map +1 -0
  266. package/dist/repository/state-update-routing.js +91 -0
  267. package/dist/repository/state-update-routing.js.map +1 -0
  268. package/dist/runtime/runtime.d.ts +156 -0
  269. package/dist/runtime/runtime.d.ts.map +1 -0
  270. package/dist/runtime/runtime.js +215 -0
  271. package/dist/runtime/runtime.js.map +1 -0
  272. package/dist/runtime/signal-intake.d.ts +84 -0
  273. package/dist/runtime/signal-intake.d.ts.map +1 -0
  274. package/dist/runtime/signal-intake.js +94 -0
  275. package/dist/runtime/signal-intake.js.map +1 -0
  276. package/dist/runtime/signal-metadata.d.ts +217 -0
  277. package/dist/runtime/signal-metadata.d.ts.map +1 -0
  278. package/dist/runtime/signal-metadata.js +333 -0
  279. package/dist/runtime/signal-metadata.js.map +1 -0
  280. package/dist/runtime/signal-publisher.d.ts +144 -0
  281. package/dist/runtime/signal-publisher.d.ts.map +1 -0
  282. package/dist/runtime/signal-publisher.js +248 -0
  283. package/dist/runtime/signal-publisher.js.map +1 -0
  284. package/dist/runtime/standalone-handler-runtime.d.ts +114 -0
  285. package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -0
  286. package/dist/runtime/standalone-handler-runtime.js +307 -0
  287. package/dist/runtime/standalone-handler-runtime.js.map +1 -0
  288. package/dist/server/environment-attachment.d.ts +356 -0
  289. package/dist/server/environment-attachment.d.ts.map +1 -0
  290. package/dist/server/environment-attachment.js +2062 -0
  291. package/dist/server/environment-attachment.js.map +1 -0
  292. package/dist/server/environment-delivery-records.d.ts +77 -0
  293. package/dist/server/environment-delivery-records.d.ts.map +1 -0
  294. package/dist/server/environment-delivery-records.js +282 -0
  295. package/dist/server/environment-delivery-records.js.map +1 -0
  296. package/dist/server/environment-delivery-worker.d.ts +161 -0
  297. package/dist/server/environment-delivery-worker.d.ts.map +1 -0
  298. package/dist/server/environment-delivery-worker.js +673 -0
  299. package/dist/server/environment-delivery-worker.js.map +1 -0
  300. package/dist/server/environment.d.ts +43 -0
  301. package/dist/server/environment.d.ts.map +1 -0
  302. package/dist/server/environment.js +90 -0
  303. package/dist/server/environment.js.map +1 -0
  304. package/dist/server/managed-child-subscription.d.ts +11 -0
  305. package/dist/server/managed-child-subscription.d.ts.map +1 -0
  306. package/dist/server/managed-child-subscription.js +44 -0
  307. package/dist/server/managed-child-subscription.js.map +1 -0
  308. package/dist/server/managed-server-application.d.ts +327 -0
  309. package/dist/server/managed-server-application.d.ts.map +1 -0
  310. package/dist/server/managed-server-application.js +937 -0
  311. package/dist/server/managed-server-application.js.map +1 -0
  312. package/dist/server/node-coordinator.d.ts +191 -0
  313. package/dist/server/node-coordinator.d.ts.map +1 -0
  314. package/dist/server/node-coordinator.js +552 -0
  315. package/dist/server/node-coordinator.js.map +1 -0
  316. package/dist/server/process-server-coordinator.d.ts +15 -0
  317. package/dist/server/process-server-coordinator.d.ts.map +1 -0
  318. package/dist/server/process-server-coordinator.js +112 -0
  319. package/dist/server/process-server-coordinator.js.map +1 -0
  320. package/dist/server/reserved-spine-rpc-paths.json +8 -0
  321. package/dist/server/retryable-close.d.ts +28 -0
  322. package/dist/server/retryable-close.d.ts.map +1 -0
  323. package/dist/server/retryable-close.js +129 -0
  324. package/dist/server/retryable-close.js.map +1 -0
  325. package/dist/server/server-environment.d.ts +180 -0
  326. package/dist/server/server-environment.d.ts.map +1 -0
  327. package/dist/server/server-environment.js +418 -0
  328. package/dist/server/server-environment.js.map +1 -0
  329. package/dist/server/server-log.d.ts +18 -0
  330. package/dist/server/server-log.d.ts.map +1 -0
  331. package/dist/server/server-log.js +100 -0
  332. package/dist/server/server-log.js.map +1 -0
  333. package/dist/server/server.d.ts +221 -0
  334. package/dist/server/server.d.ts.map +1 -0
  335. package/dist/server/server.js +704 -0
  336. package/dist/server/server.js.map +1 -0
  337. package/dist/services/query-reader.d.ts +19 -0
  338. package/dist/services/query-reader.d.ts.map +1 -0
  339. package/dist/services/query-reader.js +43 -0
  340. package/dist/services/query-reader.js.map +1 -0
  341. package/dist/services/spine-services.d.ts +88 -0
  342. package/dist/services/spine-services.d.ts.map +1 -0
  343. package/dist/services/spine-services.js +1582 -0
  344. package/dist/services/spine-services.js.map +1 -0
  345. package/dist/spi/delivery.d.ts +5 -0
  346. package/dist/spi/delivery.d.ts.map +1 -0
  347. package/dist/spi/delivery.js +18 -0
  348. package/dist/spi/delivery.js.map +1 -0
  349. package/dist/spi/handler-registry.d.ts +8 -0
  350. package/dist/spi/handler-registry.d.ts.map +1 -0
  351. package/dist/spi/handler-registry.js +15 -0
  352. package/dist/spi/handler-registry.js.map +1 -0
  353. package/dist/stand/stand.d.ts +294 -0
  354. package/dist/stand/stand.d.ts.map +1 -0
  355. package/dist/stand/stand.js +681 -0
  356. package/dist/stand/stand.js.map +1 -0
  357. package/dist/stand/subscription-observer.d.ts +53 -0
  358. package/dist/stand/subscription-observer.d.ts.map +1 -0
  359. package/dist/stand/subscription-observer.js +444 -0
  360. package/dist/stand/subscription-observer.js.map +1 -0
  361. package/dist/stand/subscription-records.d.ts +12 -0
  362. package/dist/stand/subscription-records.d.ts.map +1 -0
  363. package/dist/stand/subscription-records.js +99 -0
  364. package/dist/stand/subscription-records.js.map +1 -0
  365. package/dist/stand/subscription-registry.d.ts +285 -0
  366. package/dist/stand/subscription-registry.d.ts.map +1 -0
  367. package/dist/stand/subscription-registry.js +403 -0
  368. package/dist/stand/subscription-registry.js.map +1 -0
  369. package/dist/stand/subscription-runtime.d.ts +102 -0
  370. package/dist/stand/subscription-runtime.d.ts.map +1 -0
  371. package/dist/stand/subscription-runtime.js +380 -0
  372. package/dist/stand/subscription-runtime.js.map +1 -0
  373. package/dist/testing/index.d.ts +36 -0
  374. package/dist/testing/index.d.ts.map +1 -0
  375. package/dist/testing/index.js +54 -0
  376. package/dist/testing/index.js.map +1 -0
  377. package/dist/tsconfig.tsbuildinfo +1 -0
  378. package/package.json +76 -0
package/REFERENCE.md ADDED
@@ -0,0 +1,760 @@
1
+ # @spine-event-engine/server reference
2
+
3
+ This reference describes the public server contracts for coding agents.
4
+
5
+ ## Testing entry point
6
+
7
+ `@spine-event-engine/server/testing` is for framework-package tests and controlled
8
+ in-process fixtures. It exposes test reset and integration-frame helpers; managed-host
9
+ internals remain repository-only fixture code. This entrypoint is deliberately outside
10
+ the end-user root API and may change with test infrastructure rather than normal server
11
+ compatibility guarantees.
12
+
13
+ ## Delivery SPI
14
+
15
+ Delivery adapters import `conditionalPickUp` from
16
+ `@spine-event-engine/server/spi/delivery`. It registers or looks up an optional
17
+ conditional-pickup capability for a `DeliveryWorkRegistry`; it is not part of
18
+ the server root API and does not independently create delivery work.
19
+
20
+ ## Generated handler-registry SPI
21
+
22
+ Generated model modules import only their registry data types from
23
+ `@spine-event-engine/server/spi/handler-registry`. The stable contract is the
24
+ unversioned `GeneratedHandlerRegistry` receiver collection, receiver records,
25
+ handler records, kinds, arity, and optional `where` data. The subpath has no
26
+ runtime values. Server-side ingestion, validation errors, and their error codes
27
+ are implementation details; generated code must not depend on them. Retired
28
+ versioned registries are rejected and must be regenerated.
29
+
30
+ ## Standalone handlers
31
+
32
+ Generated standalone handlers extend `AbstractAssignee`, `AbstractCommander`,
33
+ `AbstractEventReactor`, or `AbstractEventSubscriber`. Register instances with
34
+ `addAssignee()`, `addCommandDispatcher()`, or `addEventDispatcher()` as their
35
+ role requires, then use `buildAsync()` to load generated receiver metadata and
36
+ match the exact constructor. Assignees consume Commands and produce Events;
37
+ commanders consume Commands, Events, or rejections and produce Commands;
38
+ reactors consume Events or rejections and may produce Events; subscribers
39
+ consume Events, rejections, or Entity states and produce no signal. State
40
+ subscribers use the System Event Bus. Produced signals are published in-process
41
+ on a best-effort basis; this is not an exactly-once contract.
42
+
43
+ ## Integration broker and event origin
44
+
45
+ Each `BoundedContext` creates and closes exactly one private integration broker.
46
+ The broker has distinct status, configuration, and event exchanges. Event
47
+ export is requested-only: a context installs a domestic publisher only for
48
+ event types requested by another context, and withdrawal removes only that
49
+ requester's interest. The broker does not enforce ownership; the supported
50
+ shape is many consumers and one domain producer per event type at a time.
51
+
52
+ The status exchange announces `BoundedContextOnline`; observing a foreign
53
+ announcement resends the local complete wanted-event document. The
54
+ configuration exchange treats each `ExternalEventsWanted` as a complete
55
+ replacement, installs producer publication on the first requester, avoids
56
+ duplicate unchanged broadcasts, and removes publication after the last
57
+ withdrawal. The event exchange uses one logical channel per event message type
58
+ and retains the original Event ID and complete Event. Self-origin and paired
59
+ domain/System Context messages are ignored.
60
+
61
+ `External<T>` is exported as a transparent type alias (`type External<T> = T`)
62
+ and has no runtime value or brand. The build-time handler analyzer recognizes
63
+ the canonical server declaration only when it is the direct first receptor
64
+ parameter. Missing markers mean `domestic`; a valid marker means `external`.
65
+ External commands are rejected, while external event/rejection handlers and
66
+ the supported state-subscription path are filtered by `EventContext.external`.
67
+ Repository selection applies the filter per handler, including mixed-origin
68
+ repositories. This is also the loop rule: domestic publication and origin
69
+ filtering prevent self-origin and paired-context traffic; no hop count, origin
70
+ ledger, Inbox, retry, replay, deduplication, cursor, fencing, or election is
71
+ added.
72
+
73
+ Incoming broker frames must contain a valid `ExternalMessage` wrapper and a
74
+ complete `Event`. The server unpacks and validates the event, obtains the
75
+ tenant from its explicit event origin, validates that tenant at the existing
76
+ boundary, copies only `EventContext.external = true`, and posts the ordinary
77
+ domain `EventBus`, whose admitted schemas are the destination's authority for
78
+ incoming payload decoding. Unknown or malformed received payloads are logged safely,
79
+ dropped, and do not stop the broker loop. Zero-byte control messages are valid
80
+ where the Proto contract permits an empty payload.
81
+
82
+ Malformed, unknown-schema, or undecodable received events emit the fixed ERROR
83
+ message `Dropped corrupt external event.` with safe `contextName`, `eventType`,
84
+ `operation: external-event-intake`, and
85
+ `reasonCode: corrupt_external_event`; the callback resolves, the event is
86
+ dropped, and later valid events continue. Application intake failures after a
87
+ valid decode remain observable.
88
+
89
+ Context readiness includes broker open. Close gates new EventBus intake before
90
+ awaiting transport work, broadcasts an empty wanted document, detaches domestic
91
+ publishers and external subscribers, drains accepted work, and closes acquired
92
+ channels. Failed cleanup remains retryable and concurrent close callers share
93
+ one attempt.
94
+
95
+ `ThirdPartyContext` is the sole public third-party import API. Its
96
+ `singleTenant()` form forbids an actor tenant; `multitenant()` requires one.
97
+ `emittedEvent(event, actor)` accepts a registered generated Protobuf message used as an event
98
+ payload and `ActorContext` (or a
99
+ `UserId` in the single-tenant form), preserves actor identity and timestamp,
100
+ and publishes through its hidden context. An unknown local schema throws; a
101
+ valid event with no interested external receptor is simply not delivered.
102
+
103
+ ## Server environment facilities
104
+
105
+ `ServerEnvironment.instance()` is a process-wide singleton. Production
106
+ resolution requires storage and the complete application schema registry:
107
+
108
+ ```ts
109
+ import { EnvironmentType, ServerEnvironment } from "@spine-event-engine/server";
110
+ import type { TypeRegistryLookup } from "@spine-event-engine/core";
111
+ import type { StorageFactory } from "@spine-event-engine/storage";
112
+
113
+ declare const storageFactory: StorageFactory;
114
+ declare const typeRegistry: TypeRegistryLookup;
115
+
116
+ ServerEnvironment.when(EnvironmentType.Production).use({
117
+ storageFactory,
118
+ typeRegistry,
119
+ });
120
+ ```
121
+
122
+ `storageFactory` supplies records and events. `typeRegistry` is the complete
123
+ application schema universe used by `ThirdPartyContext` to encode outgoing
124
+ imported events. An optional `integrationChannelFactory` overrides the
125
+ process-wide private
126
+ integration message channel factory. When it is absent, all local bounded
127
+ contexts share one in-memory factory, including in production. Local and test
128
+ environments default storage in memory and use the core registry only as a
129
+ fallback; those defaults are not production configuration.
130
+
131
+ To override the default channel factory, add
132
+ `integrationChannelFactory: customFactory` to the same settings object.
133
+
134
+ ## Routing lifecycle
135
+
136
+ Event, command, and state-update routing accepts exact schemas and nominal
137
+ message-interface tokens. It selects exact, first registered matching token,
138
+ then replacement/default. The route runs once at accepted admission; its
139
+ validated typed targets are stored and reused for retries. The legacy-named
140
+ local `catchUpReadSide()` helper is unrelated to retry: it resets and replays
141
+ the whole local read side, and is not Projection catch-up.
142
+
143
+ ## Message-valued Entity IDs
144
+
145
+ The first state field determines the Entity ID type. It can be a primitive or
146
+ a generated Protobuf message; for a message ID, all declared fields form the
147
+ identifier. Nested and composite IDs are supported.
148
+
149
+ ```proto
150
+ message ShipmentId {
151
+ spine.core.UserId owner = 1;
152
+ int32 number = 2;
153
+ }
154
+
155
+ message Shipment {
156
+ ShipmentId id = 1;
157
+ string status = 2;
158
+ }
159
+ ```
160
+
161
+ The root `MessageId` type accepts generated messages such as `CommandId`:
162
+
163
+ ```ts
164
+ import { create } from "@bufbuild/protobuf";
165
+ import { type MessageId } from "@spine-event-engine/server";
166
+ import { CommandIdSchema } from "@spine-event-engine/proto";
167
+
168
+ const id: MessageId = create(CommandIdSchema, { uuid: "shipment-7" });
169
+ ```
170
+
171
+ Admission validates a message ID against the schema declared by the state
172
+ field, including generated validation rules, before it is stored or replayed.
173
+ When default routing finds a message but the Entity ID type is primitive, a
174
+ custom route returns the intended primitive ID.
175
+
176
+ Without a custom route, Command routing uses the Command's declared first
177
+ field. Event routing uses a compatible producer ID when available and otherwise
178
+ uses the Event's declared first field. State-update routing selects the first
179
+ state field compatible with the Entity ID.
180
+
181
+ ## Handler routing and operations
182
+
183
+ Generated handler metadata routes a command, event, or state update by its
184
+ exact generated message type. A declared default route is considered only when
185
+ there is no exact route. This is TypeScript routing; it does not consume
186
+ `(is).java_type` or `(every_is).java_type`, and it has no decorator-based
187
+ route registration API.
188
+
189
+ Handlers may return their established result directly or through exactly one built-in `Promise<T>`.
190
+ Nested promises and structural or imported thenable lookalikes are rejected during handler analysis.
191
+ The entity transaction remains open until that promise settles; rejection rolls
192
+ back framework state and suppresses produced output, but cannot undo external
193
+ side effects. Process Managers may use their protected read-only query surface
194
+ for eventually consistent projection state during a handler. Aggregates must
195
+ not use projection reads for invariants.
196
+
197
+ `select(schema, columns)` supports `byId`, typed `where`, `mask`, `orderBy`,
198
+ `limit`, `read`, `findById`, and `all`. A Process Manager query returns at most
199
+ 1,000 states. `all()` is a convenience and can be costly on a large Projection;
200
+ prefer an ID-targeted or ordered bounded query.
201
+
202
+ Use `EntityQuery.all(...)` to require every predicate and `EntityQuery.either(...)`
203
+ to accept any branch. Query execution inherits the active handler's actor and
204
+ tenant; the protected read-only facade has no tenant override.
205
+
206
+ ```ts
207
+ import type { Message } from "@bufbuild/protobuf";
208
+ import type { GenMessage } from "@bufbuild/protobuf/codegenv2";
209
+ import { EntityQuery, type EntityColumn } from "@spine-event-engine/core";
210
+ import { ProcessManager } from "@spine-event-engine/server";
211
+
212
+ type RequestView = Message<"RequestView"> & {
213
+ id: string;
214
+ status: string;
215
+ createdAt: number;
216
+ };
217
+
218
+ declare const RequestViewSchema: GenMessage<RequestView>;
219
+ declare const RequestViewColumns: {
220
+ readonly status: EntityColumn<typeof RequestViewSchema, "status", string, "equal">;
221
+ readonly createdAt: EntityColumn<
222
+ typeof RequestViewSchema,
223
+ "createdAt",
224
+ number,
225
+ "equal" | "greaterThan"
226
+ >;
227
+ };
228
+
229
+ abstract class RequestCoordinator extends ProcessManager<string, typeof RequestViewSchema> {
230
+ protected async pendingRequests(requestId: string): Promise<void> {
231
+ const matching = await this.select(RequestViewSchema, RequestViewColumns)
232
+ .where(EntityQuery.eq(RequestViewColumns.status, "pending"))
233
+ .orderBy(RequestViewColumns.createdAt, "asc")
234
+ .limit(10)
235
+ .read();
236
+ const one = await this.select(RequestViewSchema, RequestViewColumns).findById(requestId);
237
+ const everyVisible = await this.select(RequestViewSchema, RequestViewColumns).all();
238
+ void [matching, one, everyVisible];
239
+ }
240
+ }
241
+ ```
242
+
243
+ `all()` remains capped at 1,000 states but may still be costly; use `findById()`
244
+ or an ordered bounded `read()` where possible.
245
+
246
+ A command-input `@Command` method is a command substitution receptor: it is
247
+ the one effective receptor for that Command type (instead of an `@Assign`),
248
+ commits its Entity state before its one-or-more returned Commands are detached
249
+ for in-process produced-command enqueue, and receives an optional `CommandContext`.
250
+ Only Process Manager repositories support `@Command` handlers. Aggregate and
251
+ Projection repositories reject command-input substitutions and event- or
252
+ rejection-input command reactions during generated metadata ingestion and
253
+ repository construction.
254
+ Event- and rejection-input `@Command` methods remain Event- or
255
+ rejection-to-command reactions on Event Bus.
256
+ Produced commands retain the source actor, tenant, origin, and causal lineage.
257
+ The enqueue is post-commit best effort, not an atomic outbox or exactly-once
258
+ delivery: a process crash between commit and enqueue can lose a child. Accepted
259
+ produced commands drain during context close. A contained child failure is diagnosed,
260
+ but does not retroactively fail an already accepted source command or durably
261
+ retry that child.
262
+
263
+ For a generated Process Manager, a command-input handler uses distinct domain
264
+ Command input and output types, and the generated registry supplies those
265
+ schemas. This self-contained example explicitly ingests the unversioned data that an
266
+ application build normally emits, then assembles a repository from it; it does
267
+ not claim that its fixture discovers a registry artifact automatically:
268
+
269
+ <!-- docs-snippet-path: packages/server-blackbox-tests/test/project-event-routing.test.ts -->
270
+
271
+ ```ts
272
+ import { create } from "@bufbuild/protobuf";
273
+ import { SignalEnvelopes } from "@spine-event-engine/core";
274
+ import {
275
+ CommandContextSchema,
276
+ CommandIdSchema,
277
+ type CommandContext,
278
+ } from "@spine-event-engine/proto";
279
+ import {
280
+ BoundedContext,
281
+ Command,
282
+ type EntityHandlersMetadata,
283
+ HandlerRegistryIngestor,
284
+ ProcessManager,
285
+ Repository,
286
+ } from "@spine-event-engine/server";
287
+ import type { GeneratedHandlerRegistry } from "@spine-event-engine/server/spi/handler-registry";
288
+
289
+ import {
290
+ ApproveProjectSchema,
291
+ ScheduleProjectSchema,
292
+ type ApproveProject,
293
+ type ScheduleProject,
294
+ } from "../generated/spine/server/testing/project_commands_pb.js";
295
+ import {
296
+ CoordinationStateSchema,
297
+ OrganizationIdSchema,
298
+ ProjectIdSchema,
299
+ type ProjectId,
300
+ } from "../generated/spine/server/testing/project_workflow_pb.js";
301
+
302
+ class ApprovalCoordinator extends ProcessManager<
303
+ ProjectId,
304
+ typeof CoordinationStateSchema,
305
+ number
306
+ > {
307
+ @Command
308
+ approve(command: ApproveProject, context: CommandContext): ScheduleProject {
309
+ this.update((draft) => Object.assign(draft, { id: this.id, projectName: command.status }));
310
+ return create(ScheduleProjectSchema, { project: command.project, status: command.status });
311
+ }
312
+ }
313
+
314
+ const project = create(ProjectIdSchema, {
315
+ organization: create(OrganizationIdSchema, { code: "org-a" }),
316
+ number: 1,
317
+ });
318
+ const registry: GeneratedHandlerRegistry = {
319
+ receivers: [
320
+ {
321
+ receiverKind: "entity",
322
+ receiverType: ApprovalCoordinator,
323
+ stateSchema: CoordinationStateSchema,
324
+ handlers: [
325
+ {
326
+ kind: "command-substitution",
327
+ methodName: "approve",
328
+ input: { schema: ApproveProjectSchema, origin: "domestic" },
329
+ outcomes: { returned: [ScheduleProjectSchema], thrown: [] },
330
+ parameterCount: 2,
331
+ },
332
+ ],
333
+ },
334
+ ],
335
+ };
336
+ const [handlers] = new HandlerRegistryIngestor().ingest(registry);
337
+ if (handlers === undefined) throw new Error("Generated Process Manager metadata is missing.");
338
+ const repository = new Repository({
339
+ entityType: ApprovalCoordinator,
340
+ schema: CoordinationStateSchema,
341
+ handlers: handlers as EntityHandlersMetadata<ApprovalCoordinator, typeof CoordinationStateSchema>,
342
+ });
343
+ const context = BoundedContext.singleTenant("Projects").add(repository).build();
344
+ await context.commandBus().post(
345
+ SignalEnvelopes.command({
346
+ context: create(CommandContextSchema),
347
+ schema: ApproveProjectSchema,
348
+ message: create(ApproveProjectSchema, { project, status: "approved" }),
349
+ }),
350
+ );
351
+ ```
352
+
353
+ The generated record declares `ApproveProjectSchema` as the input and
354
+ `ScheduleProjectSchema` as the emitted Command schema; registry ingestion, not
355
+ manual decorator materialization, constructs the output-bearing metadata.
356
+ Application builds emit the record to
357
+ `generated/handler/generated-handler-registry.js`; those applications use
358
+ `buildAsync()` with their compiled package root.
359
+
360
+ One `@Where({ eventField, equals })` equality filter may narrow an event- or
361
+ rejection-consuming `@Subscribe`, `@React`, or `@Command` handler after type
362
+ routing. `eventField` and `equals` are typed string literals; invalid or
363
+ repeated declarations fail closed. It is not an alternative routing mechanism.
364
+
365
+ Configure logging through `ServerEnvironment` when assembling the server. The
366
+ server installs that logger into its runtime components, where warnings and
367
+ failures carry operation context. Durable facts belong in events or storage.
368
+ Entity Inbox replay sends persisted accepted work through the normal handler
369
+ path, so handler effects must be replay-safe.
370
+
371
+ ## Context assembly and entities
372
+
373
+ Create a context with `BoundedContext.singleTenant(name)` or
374
+ `BoundedContext.multitenant(name)`. Names are immutable. Use
375
+ `withStorageFactory(factory)` to supply record/event storage.
376
+ `withGeneratedRegistryRoot(root)` enables framework discovery of the generated
377
+ handler registry for classes registered with `add(EntityClass)`;
378
+ `buildAsync()` performs that discovery and assembly. `build()` remains for
379
+ explicit `Repository` registration. A built context contains `CommandBus`,
380
+ `EventBus`, `Stand`, repositories, and its storage lifecycle.
381
+
382
+ Generated writer output is an unversioned receiver collection and records
383
+ command substitutions explicitly. The ingestor rejects retired versioned
384
+ registry shapes with an instruction to regenerate.
385
+
386
+ ### Stand subscription registry
387
+
388
+ Each built context also has one `StandSubscriptionRegistry`. By default the
389
+ builder creates a storage-backed registry from the resolved context
390
+ `StorageFactory` (including the `ServerEnvironment` factory used for a builder
391
+ added to a server). It stores one `spine.client.SubscriptionRecord` under each
392
+ explicit `SubscriptionId`. A complete custom implementation can instead be
393
+ supplied with `withSubscriptionRegistry(registry)`; responsibility transfers to
394
+ the builder on the first build attempt.
395
+
396
+ `SubscriptionService` streams are live best-effort notifications, not replay,
397
+ ordering, or completeness contracts. A standalone Server defaults to the
398
+ persistent registry. In a managed complete-replica cohort, the framework starts
399
+ and closes each child Server and accepts only every context's actual
400
+ `InMemorySubscriptionRegistry`; a persistent or custom registry is rejected
401
+ and the assembled child is closed before READY. Durable logical bindings remain
402
+ Gateway-only. The Coordinator fans each logical definition to ready children,
403
+ merges updates, propagates cancellation, and carries no subscription payload on
404
+ parent/child IPC. A late or replacement child synchronizes retained definitions
405
+ before it is eligible for normal requests. Active definitions attach their
406
+ child streams before admission; subscribed but inactive definitions do not
407
+ block readiness. Each child observes application-configured remote/shared
408
+ Delivery directly. During DRAINING, new unary and shard admission stops while
409
+ active Delivery and its subscription updates finish before child close. The
410
+ application configures the Delivery facility and selects the shard strategy;
411
+ managed mode does not infer or certify configuration provenance.
412
+
413
+ Create records begin `pending` and expire after 30 seconds unless activated.
414
+ Active records have no framework TTL. Cancellation physically deletes the
415
+ definition; no tombstone remains. A stored definition is at most 1 MiB
416
+ (1,048,576 bytes). Its physical provider columns are `status` and
417
+ `when_activation_expires`. `cleanup()` asks the provider for 26 pending rows
418
+ ordered by `when_activation_expires` then ID, validates that finite result,
419
+ deletes at most 25 expired definitions, and reports `more` only when its
420
+ observed 26th row is expired. Cleanup can run idempotently on every node.
421
+
422
+ Context close drains and closes Stand before its registry, then closes tenant,
423
+ repository, and storage resources; it attempts every close and reports
424
+ aggregate failures. An in-memory registry reports `persistent === false`.
425
+ Attaching such a context to a production `ServerEnvironment` emits one
426
+ context-name-only warning without failing startup; Local environments do not
427
+ warn.
428
+
429
+ Creation writes the pending record only when that ID is absent. Activation
430
+ replaces that pending record only when it remains unchanged. Cancellation and
431
+ expiry cleanup delete the observed record only when it remains unchanged. Each
432
+ node reconciles its local snapshot immediately after context assembly and then
433
+ every ten seconds. Physical deletion detaches the local observer after its next
434
+ completed cycle. This is best-effort per-node convergence, not a
435
+ cluster-completeness, replay, ordering, gap-repair, or exactly-once guarantee.
436
+
437
+ The registry accepts only a generated `SubscriptionId` for activate, get, and
438
+ delete. `create(subscription)` returns `{ kind: "created", entry }` or
439
+ `{ kind: "existing", entry }`; the latter requires byte-equivalent canonical
440
+ content and a different definition with the same ID throws `StandConflictError`.
441
+ `activate(id)` returns `activated`, `active`, `missing`, or `expired`.
442
+ `delete(id)` returns `deleted` or `missing`. Blank IDs or topics and malformed
443
+ durable records fail closed.
444
+
445
+ Entries and nested subscriptions returned by create, activate, get, and
446
+ snapshot are clone-safe views. Protobuf byte arrays remain mutable runtime
447
+ views but are cloned so they never alias caller storage. Snapshots are ordered
448
+ by identifier. A durable provider must implement atomic compare-and-set for
449
+ `SubscriptionRecord`; construction rejects a provider that cannot. MySQL table
450
+ configuration and Datastore custom record storage registered for
451
+ `SubscriptionRecord` are used by the registry. The registry uses one
452
+ record-storage handle, while the context closes the registry.
453
+
454
+ `Entity` is the state base class. `Aggregate`, `Projection`, and
455
+ `ProcessManager` identify the three entity families. Handler decorators are
456
+ `@Assign`, `@Command`, `@React`, `@Subscribe`, and `@Apply`. A command-accepting
457
+ handler uses `@Throws(GeneratedRejection)` to declare its possible domain
458
+ rejections. Write the primary handler decorator first and `@Throws` immediately
459
+ below it; declaration order does not affect behavior. Generated metadata records
460
+ normal and rejection outcomes before context assembly, so clients may subscribe
461
+ to a declared rejection even when no server handler consumes it. Throwing an
462
+ undeclared generated rejection is a technical handler failure. In a transactional
463
+ handler, `update(mutator)` changes the active draft and returns the draft;
464
+ `tryUpdate(mutator)` validates a scratch draft and returns violations without
465
+ applying an invalid change. Entity lifecycle and version changes are committed
466
+ only after the transaction accepts.
467
+
468
+ ## Signals, validation, and rejection behavior
469
+
470
+ `CommandBus` validates every accepted command from Proto validation options
471
+ before dispatcher or repository handler code runs. It raises the framework's
472
+ command-validation failure, which `SpineServices` maps to
473
+ `COMMAND_VALIDATION_ERROR` with a packed `spine.validation.ValidationError`.
474
+ Entity transition validation failures map to
475
+ `COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type.
476
+ Framework-created runtime command and event metadata uses fresh Node secure
477
+ UUIDs; fixed IDs belong only to existing source envelopes retained through the
478
+ normal origin chain.
479
+
480
+ An application handler throws a generated core `RejectionThrowable` for a
481
+ domain rejection declared with `@Throws`. The repository rolls back state,
482
+ version, lifecycle, and output; it schedules the typed rejection event independently. Command service
483
+ acknowledgement remains an accepted `Ack`. Rejection-event posting can be
484
+ unobserved by inactive, full, or closed subscriptions and a posting failure is
485
+ an internal diagnostic, not a retry guarantee.
486
+
487
+ Every domain context has an internal paired System Context. Domain events use
488
+ the domain `EventBus` and domain `EventStore`. System events use only the
489
+ System Context `EventBus`, so they never enter the domain EventStore. System
490
+ event persistence is optional: `persistSystemEvents()` enables the paired
491
+ System Context's separate storage; otherwise the bus validates, dispatches,
492
+ and notifies without appending. Schemas may come from an external dispatcher or
493
+ a registered internal repository producer. A producer-only schema is not
494
+ thereby an external dispatch route.
495
+
496
+ ## Services, reads, and lifecycle
497
+
498
+ `SpineServices({ contexts }).register(router)` registers the JVM-compatible
499
+ CommandService, QueryService, and SubscriptionService contracts. `Server`
500
+ opens the local Node HTTP/2 listener; default host is `127.0.0.1`. Set
501
+ `readMaxBytes` and `writeMaxBytes` only to integers 1–4294967295; defaults are 4194304. `RunningServer.close()` stops intake, closes sessions, waits for active
502
+ work to stop using dependencies, then closes contexts. Caller-managed `start()`
503
+ does not close global process facilities; close `ServerEnvironment.instance()`
504
+ separately when used. The final run-managed `run()` close closes its environment.
505
+
506
+ `Stand` registers entity state for point/list reads, updates current state, and
507
+ offers in-process subscriptions. The legacy-named local reset/replay helper
508
+ `catchUpReadSide(options?)` clears every registered Projection state and replays
509
+ the whole stored event history through matching Projection subscribers; it does
510
+ not append events. Single-tenant contexts reject a tenant option; multitenant
511
+ contexts require one. It cannot target a Projection repository, entity IDs, or
512
+ a starting time, and has no durable operation identity, progress, Inbox
513
+ catch-up delivery, restart, resumption, or historical/live coordination. It is
514
+ not JVM-equivalent Projection catch-up.
515
+
516
+ Active subscription streams and queues are process-local. `Stand` serves
517
+ authoritative queries from current state and Entity subscriptions observe
518
+ committed `EntityStateChanged` messages on the paired System Context EventBus,
519
+ so a direct Stand write alone does not produce a subscription update. Consumer
520
+ callback failures are isolated from post-commit observation and other
521
+ consumers. The package does not guarantee cluster-complete observations,
522
+ subscription replay, event-gap repair, or exactly-once effects.
523
+
524
+ ### Native and managed hosting
525
+
526
+ `Server.start()` installs no process signal handlers, never closes its
527
+ environment, and shares only a caller-managed active generation. `Server.run()`
528
+ coalesces concurrent calls on one builder, shares a run-managed generation with
529
+ other `run()` servers, and rejects mixed admission before listener open. The
530
+ coordinator uses one `SIGINT`/`SIGTERM` listener pair, closes servers in reverse
531
+ successful-start order, retains failed final environment closure for later
532
+ signal or explicit-close retry, and sets `process.exitCode` to `1` after a
533
+ signal-driven failure.
534
+
535
+ `ManagedServerApplication.run()` is the Node-only deployment entrypoint for a
536
+ complete-replica process cohort when the framework handles process shutdown.
537
+ `ManagedServerApplication.start()` starts the same cohort for an embedding host
538
+ and installs no process signal handlers; that host closes the returned handle.
539
+ Both require a positive safe-integer
540
+ `processCount` and an ESM `moduleUrl`; it never derives a process count from
541
+ the machine. Its optional `host` and required nonzero `port` bind the public
542
+ Coordinator listener. Every child executes that same module and calls the
543
+ module's `createServer({ host: "127.0.0.1", port: 0 })`. The child reports its
544
+ actual loopback endpoint only after its local readiness gates settle. The parent
545
+ initially waits until every configured child is ready. Afterwards it is ready
546
+ while at least one child is ready; it remains alive and keeps replacing while
547
+ degraded, and reports unready if no child is ready. It replaces an unexpected
548
+ child exit after a bounded exponential delay (250 ms initially, capped at 30 s;
549
+ reset after 60 s READY). It does not restart a child being closed. Restart
550
+ values are optional `restart` settings and must be positive safe integers;
551
+ concurrent starts default to `min(4, processCount)`. `run()` parent `SIGINT`
552
+ and `SIGTERM` use the same shared child-close path; `start()` leaves those
553
+ signals to its caller. This private lifecycle channel
554
+ does not transport application signals. The Coordinator forwards generated
555
+ Command and Query unary calls once to a READY child; process count does not
556
+ inspect CPU availability and does not constrain the application's independently
557
+ chosen `DeliveryStrategy` or shard count. Direct `Server.run()` and browser
558
+ hosting remain independent of managed Node deployment.
559
+
560
+ If no child is READY, Command and Query return gRPC `UNAVAILABLE`. The
561
+ Coordinator does not enter application intake and does not retry the selected
562
+ call on a sibling child. Subscription fan-out follows current READY members;
563
+ later and replacement members attach the retained subscription before managed
564
+ admission.
565
+
566
+ `ServerOptions` is native-only: it configures contexts, resources, services,
567
+ and the native listener. It has no `browser` option and the root package does
568
+ not load `@spine-event-engine/auth`. Browser hosting belongs to the explicit
569
+ `@spine-event-engine/server/browser` entry point; see the [browser/auth guide](../../docs/BROWSER_CLIENT_AUTH_EXTENSION_GUIDE.md).
570
+
571
+ Browser unary gateway admission has a fixed 1 MiB (1,048,576-byte) request
572
+ limit. A larger unary gateway request is rejected with `ResourceExhausted`.
573
+ This is an additional boundary: `readMaxBytes` still limits the Connect or
574
+ gRPC-Web transport message accepted by the public listener, so the effective
575
+ inbound limit is the stricter applicable limit. `writeMaxBytes` limits public
576
+ transport responses independently.
577
+
578
+ For `BrowserServer` from `@spine-event-engine/server/browser`, origins must be unique canonical HTTP(S) origins with no path, query,
579
+ fragment, or trailing slash. Requests without an allowed exact `Origin` receive
580
+ 403 before RPC handling. Allowed responses include credentialed exact-origin
581
+ CORS, `Vary: Origin`, protocol request headers, and exposed gRPC status headers.
582
+
583
+ Supplying `browser.backend.baseUrl` selects standalone mode. It is one canonical
584
+ HTTP(S) origin for a Spine TS or JVM backend; the gateway never closes
585
+ that backend. Every standalone mode, including local development and tests,
586
+ requires explicit subscription bindings; production additionally requires an
587
+ application type registry and named durable bindings. `ResolveContext` stays in the gateway;
588
+ Post, Read, Subscribe, Activate, and Cancel use the same authenticated policy,
589
+ context-replacement, and native descriptors before reaching the backend.
590
+
591
+ `browser.backend.baseUrls` is exclusive with `baseUrl` and configures a
592
+ non-empty ordered unique static node set. Unary calls use bounded round-robin
593
+ without retry; native streams fan out best-effort. Durable bindings retain only
594
+ logical definitions, not topology. Clients
595
+ re-query authoritative state after duplicate updates or generic loss notices.
596
+
597
+ `browser.authRoutes` is deliberately a bounded callback seam, not a router.
598
+ Each registration has one exact `GET` or `POST` canonical path, one method per
599
+ path, exact canonical origins, finite request bytes, and a finite timeout. A
600
+ missing Origin is rejected unless that route explicitly permits it for an OAuth
601
+ callback. Unknown paths, method/origin failures, body overflow, timeout, and
602
+ handler failure return fixed 404, 405, 403, 413, 504, and 500 responses without
603
+ calling application code on rejected input. The 404 unknown-path result applies
604
+ only after framework Origin admission. Auth admission is bounded to 64 active
605
+ requests by default or a configured positive `maxActiveAuthRequests`; excess
606
+ requests receive 503 before handler invocation and capacity returns when work
607
+ settles. The route deadline covers body intake, handler work, and response
608
+ transfer. Response bodies use `writeMaxBytes`; overflow returns 413 before any
609
+ application status or headers are committed. Listener close ultimately aborts
610
+ an active request through its disconnect signal.
611
+
612
+ With `cookies`, `OpaqueSessionCookies` performs strict bearer-first or
613
+ CSRF-protected cookie extraction. A strict rejection becomes an unusable
614
+ credential and never falls back to permissive header parsing. Without cookies,
615
+ the host accepts exactly one non-whitespace bearer token. Credentials and raw
616
+ transport metadata do not reach the private backend. The application-supplied
617
+ context resolver replaces caller actor and tenant facts before forwarding.
618
+
619
+ Browser close stops new listener intake, closes subscription admission and
620
+ bindings so active streams settle, awaits listener closure, then closes the
621
+ native backend. Concurrent calls share an attempt; a failed unfinished phase
622
+ can be retried without repeating completed native cleanup.
623
+
624
+ Browser subscription bindings are separate from service subscription records.
625
+ `BrowserAdmission` selects their ownership. Authenticated mode supplies
626
+ `sessions` and may supply `BrowserServerOptions.bindings`; production then
627
+ requires `DurableSubscriptionBindings` from `@spine-event-engine/server/browser` and rejects a
628
+ missing or in-memory binding store before listener open. Public mode supplies
629
+ `publicAccess: true`, cannot supply bindings, and uses process-local bindings
630
+ managed by the framework. The durable registry receives an explicit application
631
+ namespace, storage factory, identifier source, and cleanup callback. It closes
632
+ only its independently opened record-storage handle, not the application
633
+ storage factory or a Spine JVM/TS backend. It stores canonical public
634
+ Subscription definitions, never backend envelopes or membership topology, and
635
+ never returns private native data through public subscription responses.
636
+
637
+ The durable registry preserves one approved `GatewayAuthenticatedSubscription`
638
+ per public subscription through a process restart. It validates the record ID,
639
+ full Subscription, and expiry before use. The trusted Actor and Tenant remain
640
+ inside the stored Topic and are checked for Activate and Cancel. Create assigns
641
+ the public ID directly; no quota, reservation, fingerprint, or lease is
642
+ persisted. Cleanup remains bounded and restart-safe at the record level. It
643
+ cleans the backend definition before deleting its record. It is not a cleaner
644
+ lease or fence: this direct store supports one Gateway process. Active streams do not resume,
645
+ updates are not replayed, and the registry provides neither exactly-once
646
+ delivery, global update ordering, nor cluster-complete notification delivery.
647
+
648
+ ## Delivery and environment
649
+
650
+ `Inbox`, `InboxStorage`, `ShardIndex`, and `ShardedWorkRegistry` provide the
651
+ local durable-row abstraction. Read limits are 1–1000; work leases are
652
+ 1000–2147483647 ms. Framework replay supports command handling, projection
653
+ updates, and process-manager reactions. Callbacks are at-least-once/replay-safe:
654
+ lost renewal can prevent stale finalization but cannot undo a callback already
655
+ run. The package exposes no general raw worker callback API.
656
+
657
+ Shard ownership is the only delivery exclusion mechanism and excludes
658
+ concurrent delivery within that shard. Pending and delivered `InboxMessage`
659
+ rows are direct records; a delivered row is the deduplication fact. A handler
660
+ effect and the exact pending-to-delivered compare-and-set are not one
661
+ transaction, so a lost acknowledgement can redeliver after restart. Downstream
662
+ signal handling must be idempotent. A customized `DeliveryWorkRegistry`
663
+ implements `validateOwnership()` so delivery can validate before dispatch, at
664
+ repository commit time, and before acknowledgement. Validation is a fence
665
+ against an observed takeover, not a distributed transaction with handler
666
+ storage.
667
+
668
+ `keepUntil` is the optional deduplication-protection deadline, not a second
669
+ retention setting. A delivered row is cleanup-eligible when that deadline is
670
+ absent or elapsed. Under current shard ownership, environment delivery performs
671
+ one bounded cleanup page, plus at most one continuation after a full protected
672
+ page makes no removal. Direct local storage atomically verifies ownership and
673
+ the exact delivered snapshot during removal. A remote adapter may instead read
674
+ and compare the snapshot before sending a separate best-effort removal request;
675
+ that sequence is not an atomic compare-and-delete guarantee. Pending, retryable,
676
+ non-delivered, and still-protected rows remain. There is no additional retention
677
+ configuration, timer, or scheduler.
678
+
679
+ `BoundedContextBuilder.withDeliveryStrategy(strategy)` snapshots a validated
680
+ immutable strategy for its Entity Inbox; the default is one shard. For example,
681
+ use the public builder chain:
682
+
683
+ ```ts
684
+ import { BoundedContext, UniformAcrossAllShards } from "@spine-event-engine/server";
685
+
686
+ const context = BoundedContext.singleTenant("Tasks")
687
+ .withDeliveryStrategy(UniformAcrossAllShards.forNumber(3))
688
+ .build();
689
+ ```
690
+
691
+ Aggregate commands and Process Manager commands/events derive their target shard
692
+ internally and persist their envelope in the target Entity Inbox before any
693
+ handler runs. Delivery is never a post-request callback: local and remote
694
+ handler runs. Local intake can directly drain the persisted Inbox in the
695
+ current request path. Attached `ServerEnvironment` ports acknowledge admission
696
+ and delivery workers replay it through the same path. Projection rows remain
697
+ separate.
698
+
699
+ `DeliveryBuilder` constructs a controlled `Delivery`; `DeliverySupervisor`
700
+ receives `{ source, delivery, onMessage }`, manages bounded shard notifications
701
+ from that structural source, and must start after endpoints are ready and close
702
+ before source client/storage. `DeliverySource` is not configured on
703
+ `DeliveryBuilder`. The supervisor does not promise
704
+ durable supervisor state, topology failover, exactly-once effects, or automatic
705
+ retry of unknown remote mutations.
706
+
707
+ Each Inbox read is bounded to one page. That bound does not limit the total
708
+ pending work: an active drain can advance to another page while it retains the
709
+ shard. Delivery compares pending rows with delivered rows in the current page
710
+ and a process-local cache of the 1,000 most recent deliveries, then removes
711
+ duplicates. The 30-second Inbox deduplication window controls how long delivered
712
+ rows remain available as duplicate evidence; it is not a replay-retention
713
+ period. Persisted accepted rows follow their delivery lifecycle and may be
714
+ replayed according to that lifecycle after the deduplication window has elapsed.
715
+
716
+ `DeliveryMonitor` is an instantiable, customizable policy seam exposing
717
+ asynchronous continuation, start/completion, failed-reception, pickup-failure,
718
+ and already-picked hooks.
719
+ `FailedReception` supplies only `markDelivered()` and one immediate
720
+ `repeatDispatching()` action; the framework adds no attempt history, timer,
721
+ backoff, quarantine, dead-letter, receipt, marker, or scheduler policy. A failed
722
+ durable acknowledgement keeps that row pending, blocks later rows for its
723
+ target during the run, and does not prevent independent targets from running.
724
+
725
+ `Environment` resolves the Node `local` or `production` profile once from
726
+ `NODE_ENV`. `ServerEnvironment` resolves configured facilities once for that
727
+ profile and exposes its `storageFactory`, optional `delivery`, optional
728
+ `tracerFactory`, `nodeId`, and `close()` lifecycle. Applications do
729
+ not manage internal server attachments through this public API. Neither API
730
+ authenticates requests or supplies a production scheduler, remote topology,
731
+ storage adapter, or deployment policy.
732
+
733
+ `ServerEnvironmentDelivery` extends the existing closeable facility shape with
734
+ `open()` plus generic `inbox` and `workRegistry` ports. After readiness, the
735
+ environment supplies those ports to both existing delivery paths: direct finite
736
+ `Delivery` construction and the supervisor's `DeliveryBuilder`. The environment
737
+ invokes `open()` once before attachment admission and coalesces concurrent
738
+ callers; rejection admits no attachment and a later attempt retries open. A
739
+ close-only local delivery remains source-compatible. After attachments retire,
740
+ environment close runs delivery, tracer, then storage and preserves retry
741
+ checkpoints for failed phases.
742
+
743
+ `ServerEnvironmentDelivery.source` is optional. When present, its Admin source
744
+ is used by the environment supervisor for remote snapshots and
745
+ shard-update hints; when absent, the existing local source remains the fallback.
746
+ Applications configure and close only the delivery facility through the
747
+ environment: attachment supervisors and their source reads belong to that facility.
748
+
749
+ ## Signal identity and Aggregate semantics
750
+
751
+ Projection handlers cannot use `@Assign`; explicit metadata rejects that unsupported
752
+ handler shape. Framework-created child Commands and Events receive fresh IDs. Existing
753
+ Command or Event envelopes retain their IDs through transport and storage, including
754
+ when returned or passed as envelopes. Aggregate domain Events use the loaded pre-dispatch
755
+ version, while persisted Aggregate state advances to the next version. History caching accepts descending retained
756
+ versions with gaps, while continuing to reject equal or newer continuations.
757
+
758
+ # Dynamic unary discovery
759
+
760
+ `BrowserServerOptions.discovery` from `@spine-event-engine/server/browser` 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.