@zlink-systems/framework 0.29.1 → 0.30.1

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 (322) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  7. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  9. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  10. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  11. package/dist/contracts/Configuration/index.d.ts +1 -1
  12. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  13. package/dist/contracts/Handlers/Attributes.js +7 -11
  14. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  15. package/dist/contracts/Handlers/JsonContract.js +4 -153
  16. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/internal.js +3 -1
  19. package/dist/nest-integration.d.ts +1 -1
  20. package/dist/nest-integration.js +2 -1
  21. package/dist/runtime/actors/actor-client.d.ts +1 -1
  22. package/dist/runtime/actors/actor-client.js +14 -12
  23. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  24. package/dist/runtime/actors/actor-handoff.js +15 -7
  25. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  26. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  27. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  28. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  29. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  30. package/dist/runtime/actors/index.d.ts +2 -1
  31. package/dist/runtime/actors/index.js +18 -6
  32. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  33. package/dist/runtime/admission.d.ts +1 -1
  34. package/dist/runtime/admission.js +15 -5
  35. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +9 -9
  36. package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
  37. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
  38. package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
  39. package/dist/runtime/application-jobs/contracts.d.ts +15 -2
  40. package/dist/runtime/backend/contracts/index.d.ts +27 -27
  41. package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
  42. package/dist/runtime/backend/mesh-completion-table.js +160 -50
  43. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  44. package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
  45. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  46. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  47. package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
  48. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  49. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  51. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  52. package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
  54. package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
  55. package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
  56. package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
  57. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  58. package/dist/runtime/backend/runtime-message.js +5 -0
  59. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  60. package/dist/runtime/backend/runtime-values.js +2 -1
  61. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  62. package/dist/runtime/channels/channel-clients.js +58 -21
  63. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  64. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  65. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  66. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  67. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  68. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  69. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  70. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  71. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  72. package/dist/runtime/channels/channel-envelope.js +83 -8
  73. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  74. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  75. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  76. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  77. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  78. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  79. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  80. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  81. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  82. package/dist/runtime/channels/channel-transports.js +48 -31
  83. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  84. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  85. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  86. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  87. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  88. package/dist/runtime/channels/source-spot-router.js +4 -4
  89. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  90. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  91. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  92. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  93. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  94. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  95. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  96. package/dist/runtime/diagnostics/message-flow.js +3 -3
  97. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  98. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  99. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  100. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  101. package/dist/runtime/foundation/durable-service-request.js +98 -0
  102. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  103. package/dist/runtime/foundation/operation-identity.js +5 -1
  104. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +37 -6
  105. package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
  106. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  107. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  108. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  109. package/dist/runtime/foundation/service-mailbox.js +2 -1
  110. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  111. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  112. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  113. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  114. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  115. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -9
  116. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  117. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
  118. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  119. package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
  120. package/dist/runtime/foundation/service-topology-registry.js +69 -30
  121. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  122. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  123. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  124. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  125. package/dist/runtime/host/actor-packet-relay.js +7 -7
  126. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  127. package/dist/runtime/host/application-job-queue.d.ts +28 -9
  128. package/dist/runtime/host/application-job-queue.js +214 -50
  129. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  130. package/dist/runtime/host/entry-actor-runtime.js +4 -1
  131. package/dist/runtime/host/index.d.ts +7 -1
  132. package/dist/runtime/host/index.js +154 -126
  133. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  134. package/dist/runtime/host/instance-activation-authority.js +89 -25
  135. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  136. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  137. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  138. package/dist/runtime/host/service-relocation-control.js +10 -4
  139. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  140. package/dist/runtime/host/service-relocation-host-runtime.js +215 -243
  141. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  142. package/dist/runtime/host/spot-address-transport.js +28 -14
  143. package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
  144. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  145. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  146. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  147. package/dist/runtime/locations/actor-location-claims.js +34 -19
  148. package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
  149. package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
  150. package/dist/runtime/locations/in-memory-authority-store.js +80 -8
  151. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  152. package/dist/runtime/locations/in-memory-location-store.js +19 -3
  153. package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
  154. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  155. package/dist/runtime/locations/lifecycle.js +2 -5
  156. package/dist/runtime/locations/location-store-repository.d.ts +3 -2
  157. package/dist/runtime/locations/location-store-repository.js +165 -22
  158. package/dist/runtime/locations/resolvers.d.ts +2 -1
  159. package/dist/runtime/locations/resolvers.js +10 -1
  160. package/dist/runtime/locations/runtime.d.ts +1 -1
  161. package/dist/runtime/locations/runtime.js +24 -23
  162. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  163. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  164. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  165. package/dist/runtime/messaging/packet-name.js +8 -24
  166. package/dist/runtime/messaging/request-result.d.ts +2 -0
  167. package/dist/runtime/messaging/request-result.js +54 -0
  168. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  169. package/dist/runtime/messaging/submission-result.js +7 -4
  170. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  171. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  172. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  173. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  174. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +9 -2
  175. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  176. package/dist/runtime/spots/index.d.ts +7 -3
  177. package/dist/runtime/spots/index.js +23 -16
  178. package/dist/runtime/spots/spot-activation.d.ts +3 -1
  179. package/dist/runtime/spots/spot-activation.js +21 -12
  180. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  182. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  183. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  184. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  185. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  186. package/dist/runtime/spots/spot-entry-activation.js +9 -3
  187. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  188. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  189. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  190. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
  191. package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
  192. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  193. package/dist/runtime/spots/spot-outbound.js +24 -15
  194. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  195. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  196. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  197. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
  198. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  199. package/dist/runtime/spots/spot-timer.js +1 -0
  200. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  201. package/dist/runtime/streams/stream-session-runtime.js +14 -28
  202. package/package.json +3 -3
  203. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  204. package/src/contracts/Channels/Calls.ts +2 -1
  205. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  206. package/src/contracts/Configuration/Builders.ts +1 -2
  207. package/src/contracts/Configuration/Configs.ts +0 -6
  208. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  209. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  210. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  211. package/src/contracts/Configuration/index.ts +1 -6
  212. package/src/contracts/Handlers/Attributes.ts +14 -21
  213. package/src/contracts/Handlers/JsonContract.ts +8 -216
  214. package/src/contracts/Spots/Contracts.ts +2 -1
  215. package/src/internal.ts +1 -0
  216. package/src/nest-integration.ts +1 -0
  217. package/src/runtime/actors/actor-client.ts +40 -16
  218. package/src/runtime/actors/actor-handoff.ts +22 -8
  219. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  220. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  221. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  222. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  223. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  224. package/src/runtime/actors/index.ts +19 -5
  225. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  226. package/src/runtime/admission.ts +18 -5
  227. package/src/runtime/application-jobs/application-ingress-record-owner.ts +53 -27
  228. package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
  229. package/src/runtime/application-jobs/contracts.ts +28 -2
  230. package/src/runtime/backend/contracts/index.ts +63 -32
  231. package/src/runtime/backend/mesh-completion-table.ts +175 -59
  232. package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
  233. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  234. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
  235. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  236. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  237. package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
  238. package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
  239. package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
  240. package/src/runtime/backend/raw-binding-port.ts +18 -3
  241. package/src/runtime/backend/runtime-message.ts +6 -0
  242. package/src/runtime/backend/runtime-values.ts +1 -0
  243. package/src/runtime/channels/channel-clients.ts +90 -41
  244. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  245. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  246. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  247. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  248. package/src/runtime/channels/channel-envelope.ts +133 -8
  249. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  250. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  251. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  252. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  253. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  254. package/src/runtime/channels/channel-transports.ts +128 -60
  255. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  256. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  257. package/src/runtime/channels/source-spot-router.ts +8 -4
  258. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  259. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  260. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  261. package/src/runtime/diagnostics/message-flow.ts +1 -1
  262. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  263. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  264. package/src/runtime/foundation/durable-service-request.ts +137 -0
  265. package/src/runtime/foundation/operation-identity.ts +5 -1
  266. package/src/runtime/foundation/raw-service-mesh-runtime.ts +642 -253
  267. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  268. package/src/runtime/foundation/service-mailbox.ts +7 -1
  269. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  270. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  271. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  272. package/src/runtime/foundation/service-stateful-runtime.ts +128 -160
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
  274. package/src/runtime/foundation/service-topology-registry.ts +103 -42
  275. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  276. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  277. package/src/runtime/host/actor-packet-relay.ts +7 -0
  278. package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
  279. package/src/runtime/host/application-job-queue.ts +249 -48
  280. package/src/runtime/host/entry-actor-runtime.ts +5 -0
  281. package/src/runtime/host/index.ts +224 -160
  282. package/src/runtime/host/instance-activation-authority.ts +132 -27
  283. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  284. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  285. package/src/runtime/host/service-relocation-control.ts +11 -5
  286. package/src/runtime/host/service-relocation-host-runtime.ts +317 -291
  287. package/src/runtime/host/spot-address-transport.ts +49 -24
  288. package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  290. package/src/runtime/locations/actor-location-claims.ts +52 -30
  291. package/src/runtime/locations/domain-store-contract.ts +6 -2
  292. package/src/runtime/locations/in-memory-authority-store.ts +113 -9
  293. package/src/runtime/locations/in-memory-location-store.ts +25 -3
  294. package/src/runtime/locations/internal-location-contracts.ts +4 -0
  295. package/src/runtime/locations/lifecycle.ts +8 -26
  296. package/src/runtime/locations/location-store-repository.ts +220 -15
  297. package/src/runtime/locations/resolvers.ts +25 -2
  298. package/src/runtime/locations/runtime.ts +28 -24
  299. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  300. package/src/runtime/messaging/packet-name.ts +5 -25
  301. package/src/runtime/messaging/request-result.ts +58 -0
  302. package/src/runtime/messaging/submission-result.ts +7 -3
  303. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  304. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  305. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +45 -23
  306. package/src/runtime/spots/index.ts +30 -2
  307. package/src/runtime/spots/spot-activation.ts +33 -10
  308. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  309. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  310. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  311. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  312. package/src/runtime/spots/spot-entry-activation.ts +12 -2
  313. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  314. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  315. package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
  316. package/src/runtime/spots/spot-outbound.ts +36 -16
  317. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  318. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  319. package/src/runtime/spots/spot-runtime-ports.ts +3 -0
  320. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  321. package/src/runtime/spots/spot-timer.ts +5 -1
  322. package/src/runtime/streams/stream-session-runtime.ts +13 -30
@@ -1,216 +1,8 @@
1
- const MAX_CONTRACT_SCHEMA_DEPTH = 64;
2
-
3
- /** Describes the fields accepted by the default framework-json-v1 serializer. */
4
- export type ZLinkJsonSchema =
5
- | { readonly type: 'boolean' }
6
- | { readonly type: 'string' }
7
- | { readonly type: 'number' }
8
- | { readonly type: 'int32' }
9
- | { readonly type: 'uint32' }
10
- | { readonly type: 'int64' }
11
- | { readonly type: 'uint64' }
12
- | { readonly type: 'bytes' }
13
- | { readonly type: 'enum'; readonly names: readonly string[] }
14
- | { readonly type: 'nullable'; readonly value: ZLinkJsonSchema }
15
- | { readonly type: 'array'; readonly items: ZLinkJsonSchema }
16
- | { readonly type: 'record'; readonly values: ZLinkJsonSchema }
17
- | {
18
- readonly type: 'object';
19
- readonly properties: Readonly<Record<string, ZLinkJsonSchema>>;
20
- readonly required: readonly string[];
21
- /** Unknown properties are ignored during decoding unless this is false. */
22
- readonly additionalProperties?: boolean;
23
- };
24
-
25
- /**
26
- * Describes the request and optional reply fields carried under one packet
27
- * name by the default JSON serializer.
28
- */
29
- export interface ZLinkPacketJsonContract {
30
- readonly payload: ZLinkJsonSchema;
31
- readonly reply?: ZLinkJsonSchema;
32
- }
33
-
34
- const ZLINK_PACKET_JSON_CONTRACTS = Symbol.for('@zlink-systems/framework:packet-json-contracts');
35
-
36
- export function defineZLinkPacketJsonContract(
37
- packetName: string,
38
- contract: ZLinkPacketJsonContract
39
- ): ZLinkPacketJsonContract {
40
- if (packetName.trim().length === 0) {
41
- throw new TypeError('ZLink packet name must not be empty.');
42
- }
43
- const runtimeContract: unknown = contract;
44
- if (typeof runtimeContract !== 'object' || runtimeContract === null) {
45
- throw new TypeError('ZLink packet JSON contract must be an object.');
46
- }
47
- const normalizedContract = runtimeContract as ZLinkPacketJsonContract;
48
- const normalized = Object.freeze({
49
- payload: normalizeJsonSchema(normalizedContract.payload, new Set(), 0),
50
- ...(normalizedContract.reply === undefined
51
- ? {}
52
- : { reply: normalizeJsonSchema(normalizedContract.reply, new Set(), 0) })
53
- });
54
- const contracts = packetJsonContracts();
55
- const current = contracts.get(packetName);
56
- if (current !== undefined && canonicalContract(current) !== canonicalContract(normalized)) {
57
- throw new TypeError(
58
- `ZLink packet '${packetName}' has conflicting JSON contracts in one process.`
59
- );
60
- }
61
- if (current !== undefined) return current;
62
- contracts.set(packetName, normalized);
63
- return normalized;
64
- }
65
-
66
- export function readZLinkPacketJsonContract(
67
- packetName: string
68
- ): ZLinkPacketJsonContract | undefined {
69
- return packetJsonContracts().get(packetName);
70
- }
71
-
72
- function normalizeJsonSchema(
73
- schema: ZLinkJsonSchema,
74
- parents: Set<object>,
75
- depth: number
76
- ): ZLinkJsonSchema {
77
- // Keep the runtime boundary defensive for JavaScript callers even though
78
- // the TypeScript signature describes the accepted shape.
79
- const runtimeSchema: unknown = schema;
80
- if (
81
- typeof runtimeSchema !== 'object' ||
82
- runtimeSchema === null ||
83
- depth > MAX_CONTRACT_SCHEMA_DEPTH
84
- ) {
85
- throw new TypeError(
86
- `ZLink packet JSON schema must be an acyclic object with at most ${MAX_CONTRACT_SCHEMA_DEPTH} levels.`
87
- );
88
- }
89
- const normalizedSchema = runtimeSchema as ZLinkJsonSchema;
90
- if (parents.has(normalizedSchema))
91
- throw new TypeError('ZLink packet JSON schema must not contain a cycle.');
92
- const nextParents = new Set(parents).add(normalizedSchema);
93
- switch (normalizedSchema.type) {
94
- case 'boolean':
95
- case 'string':
96
- case 'number':
97
- case 'int32':
98
- case 'uint32':
99
- case 'int64':
100
- case 'uint64':
101
- case 'bytes':
102
- return Object.freeze({ type: normalizedSchema.type });
103
- case 'enum': {
104
- if (
105
- !Array.isArray(normalizedSchema.names) ||
106
- normalizedSchema.names.length === 0 ||
107
- normalizedSchema.names.some((name) => typeof name !== 'string' || name.length === 0)
108
- ) {
109
- throw new TypeError('ZLink packet enum schema requires non-empty string names.');
110
- }
111
- if (new Set(normalizedSchema.names).size !== normalizedSchema.names.length) {
112
- throw new TypeError('ZLink packet enum schema names must be unique.');
113
- }
114
- return Object.freeze({ type: 'enum', names: Object.freeze([...normalizedSchema.names]) });
115
- }
116
- case 'nullable':
117
- return Object.freeze({
118
- type: 'nullable',
119
- value: normalizeJsonSchema(normalizedSchema.value, nextParents, depth + 1)
120
- });
121
- case 'array':
122
- return Object.freeze({
123
- type: 'array',
124
- items: normalizeJsonSchema(normalizedSchema.items, nextParents, depth + 1)
125
- });
126
- case 'record':
127
- return Object.freeze({
128
- type: 'record',
129
- values: normalizeJsonSchema(normalizedSchema.values, nextParents, depth + 1)
130
- });
131
- case 'object': {
132
- const runtimeProperties: unknown = normalizedSchema.properties;
133
- if (
134
- typeof runtimeProperties !== 'object' ||
135
- runtimeProperties === null ||
136
- Array.isArray(runtimeProperties)
137
- ) {
138
- throw new TypeError('ZLink packet object schema properties must be an object.');
139
- }
140
- if (
141
- !Array.isArray(normalizedSchema.required) ||
142
- normalizedSchema.required.some((name) => typeof name !== 'string' || name.length === 0)
143
- ) {
144
- throw new TypeError('ZLink packet object schema required must contain property names.');
145
- }
146
- if (
147
- normalizedSchema.additionalProperties !== undefined &&
148
- typeof normalizedSchema.additionalProperties !== 'boolean'
149
- ) {
150
- throw new TypeError('ZLink packet object schema additionalProperties must be boolean.');
151
- }
152
- const properties: Record<string, ZLinkJsonSchema> = {};
153
- for (const [name, property] of Object.entries(
154
- runtimeProperties as Record<string, ZLinkJsonSchema>
155
- )) {
156
- if (isPrototypeKey(name)) {
157
- throw new TypeError(`ZLink packet JSON property '${name}' is not allowed.`);
158
- }
159
- properties[name] = normalizeJsonSchema(property, nextParents, depth + 1);
160
- }
161
- if (new Set(normalizedSchema.required).size !== normalizedSchema.required.length) {
162
- throw new TypeError('ZLink packet JSON required properties must be unique.');
163
- }
164
- for (const name of normalizedSchema.required) {
165
- if (isPrototypeKey(name)) {
166
- throw new TypeError(`ZLink packet JSON property '${name}' is not allowed.`);
167
- }
168
- if (!Object.prototype.hasOwnProperty.call(properties, name)) {
169
- throw new TypeError(
170
- `ZLink packet JSON required property '${name}' has no property schema.`
171
- );
172
- }
173
- }
174
- return Object.freeze({
175
- type: 'object',
176
- properties: Object.freeze(properties),
177
- required: Object.freeze([...normalizedSchema.required]),
178
- ...(normalizedSchema.additionalProperties === undefined
179
- ? {}
180
- : { additionalProperties: normalizedSchema.additionalProperties })
181
- });
182
- }
183
- }
184
- throw new TypeError(
185
- `ZLink packet JSON schema type '${String((normalizedSchema as { type?: unknown }).type)}' is not supported.`
186
- );
187
- }
188
-
189
- function packetJsonContracts(): Map<string, ZLinkPacketJsonContract> {
190
- const root = globalThis as typeof globalThis & Record<symbol, unknown>;
191
- let contracts = root[ZLINK_PACKET_JSON_CONTRACTS] as
192
- Map<string, ZLinkPacketJsonContract> | undefined;
193
- if (contracts === undefined) {
194
- contracts = new Map();
195
- Object.defineProperty(root, ZLINK_PACKET_JSON_CONTRACTS, {
196
- configurable: false,
197
- enumerable: false,
198
- value: contracts,
199
- writable: false
200
- });
201
- }
202
- return contracts;
203
- }
204
-
205
- function canonicalContract(value: unknown): string {
206
- if (Array.isArray(value)) return `[${value.map(canonicalContract).join(',')}]`;
207
- if (typeof value !== 'object' || value === null) return JSON.stringify(value);
208
- return `{${Object.entries(value as Record<string, unknown>)
209
- .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
210
- .map(([key, item]) => `${JSON.stringify(key)}:${canonicalContract(item)}`)
211
- .join(',')}}`;
212
- }
213
-
214
- function isPrototypeKey(name: string): boolean {
215
- return name === '__proto__' || name === 'prototype' || name === 'constructor';
216
- }
1
+ export {
2
+ defineZLinkPacketJsonContract,
3
+ readZLinkPacketJsonContract
4
+ } from '@zlink-systems/stream-wire/internal/json';
5
+ export type {
6
+ ZLinkJsonSchema,
7
+ ZLinkPacketJsonContract
8
+ } from '@zlink-systems/stream-wire/internal/json';
@@ -2,6 +2,7 @@ import type { ZLinkActor } from '../Actors';
2
2
  import type { ZLinkChannelRequestCall, ZLinkPublishCall, ZLinkSendCall } from '../Channels';
3
3
  import type { RoutingId, SpotId, Type, ZLinkMessageMetadata } from '../Common';
4
4
  import type { ZLinkSpotTimerHandler } from '../Handlers';
5
+ import type { ZLinkRequest } from '../Handlers/Attributes';
5
6
  import type { ZLinkTimer, ZLinkTimerOptions } from '../Timers';
6
7
  import type {
7
8
  ZLinkEntrySpot,
@@ -106,7 +107,7 @@ export interface ZLinkSpotRequestCall {
106
107
  instanceSpot(instanceSpotType: string): this;
107
108
  inMesh(meshName: string): this;
108
109
  timeout(timeoutMs: number): this;
109
- submit<TReply>(signal?: AbortSignal): Promise<TReply>;
110
+ submit<TReply>(signal?: AbortSignal): ZLinkRequest<TReply>;
110
111
  yield<TReply>(signal?: AbortSignal): Promise<TReply>;
111
112
  }
112
113
 
package/src/internal.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /** Test and companion-package integration surface. It is not exported by package.json. */
2
2
  export * from './index';
3
+ export { requireValidSendTimeoutMs } from './contracts/Configuration/SendTimeoutValidation';
3
4
  export * from './runtime/diagnostics';
4
5
  export * from './runtime/host';
5
6
  export * from './runtime/admission';
@@ -77,6 +77,7 @@ export {
77
77
  type ZLinkHandlerFilterScopeRunner
78
78
  } from './runtime/channels/handler-filter-scope';
79
79
  export {
80
+ registerHandlerInstanceScopeFactory as registerIntegrationHandlerInstanceScopeFactory,
80
81
  disposeOwnedInstance as disposeIntegrationHandler,
81
82
  disposeOwnedInstances as disposeIntegrationHandlers
82
83
  } from './runtime/handlers/handler-instance-scope';
@@ -1,4 +1,6 @@
1
1
  import { ZlinkStreamContentType } from '@zlink-systems/stream-wire';
2
+ import { createZLinkRequest } from '../messaging/request-result';
3
+ import type { ZLinkRequest } from '../../contracts/Handlers/Attributes';
2
4
  import {
3
5
  type ActorRef,
4
6
  type RoutingId,
@@ -89,7 +91,8 @@ export interface ZLinkActorClientOptions {
89
91
  parts: readonly Message[],
90
92
  returnResponse: boolean,
91
93
  actor: ActorRef,
92
- deadlineUnixMs?: number
94
+ deadlineUnixMs?: number,
95
+ onAdmitted?: () => void
93
96
  ) => Promise<unknown> | undefined;
94
97
  readonly sendErrorReporter?: (error: unknown) => void;
95
98
  readonly routeTransport?: ZLinkActorRoutedJoinTransport;
@@ -118,8 +121,17 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
118
121
  requestToActor(actorId: string, request: unknown): ZLinkActorRequestCall {
119
122
  requireActorId(actorId);
120
123
  return new DefaultZLinkActorRequestCall(
121
- (packetName, timeoutMs, metadata, signal) =>
122
- this.request(actorId, packetName, request, timeoutMs, metadata, signal, 'async'),
124
+ (packetName, timeoutMs, metadata, signal, onAdmitted) =>
125
+ this.request(
126
+ actorId,
127
+ packetName,
128
+ request,
129
+ timeoutMs,
130
+ metadata,
131
+ signal,
132
+ 'async',
133
+ onAdmitted
134
+ ),
123
135
  (packetName, timeoutMs, metadata, signal) =>
124
136
  this.request(actorId, packetName, request, timeoutMs, metadata, signal, 'yield'),
125
137
  actorId,
@@ -211,7 +223,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
211
223
  timeoutMs: number | undefined,
212
224
  metadata: ReadonlyMap<string, string>,
213
225
  signal?: AbortSignal,
214
- waitPolicy: 'async' | 'yield' = 'async'
226
+ waitPolicy: 'async' | 'yield' = 'async',
227
+ onAdmitted?: () => void
215
228
  ): Promise<TReply> {
216
229
  throwIfAborted(signal);
217
230
  const sourceSpotId = currentZLinkActorExecution()?.spotId ?? currentZLinkSpotSerialSourceId();
@@ -267,7 +280,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
267
280
  parts,
268
281
  true,
269
282
  routedActor,
270
- deadlineUnixMs
283
+ deadlineUnixMs,
284
+ onAdmitted
271
285
  );
272
286
  if (handoff !== undefined) {
273
287
  const submissions = [handoff];
@@ -278,7 +292,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
278
292
  parts,
279
293
  true,
280
294
  routedActor,
281
- deadlineUnixMs
295
+ deadlineUnixMs,
296
+ onAdmitted
282
297
  );
283
298
  if (duplicate !== undefined) submissions.push(duplicate);
284
299
  }
@@ -297,7 +312,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
297
312
  remainingActorRequestTimeout(actorId, deadlineMs),
298
313
  signal,
299
314
  route,
300
- messageFollow
315
+ messageFollow,
316
+ onAdmitted
301
317
  );
302
318
  } catch (error) {
303
319
  if (isStaleActorError(error)) {
@@ -423,7 +439,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
423
439
  timeoutMs: number | undefined,
424
440
  signal?: AbortSignal,
425
441
  route?: ZLinkResolvedActorRoute,
426
- messageFollowContext?: ZLinkActorMessageFollowContext
442
+ messageFollowContext?: ZLinkActorMessageFollowContext,
443
+ onAdmitted?: () => void
427
444
  ): Promise<TReply> {
428
445
  const node = this.requireNode(meshName);
429
446
  if (
@@ -459,7 +476,7 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
459
476
  this.options.routeTransport,
460
477
  remoteActorRouteTarget(route),
461
478
  relay,
462
- { timeoutMs, signal },
479
+ { timeoutMs, signal, onAdmitted },
463
480
  `Remote Actor request is not available for '${actor.actorId}'.`,
464
481
  (replyParts) => JSON.parse(replyParts[0]?.getString('utf8') ?? '{}')
465
482
  );
@@ -481,7 +498,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
481
498
  () =>
482
499
  node.requestToActor(actor, toMessageLikeParts(parts), {
483
500
  flags: ZLINK_BACKEND_SEND_NONE,
484
- timeoutMs
501
+ timeoutMs,
502
+ onAdmitted
485
503
  }),
486
504
  signal
487
505
  );
@@ -700,7 +718,8 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
700
718
  packetName: string | undefined,
701
719
  timeoutMs: number | undefined,
702
720
  metadata: ReadonlyMap<string, string>,
703
- signal?: AbortSignal
721
+ signal?: AbortSignal,
722
+ onAdmitted?: () => void
704
723
  ) => Promise<TReply>,
705
724
  private readonly yieldSubmitter: <TReply>(
706
725
  packetName: string | undefined,
@@ -728,8 +747,9 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
728
747
  return this;
729
748
  }
730
749
 
731
- submit<TReply>(signal?: AbortSignal): Promise<TReply> {
732
- return this.execute<TReply>('async', signal);
750
+ submit<TReply>(signal?: AbortSignal): ZLinkRequest<TReply> {
751
+ this.rejectSelfActorRequest();
752
+ return createZLinkRequest((onAdmitted) => this.execute<TReply>('async', signal, onAdmitted));
733
753
  }
734
754
 
735
755
  yield<TReply>(signal?: AbortSignal): Promise<TReply> {
@@ -739,9 +759,12 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
739
759
  return turn.yieldPromise(pending);
740
760
  }
741
761
 
742
- private execute<TReply>(waitPolicy: 'async' | 'yield', signal?: AbortSignal): Promise<TReply> {
762
+ private execute<TReply>(
763
+ waitPolicy: 'async' | 'yield',
764
+ signal?: AbortSignal,
765
+ onAdmitted?: () => void
766
+ ): Promise<TReply> {
743
767
  ensureSingleSubmit(this.executed);
744
- this.rejectSelfActorRequest();
745
768
  this.executed = true;
746
769
  throwIfAborted(signal);
747
770
  const submitter = waitPolicy === 'async' ? this.asyncSubmitter : this.yieldSubmitter;
@@ -749,7 +772,8 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
749
772
  this.packet ?? resolveFrameworkPacketName(this.request, undefined, 'Actor'),
750
773
  this.timeoutMs ?? this.defaultRequestTimeoutMs,
751
774
  this.selectedMetadata,
752
- signal
775
+ signal,
776
+ onAdmitted
753
777
  );
754
778
  }
755
779
 
@@ -3,6 +3,7 @@ import { type ActorRef, type RoutingId, ZLinkFrameworkException } from '../../co
3
3
  import type { Message } from '../../contracts/Common/Message';
4
4
  import { zlinkDefaultLocationOptions } from '../../contracts/Locations/Options';
5
5
  import { releaseApplicationJobPermitForDurableHandoff } from '../application-jobs/application-job-queue-scope';
6
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
6
7
  import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
7
8
  import {
8
9
  MessageFollowSuppressionRegistry,
@@ -108,7 +109,8 @@ export interface ZLinkActorHandoffPreparedReplayAdmission {
108
109
  }
109
110
 
110
111
  export type ZLinkActorHandoffReplayPreparation = (
111
- signal: AbortSignal
112
+ signal: AbortSignal,
113
+ origin: ApplicationJobOrigin
112
114
  ) => Promise<ZLinkActorHandoffPreparedReplayAdmission>;
113
115
 
114
116
  export interface ZLinkActorHandoffPrefixAdmission {
@@ -137,6 +139,7 @@ export type ZLinkActorHandoffPrefixQueue = (
137
139
  ) => ZLinkActorHandoffPrefixAdmission;
138
140
 
139
141
  interface PendingPacket {
142
+ readonly origin: ApplicationJobOrigin;
140
143
  readonly packet: ZLinkActorHandoffPacket;
141
144
  readonly resolve?: (value: unknown) => void;
142
145
  readonly reject?: (reason: unknown) => void;
@@ -554,7 +557,7 @@ export class ZLinkActorHandoffCoordinator {
554
557
  try {
555
558
  await waitForHandoffReplayStart(release.start, signal);
556
559
  if (release.preparation !== undefined) {
557
- const next = await release.preparation(signal);
560
+ const next = await release.preparation(signal, pending.origin);
558
561
  if (signal.aborted) {
559
562
  next.cancel();
560
563
  throw signal.reason;
@@ -765,6 +768,7 @@ export class ZLinkActorHandoffCoordinator {
765
768
  }
766
769
 
767
770
  capture(
771
+ origin: ApplicationJobOrigin,
768
772
  actorId: string,
769
773
  parts: readonly Message[],
770
774
  returnResponse = false,
@@ -772,7 +776,8 @@ export class ZLinkActorHandoffCoordinator {
772
776
  fallbackActorRef?: ActorRef,
773
777
  deadlineUnixMs?: number,
774
778
  messageFollowOrigin?: ZLinkMessageFollowOrigin,
775
- provisionalReplay?: ZLinkActorHandoffDispatch
779
+ provisionalReplay?: ZLinkActorHandoffDispatch,
780
+ onAdmitted?: () => void
776
781
  ): Promise<unknown> | undefined {
777
782
  const incomingContext = actorMessageFollowContext(fallbackActorRef);
778
783
  const originalDeadlineUnixMs =
@@ -823,7 +828,7 @@ export class ZLinkActorHandoffCoordinator {
823
828
  this.reportRequestFrame(actorId, packet);
824
829
  }
825
830
  if (!returnResponse) {
826
- handoff.pending.push({ packet });
831
+ handoff.pending.push({ packet, origin });
827
832
  // The durable handoff now owns this record. Return the ingress permit
828
833
  // before waiting for a later replay, which must acquire its own fresh
829
834
  // application-job permit.
@@ -859,9 +864,15 @@ export class ZLinkActorHandoffCoordinator {
859
864
  }, RELOCATION_REPLY_RETENTION_MS);
860
865
  route.deadline.unref();
861
866
  this.replyRoutes.set(source.replyRouteId, route);
862
- handoff.pending.push({ packet: requestPacket, resolve, reject });
867
+ handoff.pending.push({
868
+ packet: requestPacket,
869
+ origin,
870
+ resolve,
871
+ reject
872
+ });
863
873
  });
864
874
  releaseApplicationJobPermitForDurableHandoff();
875
+ onAdmitted?.();
865
876
  if (handoff.prefixRelease !== undefined) {
866
877
  try {
867
878
  this.admitPendingPrefix(actorId, handoff, handoff.prefixRelease);
@@ -907,7 +918,7 @@ export class ZLinkActorHandoffCoordinator {
907
918
  incomingContext,
908
919
  messageFollowOrigin
909
920
  );
910
- return this.enqueueMessageFollow(followRoute, actorId, packet);
921
+ return this.enqueueMessageFollow(followRoute, actorId, packet, onAdmitted);
911
922
  }
912
923
  this.options.onMarker?.('message_follow_rejected', actorId);
913
924
  return Promise.reject(actorLocationStale(actorId));
@@ -964,7 +975,7 @@ export class ZLinkActorHandoffCoordinator {
964
975
  context,
965
976
  messageFollowOrigin
966
977
  );
967
- return this.enqueueMessageFollow(followRoute, actorId, packet);
978
+ return this.enqueueMessageFollow(followRoute, actorId, packet, onAdmitted);
968
979
  }
969
980
 
970
981
  snapshot(actorId: string): readonly ZLinkActorHandoffPacket[] {
@@ -1431,7 +1442,8 @@ export class ZLinkActorHandoffCoordinator {
1431
1442
  private enqueueMessageFollow(
1432
1443
  entry: MessageFollowRoute,
1433
1444
  actorId: string,
1434
- packet: ZLinkActorHandoffPacket
1445
+ packet: ZLinkActorHandoffPacket,
1446
+ onAdmitted?: () => void
1435
1447
  ): Promise<unknown> {
1436
1448
  const context = packet.messageFollowContext;
1437
1449
  const duplicate = entry.operations.get(context.operationId);
@@ -1444,6 +1456,7 @@ export class ZLinkActorHandoffCoordinator {
1444
1456
  this.options.onMarker?.('message_follow_rejected', actorId);
1445
1457
  return Promise.reject(actorLocationStale(actorId));
1446
1458
  }
1459
+ onAdmitted?.();
1447
1460
  return duplicate.result;
1448
1461
  }
1449
1462
  const bytes = packetBytes(packet);
@@ -1465,6 +1478,7 @@ export class ZLinkActorHandoffCoordinator {
1465
1478
  replyRouteId: context.replyRouteId,
1466
1479
  result
1467
1480
  });
1481
+ onAdmitted?.();
1468
1482
  entry.tail = entry.tail.then(async () => {
1469
1483
  try {
1470
1484
  resolve(await this.relayMessageFollow(actorId, entry, packet));
@@ -30,6 +30,7 @@ export interface ZLinkActorJoinRelocation {
30
30
  };
31
31
  /** Target's advertised relocation state chunk cap from the accepted admission reply. */
32
32
  readonly advertisedReceiveChunkLimitBytes?: number;
33
+ readonly deadlineAtMs?: number;
33
34
  readonly signal?: AbortSignal;
34
35
  }): Promise<{
35
36
  readonly actorRef: ZLinkBackendActorRef;
@@ -199,33 +199,24 @@ export class ZLinkLocalNativeActorJoin {
199
199
  );
200
200
  }
201
201
  const membershipEpoch = location.membershipEpoch + 1n;
202
+ const currentActor = toFrameworkActorRef(actorRef, meshName);
203
+ const authorityOwnerGeneration = state.locationGeneration ?? actorRef.generation;
202
204
  const commit = async (spot?: ZLinkSpot): Promise<void> => {
203
205
  throwIfAborted(signal);
204
- if (target.spotKind === ZLinkSpotKind.Entry) {
205
- await this.options.locationLifecycle?.notifyActorLeftSpot(
206
- actorType,
207
- actor.context.actorId,
208
- storeSpotId,
209
- spotGeneration,
210
- membershipEpoch,
211
- node.status().lifecycleGeneration
212
- );
213
- } else {
214
- await this.options.locationLifecycle?.notifyActorJoinedSpot(
215
- actorType,
216
- actor.context.actorId,
217
- meshName,
218
- storeSpotId,
219
- spotGeneration,
220
- membershipEpoch,
221
- node.status().lifecycleGeneration
222
- );
223
- }
206
+ await this.options.locationLifecycle?.commitActorMembership(
207
+ actorType,
208
+ currentActor,
209
+ authorityOwnerGeneration,
210
+ storeSpotId,
211
+ spotGeneration,
212
+ target.spotKind === ZLinkSpotKind.Entry ? ZLinkSpotKind.Entry : ZLinkSpotKind.User,
213
+ node.status().lifecycleGeneration
214
+ );
224
215
  const committedActor = node.restoreActorAuthority!(
225
216
  actor.context.actorId,
226
217
  actorType,
227
218
  actorRef.generation,
228
- state.locationGeneration ?? actorRef.generation,
219
+ authorityOwnerGeneration,
229
220
  target.spotKind === ZLinkSpotKind.Entry ? undefined : String(target.spotId),
230
221
  spotGeneration,
231
222
  membershipEpoch
@@ -297,6 +288,7 @@ export class ZLinkLocalNativeActorJoin {
297
288
  completionOperationId: ZLinkActorJoinOperationId | undefined,
298
289
  entrySpot: boolean
299
290
  ): Promise<ZLinkActorJoinRuntimeResult<Message>> {
291
+ const deadlineAtMs = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
300
292
  const actorType = state.actorType;
301
293
  if (actorType === undefined) {
302
294
  throw createInternalFrameworkException(
@@ -443,6 +435,7 @@ export class ZLinkLocalNativeActorJoin {
443
435
  target,
444
436
  relocationId,
445
437
  completionOperationId,
438
+ deadlineAtMs,
446
439
  ...(control.canonicalHandoffId === undefined || canonicalAdmission === undefined
447
440
  ? {}
448
441
  : {
@@ -456,11 +449,9 @@ export class ZLinkLocalNativeActorJoin {
456
449
  },
457
450
  requestContentType: canonicalAdmission.request.contentType,
458
451
  request: Buffer.from(canonicalAdmission.request.payload),
459
- ...(completionOperationId === undefined
452
+ ...(completionOperationId === undefined || control.replyContentType === undefined
460
453
  ? {}
461
- : {
462
- replyContentType: control.replyContentType ?? ZlinkStreamContentType.Raw
463
- }),
454
+ : { replyContentType: control.replyContentType }),
464
455
  reply:
465
456
  completionOperationId === undefined
466
457
  ? Buffer.alloc(0)
@@ -469,7 +460,7 @@ export class ZLinkLocalNativeActorJoin {
469
460
  expectedOwnerLeaseGeneration: actorAuthorityFence!.ownerLeaseGeneration,
470
461
  targetNodeGeneration: target.targetNodeGeneration!,
471
462
  targetSpotGeneration: control.location.spotGeneration,
472
- targetAuthorityOwnerGeneration: actorAuthorityFence!.authorityOwnerGeneration + 1n,
463
+ targetAuthorityOwnerGeneration: actorAuthorityFence!.authorityOwnerGeneration,
473
464
  targetSpotAuthorityOwnerGeneration: target.authorityOwnerGeneration ?? 1n
474
465
  }
475
466
  }),
@@ -21,9 +21,26 @@ export interface ZLinkRemoteActorSourceLeaveTerminal {
21
21
  readonly succeeded: boolean;
22
22
  }
23
23
 
24
+ const JSON_OBJECT_START = '{'.charCodeAt(0);
25
+ const JSON_SPACE = ' '.charCodeAt(0);
26
+ const JSON_TAB = '\t'.charCodeAt(0);
27
+ const JSON_LINE_FEED = '\n'.charCodeAt(0);
28
+ const JSON_CARRIAGE_RETURN = '\r'.charCodeAt(0);
29
+
24
30
  export function decodeRemoteActorSourceLeaveTerminal(
25
31
  payload: Buffer
26
32
  ): ZLinkRemoteActorSourceLeaveTerminal | undefined {
33
+ // A SourceLeave terminal is a JSON object. Binary channel frames and JSON
34
+ // primitives cannot be terminals, so do not materialize or parse them.
35
+ let offset = 0;
36
+ while (
37
+ payload[offset] === JSON_SPACE ||
38
+ payload[offset] === JSON_TAB ||
39
+ payload[offset] === JSON_LINE_FEED ||
40
+ payload[offset] === JSON_CARRIAGE_RETURN
41
+ )
42
+ offset++;
43
+ if (payload[offset] !== JSON_OBJECT_START) return undefined;
27
44
  let decoded: unknown;
28
45
  try {
29
46
  decoded = JSON.parse(payload.toString());