@memberjunction/server 6.2.0-edge.5 → 6.2.0-edge.7

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 (664) hide show
  1. package/README.md +96 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
  4. package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
  5. package/dist/agentSessions/BridgeHostInstance.js +14 -4
  6. package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
  7. package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
  8. package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
  9. package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
  10. package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
  11. package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
  12. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  13. package/dist/agentSessions/SessionJanitor.d.ts +34 -11
  14. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  15. package/dist/agentSessions/SessionJanitor.js +88 -44
  16. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  17. package/dist/agentSessions/SessionManager.d.ts +29 -9
  18. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  19. package/dist/agentSessions/SessionManager.js +62 -16
  20. package/dist/agentSessions/SessionManager.js.map +1 -1
  21. package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
  22. package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
  23. package/dist/agentSessions/conversationBrowsers.js +118 -0
  24. package/dist/agentSessions/conversationBrowsers.js.map +1 -0
  25. package/dist/agentSessions/sessionDeadline.d.ts +43 -0
  26. package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
  27. package/dist/agentSessions/sessionDeadline.js +68 -0
  28. package/dist/agentSessions/sessionDeadline.js.map +1 -0
  29. package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
  30. package/dist/auth/APIKeyScopeAuth.js +5 -4
  31. package/dist/auth/APIKeyScopeAuth.js.map +1 -1
  32. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  33. package/dist/auth/AuthProviderCatalogRouter.js +2 -0
  34. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  35. package/dist/auth/index.d.ts.map +1 -1
  36. package/dist/auth/index.js +51 -10
  37. package/dist/auth/index.js.map +1 -1
  38. package/dist/auth/initializeProviders.d.ts +10 -0
  39. package/dist/auth/initializeProviders.d.ts.map +1 -1
  40. package/dist/auth/initializeProviders.js +37 -1
  41. package/dist/auth/initializeProviders.js.map +1 -1
  42. package/dist/auth/localDevAuth.d.ts +79 -0
  43. package/dist/auth/localDevAuth.d.ts.map +1 -0
  44. package/dist/auth/localDevAuth.js +439 -0
  45. package/dist/auth/localDevAuth.js.map +1 -0
  46. package/dist/auth/loginEmailResolution.d.ts +41 -0
  47. package/dist/auth/loginEmailResolution.d.ts.map +1 -0
  48. package/dist/auth/loginEmailResolution.js +47 -0
  49. package/dist/auth/loginEmailResolution.js.map +1 -0
  50. package/dist/auth/magicLink/MagicLinkKeys.d.ts +51 -3
  51. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  52. package/dist/auth/magicLink/MagicLinkKeys.js +130 -13
  53. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  54. package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
  55. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  56. package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
  57. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  58. package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
  59. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  60. package/dist/auth/magicLink/MagicLinkService.js +221 -9
  61. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  62. package/dist/auth/magicLink/index.d.ts +1 -1
  63. package/dist/auth/magicLink/index.d.ts.map +1 -1
  64. package/dist/auth/magicLink/index.js +1 -1
  65. package/dist/auth/magicLink/index.js.map +1 -1
  66. package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
  67. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  68. package/dist/auth/magicLink/redeemLanding.js +7 -4
  69. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  70. package/dist/auth/magicLink/types.d.ts +39 -3
  71. package/dist/auth/magicLink/types.d.ts.map +1 -1
  72. package/dist/auth/magicLink/types.js +0 -4
  73. package/dist/auth/magicLink/types.js.map +1 -1
  74. package/dist/auth/newUsers.d.ts.map +1 -1
  75. package/dist/auth/newUsers.js +1 -0
  76. package/dist/auth/newUsers.js.map +1 -1
  77. package/dist/auth/sessionUserClone.d.ts +1 -1
  78. package/dist/auth/sessionUserClone.d.ts.map +1 -1
  79. package/dist/auth/sessionUserClone.js +3 -2
  80. package/dist/auth/sessionUserClone.js.map +1 -1
  81. package/dist/backgroundSweepConfigUnits.d.ts +231 -0
  82. package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
  83. package/dist/backgroundSweepConfigUnits.js +180 -0
  84. package/dist/backgroundSweepConfigUnits.js.map +1 -0
  85. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
  86. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
  87. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
  88. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
  89. package/dist/broadcast/index.d.ts +6 -0
  90. package/dist/broadcast/index.d.ts.map +1 -0
  91. package/dist/broadcast/index.js +6 -0
  92. package/dist/broadcast/index.js.map +1 -0
  93. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
  94. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
  95. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
  96. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
  97. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
  98. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
  99. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
  100. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
  101. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
  102. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
  103. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
  104. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
  105. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
  106. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
  107. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
  108. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
  109. package/dist/cache.d.ts +3 -2
  110. package/dist/cache.d.ts.map +1 -1
  111. package/dist/cache.js.map +1 -1
  112. package/dist/config.d.ts +1402 -8
  113. package/dist/config.d.ts.map +1 -1
  114. package/dist/config.js +120 -0
  115. package/dist/config.js.map +1 -1
  116. package/dist/context.d.ts +5 -1
  117. package/dist/context.d.ts.map +1 -1
  118. package/dist/context.js +64 -12
  119. package/dist/context.js.map +1 -1
  120. package/dist/coreRoutes.d.ts +3 -1
  121. package/dist/coreRoutes.d.ts.map +1 -1
  122. package/dist/coreRoutes.js +20 -4
  123. package/dist/coreRoutes.js.map +1 -1
  124. package/dist/generated/graphql-schemas/__mj.d.ts +863 -14
  125. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  126. package/dist/generated/graphql-schemas/__mj.js +4167 -62
  127. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  128. package/dist/generic/CacheInvalidationResolver.d.ts +50 -30
  129. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  130. package/dist/generic/CacheInvalidationResolver.js +154 -79
  131. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  132. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
  133. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  134. package/dist/generic/OrphanedConversationDetailReconciler.js +29 -1
  135. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  136. package/dist/generic/PubSubManager.d.ts +10 -0
  137. package/dist/generic/PubSubManager.d.ts.map +1 -1
  138. package/dist/generic/PubSubManager.js +44 -1
  139. package/dist/generic/PubSubManager.js.map +1 -1
  140. package/dist/generic/PushStatusResolver.d.ts +39 -6
  141. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  142. package/dist/generic/PushStatusResolver.js +93 -11
  143. package/dist/generic/PushStatusResolver.js.map +1 -1
  144. package/dist/generic/ResolverBase.d.ts +114 -29
  145. package/dist/generic/ResolverBase.d.ts.map +1 -1
  146. package/dist/generic/ResolverBase.js +509 -220
  147. package/dist/generic/ResolverBase.js.map +1 -1
  148. package/dist/generic/RunViewResolver.d.ts +15 -3
  149. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  150. package/dist/generic/RunViewResolver.js +126 -20
  151. package/dist/generic/RunViewResolver.js.map +1 -1
  152. package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
  153. package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
  154. package/dist/generic/actionOutputFieldSecurity.js +47 -0
  155. package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
  156. package/dist/generic/fieldSecurityTransport.d.ts +30 -0
  157. package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
  158. package/dist/generic/fieldSecurityTransport.js +30 -0
  159. package/dist/generic/fieldSecurityTransport.js.map +1 -0
  160. package/dist/index.d.ts +4 -0
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +262 -84
  163. package/dist/index.js.map +1 -1
  164. package/dist/integration/ConnectionPause.d.ts +121 -0
  165. package/dist/integration/ConnectionPause.d.ts.map +1 -0
  166. package/dist/integration/ConnectionPause.js +183 -0
  167. package/dist/integration/ConnectionPause.js.map +1 -0
  168. package/dist/integration/CustomColumnPromoter.d.ts +72 -6
  169. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  170. package/dist/integration/CustomColumnPromoter.js +93 -47
  171. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  172. package/dist/integration/EntityMapLifecycle.d.ts +78 -4
  173. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  174. package/dist/integration/EntityMapLifecycle.js +199 -5
  175. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  176. package/dist/integration/InactiveRowWarnings.d.ts +31 -0
  177. package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
  178. package/dist/integration/InactiveRowWarnings.js +29 -0
  179. package/dist/integration/InactiveRowWarnings.js.map +1 -1
  180. package/dist/integration/ObjectNamesByID.d.ts +28 -0
  181. package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
  182. package/dist/integration/ObjectNamesByID.js +87 -0
  183. package/dist/integration/ObjectNamesByID.js.map +1 -0
  184. package/dist/integration/PostRestartIntrospect.d.ts +26 -0
  185. package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
  186. package/dist/integration/PostRestartIntrospect.js +27 -0
  187. package/dist/integration/PostRestartIntrospect.js.map +1 -0
  188. package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
  189. package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
  190. package/dist/integration/RSUPostRestartProgress.js +323 -0
  191. package/dist/integration/RSUPostRestartProgress.js.map +1 -0
  192. package/dist/integration/RSUProgressBridge.d.ts +41 -2
  193. package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
  194. package/dist/integration/RSUProgressBridge.js +84 -1
  195. package/dist/integration/RSUProgressBridge.js.map +1 -1
  196. package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
  197. package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
  198. package/dist/integration/RunArtifactAuthorization.js +45 -0
  199. package/dist/integration/RunArtifactAuthorization.js.map +1 -0
  200. package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
  201. package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
  202. package/dist/integration/SchemaRefreshLaunch.js +3 -2
  203. package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
  204. package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
  205. package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
  206. package/dist/integration/ScopedFieldsForBuild.js +91 -0
  207. package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
  208. package/dist/integration/TargetConfigGuard.d.ts +40 -0
  209. package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
  210. package/dist/integration/TargetConfigGuard.js +40 -0
  211. package/dist/integration/TargetConfigGuard.js.map +1 -0
  212. package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
  213. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  214. package/dist/logging/variablesLoggingMiddleware.js +50 -1
  215. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  216. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
  217. package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
  218. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
  219. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +8 -6
  220. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
  221. package/dist/realtimeSessions/ownedRealtimeSession.js +14 -6
  222. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
  223. package/dist/realtimeSessions/sessionAccess.d.ts +103 -11
  224. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  225. package/dist/realtimeSessions/sessionAccess.js +147 -22
  226. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  227. package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
  228. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
  229. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
  230. package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
  231. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
  232. package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
  233. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
  234. package/dist/realtimeSessions/verificationWorkflow.js +1 -1
  235. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
  236. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  237. package/dist/realtimeWidget/WidgetRouter.js +19 -3
  238. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  239. package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
  240. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  241. package/dist/realtimeWidget/WidgetSessionService.js +203 -19
  242. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  243. package/dist/realtimeWidget/host-identity.d.ts +1 -1
  244. package/dist/realtimeWidget/host-identity.js +1 -1
  245. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  246. package/dist/realtimeWidget/visitorIdentity.js +1 -0
  247. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  248. package/dist/realtimeWidget/widgetCore.d.ts +20 -1
  249. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  250. package/dist/realtimeWidget/widgetCore.js +21 -8
  251. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  252. package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
  253. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  254. package/dist/realtimeWidget/widgetGuestElevation.js +3 -1
  255. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  256. package/dist/requestOrigin.d.ts +22 -0
  257. package/dist/requestOrigin.d.ts.map +1 -0
  258. package/dist/requestOrigin.js +60 -0
  259. package/dist/requestOrigin.js.map +1 -0
  260. package/dist/resolvers/ActionResolver.d.ts +19 -1
  261. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  262. package/dist/resolvers/ActionResolver.js +63 -12
  263. package/dist/resolvers/ActionResolver.js.map +1 -1
  264. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  265. package/dist/resolvers/AdhocQueryResolver.js +1 -0
  266. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  267. package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
  268. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  269. package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
  270. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  271. package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
  272. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  273. package/dist/resolvers/AgentSessionResolver.js +44 -17
  274. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  275. package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
  276. package/dist/resolvers/AutotagPipelineResolver.js +2 -1
  277. package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
  278. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  279. package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
  280. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  281. package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
  282. package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
  283. package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
  284. package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
  285. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
  286. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
  287. package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
  288. package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
  289. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +28 -0
  290. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  291. package/dist/resolvers/FetchEntityVectorsResolver.js +117 -21
  292. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  293. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  294. package/dist/resolvers/FileCategoryResolver.js +1 -0
  295. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  296. package/dist/resolvers/FileResolver.d.ts +5 -0
  297. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  298. package/dist/resolvers/FileResolver.js +13 -4
  299. package/dist/resolvers/FileResolver.js.map +1 -1
  300. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  301. package/dist/resolvers/GetDataResolver.js +34 -13
  302. package/dist/resolvers/GetDataResolver.js.map +1 -1
  303. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
  304. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  305. package/dist/resolvers/IntegrationDiscoveryResolver.js +2713 -1290
  306. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  307. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  308. package/dist/resolvers/MCPResolver.js +13 -2
  309. package/dist/resolvers/MCPResolver.js.map +1 -1
  310. package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
  311. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  312. package/dist/resolvers/MergeRecordsResolver.js +31 -3
  313. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  314. package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
  315. package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
  316. package/dist/resolvers/PipelineProgressResolver.js +5 -3
  317. package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
  318. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  319. package/dist/resolvers/QueryResolver.js +20 -6
  320. package/dist/resolvers/QueryResolver.js.map +1 -1
  321. package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -0
  322. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  323. package/dist/resolvers/QuerySystemUserResolver.js +184 -88
  324. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  325. package/dist/resolvers/RSUResolver.d.ts.map +1 -1
  326. package/dist/resolvers/RSUResolver.js +12 -0
  327. package/dist/resolvers/RSUResolver.js.map +1 -1
  328. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  329. package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
  330. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  331. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +22 -2
  332. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  333. package/dist/resolvers/RealtimeClientSessionResolver.js +118 -33
  334. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  335. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
  336. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  337. package/dist/resolvers/RemoteBrowserActionResolver.js +224 -39
  338. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  339. package/dist/resolvers/RunAIAgentResolver.d.ts +80 -16
  340. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  341. package/dist/resolvers/RunAIAgentResolver.js +388 -125
  342. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  343. package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
  344. package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
  345. package/dist/resolvers/RunAIPromptResolver.js +19 -18
  346. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  347. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  348. package/dist/resolvers/RunTemplateResolver.js +7 -5
  349. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  350. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  351. package/dist/resolvers/RunTestResolver.js +3 -1
  352. package/dist/resolvers/RunTestResolver.js.map +1 -1
  353. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  354. package/dist/resolvers/SyncDataResolver.js +4 -0
  355. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  356. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  357. package/dist/resolvers/TestQuerySQLResolver.js +1 -0
  358. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  359. package/dist/resolvers/TransactionGroupResolver.d.ts +17 -2
  360. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  361. package/dist/resolvers/TransactionGroupResolver.js +60 -15
  362. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  363. package/dist/resolvers/UserViewResolver.d.ts +1 -1
  364. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  365. package/dist/resolvers/UserViewResolver.js +2 -1
  366. package/dist/resolvers/UserViewResolver.js.map +1 -1
  367. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  368. package/dist/resolvers/meetingRecordingRegistration.js +2 -0
  369. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  370. package/dist/rest/EntityCRUDHandler.d.ts +6 -0
  371. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  372. package/dist/rest/EntityCRUDHandler.js +19 -5
  373. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  374. package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
  375. package/dist/rest/MediaAccessKeys.js +6 -2
  376. package/dist/rest/MediaAccessKeys.js.map +1 -1
  377. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  378. package/dist/rest/OAuthCallbackHandler.js +11 -5
  379. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  380. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  381. package/dist/rest/RESTEndpointHandler.js +8 -5
  382. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  383. package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
  384. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
  385. package/dist/rest/RealtimeRecordingHandler.js +6 -8
  386. package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
  387. package/dist/rest/ViewOperationsHandler.d.ts +6 -0
  388. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  389. package/dist/rest/ViewOperationsHandler.js +24 -6
  390. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  391. package/dist/rest/setupRESTEndpoints.d.ts +3 -1
  392. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  393. package/dist/rest/setupRESTEndpoints.js +11 -2
  394. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  395. package/dist/serverRoleConfigUnits.d.ts +29 -0
  396. package/dist/serverRoleConfigUnits.d.ts.map +1 -0
  397. package/dist/serverRoleConfigUnits.js +33 -0
  398. package/dist/serverRoleConfigUnits.js.map +1 -0
  399. package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
  400. package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
  401. package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
  402. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  403. package/dist/services/TaskGraphActionRunner.js +2 -26
  404. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  405. package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
  406. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  407. package/dist/services/TaskGraphAgentRunner.js +38 -0
  408. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  409. package/dist/services/TaskGraphContinuationDeliverer.d.ts +5 -0
  410. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  411. package/dist/services/TaskGraphContinuationDeliverer.js +43 -15
  412. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  413. package/dist/services/WorkQueueHostService.d.ts +2 -1
  414. package/dist/services/WorkQueueHostService.d.ts.map +1 -1
  415. package/dist/services/WorkQueueHostService.js +19 -4
  416. package/dist/services/WorkQueueHostService.js.map +1 -1
  417. package/dist/services/workQueueConfig.d.ts +2 -2
  418. package/dist/services/workQueueConfig.js +5 -5
  419. package/dist/services/workQueueConfig.js.map +1 -1
  420. package/dist/sharedCache.js +1 -1
  421. package/dist/sharedCache.js.map +1 -1
  422. package/dist/types.d.ts +40 -1
  423. package/dist/types.d.ts.map +1 -1
  424. package/dist/types.js.map +1 -1
  425. package/package.json +98 -98
  426. package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
  427. package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
  428. package/src/__tests__/ActiveOperations.test.ts +68 -0
  429. package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
  430. package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
  431. package/src/__tests__/AgentSessionResolver.ownership.test.ts +150 -0
  432. package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
  433. package/src/__tests__/BatchApplyParity.test.ts +109 -0
  434. package/src/__tests__/BridgeHostInstance.test.ts +42 -0
  435. package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
  436. package/src/__tests__/ConnectionPause.test.ts +192 -0
  437. package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
  438. package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
  439. package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
  440. package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
  441. package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
  442. package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
  443. package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
  444. package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
  445. package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
  446. package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
  447. package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
  448. package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
  449. package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
  450. package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
  451. package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
  452. package/src/__tests__/MagicLinkKeys.test.ts +102 -0
  453. package/src/__tests__/MediaAccessKeys.test.ts +57 -10
  454. package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
  455. package/src/__tests__/ObjectNamesByID.test.ts +176 -0
  456. package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
  457. package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
  458. package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
  459. package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
  460. package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
  461. package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
  462. package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
  463. package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
  464. package/src/__tests__/RSUProgressBridge.test.ts +188 -5
  465. package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
  466. package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
  467. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
  468. package/src/__tests__/RealtimeClientSessionResolver.test.ts +346 -46
  469. package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
  470. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
  471. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
  472. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +100 -0
  473. package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
  474. package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
  475. package/src/__tests__/ResolverBase.clientOldValues.test.ts +344 -14
  476. package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
  477. package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
  478. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +227 -0
  479. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +83 -1
  480. package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
  481. package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
  482. package/src/__tests__/RunAIAgentResolver.branch.test.ts +72 -13
  483. package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
  484. package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
  485. package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
  486. package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
  487. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +19 -27
  488. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +10 -2
  489. package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
  490. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +91 -13
  491. package/src/__tests__/RunTemplateResolver.test.ts +35 -2
  492. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
  493. package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
  494. package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
  495. package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
  496. package/src/__tests__/SessionJanitor.test.ts +195 -4
  497. package/src/__tests__/SessionManager.test.ts +164 -0
  498. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
  499. package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
  500. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +114 -3
  501. package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
  502. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
  503. package/src/__tests__/ViewOperationsHandler.test.ts +9 -7
  504. package/src/__tests__/WidgetSessionService.test.ts +583 -4
  505. package/src/__tests__/WorkQueueHostService.test.ts +25 -7
  506. package/src/__tests__/apiRootBoot.test.ts +1 -1
  507. package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
  508. package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
  509. package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
  510. package/src/__tests__/cacheInvalidationRecordData.test.ts +45 -0
  511. package/src/__tests__/contextRequestOrigin.test.ts +105 -0
  512. package/src/__tests__/conversationBrowsers.test.ts +62 -0
  513. package/src/__tests__/fieldSecurityFixtures.ts +91 -0
  514. package/src/__tests__/globalCors.test.ts +3 -3
  515. package/src/__tests__/localDevAuth.test.ts +196 -0
  516. package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
  517. package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
  518. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
  519. package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
  520. package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
  521. package/src/__tests__/realtimeRecordingHandler.test.ts +24 -2
  522. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
  523. package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
  524. package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
  525. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +224 -7
  526. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
  527. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
  528. package/src/__tests__/requestOrigin.test.ts +104 -0
  529. package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
  530. package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
  531. package/src/__tests__/resolverBase.fls.test.ts +146 -97
  532. package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
  533. package/src/__tests__/runParamsTimeZone.test.ts +179 -0
  534. package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
  535. package/src/__tests__/runViewProperties.test.ts +114 -0
  536. package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
  537. package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
  538. package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
  539. package/src/__tests__/sessionDeadline.test.ts +51 -0
  540. package/src/__tests__/sessionUserClone.test.ts +5 -1
  541. package/src/__tests__/sharedCache.test.ts +11 -0
  542. package/src/__tests__/startupSweepOrder.test.ts +40 -0
  543. package/src/__tests__/unifiedAuth.test.ts +101 -1
  544. package/src/__tests__/widgetGuestElevation.test.ts +2 -0
  545. package/src/agentSessions/BridgeHostInstance.ts +20 -5
  546. package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
  547. package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
  548. package/src/agentSessions/SessionJanitor.ts +95 -45
  549. package/src/agentSessions/SessionManager.ts +73 -20
  550. package/src/agentSessions/conversationBrowsers.ts +143 -0
  551. package/src/agentSessions/sessionDeadline.ts +81 -0
  552. package/src/auth/APIKeyScopeAuth.ts +5 -4
  553. package/src/auth/AuthProviderCatalogRouter.ts +3 -0
  554. package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
  555. package/src/auth/index.ts +56 -12
  556. package/src/auth/initializeProviders.ts +43 -1
  557. package/src/auth/localDevAuth.ts +528 -0
  558. package/src/auth/loginEmailResolution.ts +67 -0
  559. package/src/auth/magicLink/MagicLinkKeys.ts +147 -15
  560. package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
  561. package/src/auth/magicLink/MagicLinkService.ts +250 -10
  562. package/src/auth/magicLink/index.ts +1 -1
  563. package/src/auth/magicLink/redeemLanding.ts +7 -4
  564. package/src/auth/magicLink/types.ts +38 -3
  565. package/src/auth/newUsers.ts +1 -0
  566. package/src/auth/sessionUserClone.ts +3 -2
  567. package/src/backgroundSweepConfigUnits.ts +213 -0
  568. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
  569. package/src/broadcast/index.ts +5 -0
  570. package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
  571. package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
  572. package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
  573. package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
  574. package/src/cache.ts +2 -1
  575. package/src/config.ts +138 -0
  576. package/src/context.ts +71 -14
  577. package/src/coreRoutes.ts +29 -7
  578. package/src/generated/graphql-schemas/__mj.ts +4145 -1193
  579. package/src/generic/CacheInvalidationResolver.ts +135 -78
  580. package/src/generic/OrphanedConversationDetailReconciler.ts +36 -3
  581. package/src/generic/PubSubManager.ts +54 -1
  582. package/src/generic/PushStatusResolver.ts +108 -11
  583. package/src/generic/ResolverBase.ts +635 -234
  584. package/src/generic/RunViewResolver.ts +176 -64
  585. package/src/generic/actionOutputFieldSecurity.ts +75 -0
  586. package/src/generic/fieldSecurityTransport.ts +62 -0
  587. package/src/index.ts +310 -85
  588. package/src/integration/ConnectionPause.ts +222 -0
  589. package/src/integration/CustomColumnPromoter.ts +129 -54
  590. package/src/integration/EntityMapLifecycle.ts +229 -6
  591. package/src/integration/InactiveRowWarnings.ts +50 -0
  592. package/src/integration/ObjectNamesByID.ts +97 -0
  593. package/src/integration/PostRestartIntrospect.ts +49 -0
  594. package/src/integration/RSUPostRestartProgress.ts +359 -0
  595. package/src/integration/RSUProgressBridge.ts +85 -2
  596. package/src/integration/RunArtifactAuthorization.ts +65 -0
  597. package/src/integration/SchemaRefreshLaunch.ts +12 -2
  598. package/src/integration/ScopedFieldsForBuild.ts +113 -0
  599. package/src/integration/TargetConfigGuard.ts +71 -0
  600. package/src/logging/variablesLoggingMiddleware.ts +59 -3
  601. package/src/realtimeSessions/README.md +7 -3
  602. package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
  603. package/src/realtimeSessions/ownedRealtimeSession.ts +16 -6
  604. package/src/realtimeSessions/sessionAccess.ts +211 -25
  605. package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
  606. package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
  607. package/src/realtimeSessions/verificationWorkflow.ts +3 -1
  608. package/src/realtimeWidget/WidgetRouter.ts +22 -4
  609. package/src/realtimeWidget/WidgetSessionService.ts +254 -17
  610. package/src/realtimeWidget/host-identity.ts +1 -1
  611. package/src/realtimeWidget/visitorIdentity.ts +1 -0
  612. package/src/realtimeWidget/widgetCore.ts +34 -9
  613. package/src/realtimeWidget/widgetGuestElevation.ts +3 -1
  614. package/src/requestOrigin.ts +64 -0
  615. package/src/resolvers/ActionResolver.ts +78 -15
  616. package/src/resolvers/AdhocQueryResolver.ts +1 -0
  617. package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
  618. package/src/resolvers/AgentSessionResolver.ts +50 -18
  619. package/src/resolvers/AutotagPipelineResolver.ts +2 -1
  620. package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
  621. package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
  622. package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
  623. package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
  624. package/src/resolvers/FileCategoryResolver.ts +1 -0
  625. package/src/resolvers/FileResolver.ts +14 -4
  626. package/src/resolvers/GetDataResolver.ts +35 -13
  627. package/src/resolvers/IntegrationDiscoveryResolver.ts +1570 -209
  628. package/src/resolvers/MCPResolver.ts +15 -2
  629. package/src/resolvers/MergeRecordsResolver.ts +23 -2
  630. package/src/resolvers/PipelineProgressResolver.ts +12 -3
  631. package/src/resolvers/QueryResolver.ts +20 -6
  632. package/src/resolvers/QuerySystemUserResolver.ts +207 -99
  633. package/src/resolvers/RSUResolver.ts +12 -0
  634. package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
  635. package/src/resolvers/RealtimeClientSessionResolver.ts +144 -40
  636. package/src/resolvers/RemoteBrowserActionResolver.ts +252 -37
  637. package/src/resolvers/RunAIAgentResolver.ts +518 -163
  638. package/src/resolvers/RunAIPromptResolver.ts +18 -18
  639. package/src/resolvers/RunTemplateResolver.ts +9 -5
  640. package/src/resolvers/RunTestResolver.ts +3 -1
  641. package/src/resolvers/SyncDataResolver.ts +4 -0
  642. package/src/resolvers/TestQuerySQLResolver.ts +1 -0
  643. package/src/resolvers/TransactionGroupResolver.ts +66 -15
  644. package/src/resolvers/UserViewResolver.ts +2 -1
  645. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
  646. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
  647. package/src/resolvers/meetingRecordingRegistration.ts +2 -0
  648. package/src/rest/EntityCRUDHandler.ts +22 -5
  649. package/src/rest/MediaAccessKeys.ts +6 -2
  650. package/src/rest/OAuthCallbackHandler.ts +13 -5
  651. package/src/rest/RESTEndpointHandler.ts +8 -5
  652. package/src/rest/RealtimeRecordingHandler.ts +9 -10
  653. package/src/rest/ViewOperationsHandler.ts +26 -7
  654. package/src/rest/setupRESTEndpoints.ts +11 -2
  655. package/src/serverRoleConfigUnits.ts +48 -0
  656. package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
  657. package/src/services/TaskGraphActionRunner.ts +2 -23
  658. package/src/services/TaskGraphAgentRunner.ts +43 -0
  659. package/src/services/TaskGraphContinuationDeliverer.ts +53 -20
  660. package/src/services/WorkQueueHostService.ts +26 -4
  661. package/src/services/workQueueConfig.ts +5 -5
  662. package/src/sharedCache.ts +1 -1
  663. package/src/types.ts +41 -1
  664. package/src/services/TaskOrchestration-Integration.md +0 -188
@@ -1,5 +1,9 @@
1
- import { Ctx, Field, ObjectType, Resolver, Root, Subscription } from 'type-graphql';
2
- import { Metadata, UserInfo } from '@memberjunction/core';
1
+ import 'reflect-metadata';
2
+ import { Arg, Ctx, Field, Int, ObjectType, Query, Resolver, Root, Subscription } from 'type-graphql';
3
+ import { EntityInfo, Metadata, RecordChangeFieldSecurityProjector, RecordChangesEntityName, UserInfo } from '@memberjunction/core';
4
+ import {
5
+ CacheInvalidationBroadcastManager,
6
+ } from '../broadcast/index.js';
3
7
 
4
8
  export const CACHE_INVALIDATION_TOPIC = 'CACHE_INVALIDATION';
5
9
 
@@ -36,22 +40,55 @@ export function ConfigureRecordDataBroadcast(entities: readonly string[] | undef
36
40
  *
37
41
  * The subscription below is filtered only by ENTITY-level read permission, so anything included
38
42
  * here is disclosed to every signed-in session that may read the entity at all — regardless of
39
- * row-level security or any tenant scoping a consumer applies on the read path, neither of which
40
- * this push traverses. The answer is therefore NO unless a deployment has explicitly opted the
41
- * entity in via `cacheSettings.recordDataBroadcastEntities`.
43
+ * row-level security, field-level security, or any tenant scoping a consumer applies on the read
44
+ * path, none of which this push traverses. The answer is therefore NO unless a deployment has
45
+ * explicitly opted the entity in via `cacheSettings.recordDataBroadcastEntities`, and always NO
46
+ * for an entity under field-level security (its own flag or an IS-A ancestor's), and for
47
+ * `MJ: Record Changes`, whatever the allowlist says: the row would carry columns (or, for Record
48
+ * Changes, other entities' values) some of those sessions may not read.
42
49
  *
43
50
  * Callers that get `false` simply omit `recordData`; the event still carries the entity name and
44
51
  * primary key, so clients evict and re-fetch through the normal access-controlled read path.
45
52
  *
46
53
  * Matching is exact (trimmed, case-insensitive) rather than substring: a loose match would let an
47
54
  * allowlisted name drag in every entity whose name contains it.
55
+ *
56
+ * @param entityInfo The entity's metadata, when the caller holds it. Otherwise it is looked up by
57
+ * name, so the field-security refusal applies either way.
48
58
  */
49
- export function MayBroadcastRecordData(entityName: string): boolean {
59
+ export function MayBroadcastRecordData(entityName: string, entityInfo?: EntityInfo | null): boolean {
50
60
  if (allowedRecordDataEntities.length === 0) return false;
61
+ if (fieldSecurityApplies(entityName, entityInfo)) return false;
62
+ if (isRecordChanges(entityName, entityInfo)) return false;
51
63
  if (allowedRecordDataEntities.includes('*')) return true;
52
64
  return allowedRecordDataEntities.includes(entityName.trim().toLowerCase());
53
65
  }
54
66
 
67
+ /** Whether field-level security applies to the entity, resolving it by name when not supplied. */
68
+ function fieldSecurityApplies(entityName: string, entityInfo: EntityInfo | null | undefined): boolean {
69
+ const info = entityInfo ?? lookUpEntity(entityName);
70
+ return Boolean(info?.FieldLevelSecurityApplies);
71
+ }
72
+
73
+ /**
74
+ * Whether the entity is the Record Changes audit trail. Its rows carry other entities' values in
75
+ * `ChangesJSON` and `FullRecordJSON`, which are projected per reader, so a row is never broadcast
76
+ * even though field-level security is not switched on for the audit entity itself.
77
+ */
78
+ function isRecordChanges(entityName: string, entityInfo: EntityInfo | null | undefined): boolean {
79
+ if (entityInfo) return RecordChangeFieldSecurityProjector.IsRecordChangesEntity(entityInfo);
80
+ return entityName.trim().toLowerCase() === RecordChangesEntityName.toLowerCase();
81
+ }
82
+
83
+ /** The entity by name from the process's metadata, or undefined when none is loaded. */
84
+ function lookUpEntity(entityName: string): EntityInfo | undefined {
85
+ try {
86
+ return new Metadata().EntityByName(entityName) ?? undefined; // global-provider-ok: metadata lookup for a process-wide broadcast gate
87
+ } catch {
88
+ return undefined;
89
+ }
90
+ }
91
+
55
92
  @ObjectType()
56
93
  export class CacheInvalidationNotification {
57
94
  @Field(() => String)
@@ -74,6 +111,48 @@ export class CacheInvalidationNotification {
74
111
 
75
112
  @Field(() => String, { nullable: true })
76
113
  RecordData?: string;
114
+
115
+ @Field(() => Int, { nullable: true })
116
+ Sequence?: number;
117
+ }
118
+
119
+ @ObjectType()
120
+ export class CacheInvalidationCatchUpResult {
121
+ @Field(() => Boolean)
122
+ RequiresFullRefresh!: boolean;
123
+
124
+ @Field(() => Int)
125
+ CurrentSequence!: number;
126
+
127
+ @Field(() => String)
128
+ ServerProcessID!: string;
129
+
130
+ @Field(() => [CacheInvalidationNotification])
131
+ Events!: CacheInvalidationNotification[];
132
+ }
133
+
134
+ @ObjectType()
135
+ export class CacheBroadcastConnectionToken {
136
+ @Field(() => String)
137
+ Provider!: string;
138
+
139
+ @Field(() => String)
140
+ Url!: string;
141
+
142
+ @Field(() => String, { nullable: true })
143
+ Token?: string;
144
+
145
+ @Field(() => [String])
146
+ Groups!: string[];
147
+
148
+ @Field(() => String)
149
+ ExpiresAt!: string;
150
+
151
+ @Field(() => String)
152
+ ServerProcessID!: string;
153
+
154
+ @Field(() => Int)
155
+ CurrentSequence!: number;
77
156
  }
78
157
 
79
158
  /**
@@ -88,6 +167,7 @@ export interface CacheInvalidationPayload {
88
167
  timestamp: Date;
89
168
  originSessionId?: string;
90
169
  recordData?: string;
170
+ sequence?: number;
91
171
  }
92
172
 
93
173
  /**
@@ -116,39 +196,23 @@ export interface CacheInvalidationFilterContext {
116
196
  * see the class docblock below.
117
197
  *
118
198
  * `GetUserPermisions` is an in-memory match of the entity's permission rows against the user's
119
- * roles, so this stays cheap enough to run per subscriber per event. It is not free: it runs for
120
- * every connected socket on every save, so keep it free of I/O.
199
+ * roles, memoized per `(payload, entityName, roleFingerprint)` by the active
200
+ * {@link BaseCacheInvalidationBroadcastProvider} so $N$ connected subscribers sharing $R$ role
201
+ * combinations only run `GetUserPermisions` $R$ times per event.
121
202
  */
122
203
  export function CacheInvalidationFilter(data: {
123
204
  payload: CacheInvalidationPayload;
124
205
  context: CacheInvalidationFilterContext | undefined;
125
206
  }): boolean {
126
207
  const user = data.context?.userPayload?.userRecord as UserInfo | undefined;
127
- // FAIL CLOSED on identity, matching `statusUpdatesFilter`. `onConnect` rejects a socket whose
128
- // token does not validate, so a subscriber with no user record should not exist; if one does,
129
- // it is the case least deserving of an unfiltered firehose.
130
208
  if (!user) {
131
209
  return false;
132
210
  }
133
-
134
- const entityName = data.payload?.entityName;
135
- if (!entityName) {
136
- return false;
137
- }
138
-
139
- // A pub/sub subscription filter has no per-request provider to thread: it runs on the server's
140
- // own metadata, which is the one place the entity's permission rows can be answered from.
141
- const entity = new Metadata().EntityByName(entityName); // global-provider-ok: subscription filter — server-wide metadata, no request-scoped provider exists here
142
- // DELIVER when the entity is unknown here, deliberately — the opposite of the choice above.
143
- // A name absent from metadata cannot be permission-checked, and withholding would silently
144
- // stop invalidating a legitimately cacheable entity, which is a correctness bug rather than a
145
- // disclosure one. All it discloses is the name and key of something this server cannot
146
- // describe.
147
- if (!entity) {
148
- return true;
149
- }
150
-
151
- return entity.GetUserPermisions(user).CanRead;
211
+ return CacheInvalidationBroadcastManager.Instance.Provider.EvaluateEntityReadAccess(
212
+ data.payload,
213
+ user,
214
+ (entityName) => new Metadata().EntityByName(entityName) // global-provider-ok: subscription filter — server-wide metadata, no request-scoped provider exists here
215
+ );
152
216
  }
153
217
 
154
218
  /** The part of a permission row and of a user this module reads, so the rule can be tested on plain objects. */
@@ -174,39 +238,23 @@ export interface RoleHolder {
174
238
  * The same in-memory match `GetUserPermisions` does, with no I/O, so it can run per subscriber per event.
175
239
  */
176
240
  export function ReadIsRowFiltered(entity: { Permissions: ReadonlyArray<ReadPermissionRow> }, user: RoleHolder): boolean {
177
- const roles = new Set((user.UserRoles ?? []).map((role) => (role.RoleID ?? '').trim().toLowerCase()));
178
- let filteredReads = 0;
179
- for (const row of entity.Permissions) {
180
- if (!row.CanRead) continue;
181
- const isDeny = row.IsDeny ?? (row.Type ?? 'Allow').trim().toLowerCase() === 'deny';
182
- if (isDeny) continue;
183
- if (!roles.has((row.RoleID ?? '').trim().toLowerCase())) continue;
184
- if (!row.ReadRLSFilterID) return false;
185
- filteredReads += 1;
186
- }
187
- return filteredReads > 0;
241
+ return CacheInvalidationBroadcastManager.Instance.Provider.ReadIsRowFiltered(entity, user);
188
242
  }
189
243
 
190
244
  /**
191
245
  * The event as one subscriber may see it. A subscriber whose read of the entity is row-filtered gets the entity, the action and
192
246
  * the time, and neither the key nor the row: "something in this entity changed", which the client already takes as a
193
247
  * whole-entity invalidation (a null key on `remote-invalidate`). Everyone else gets the event as published.
248
+ *
249
+ * Memoized per `(payload, entity, roleFingerprint)` via the active broadcast provider so $N$ subscribers
250
+ * sharing $R$ role buckets only allocate and evaluate `ReadIsRowFiltered` $R$ times per event.
194
251
  */
195
252
  export function ShapeCacheInvalidationEvent(
196
253
  payload: CacheInvalidationPayload,
197
254
  user: RoleHolder | undefined,
198
255
  entity: { Permissions: ReadonlyArray<ReadPermissionRow> } | null | undefined,
199
256
  ): CacheInvalidationNotification {
200
- const withholdKey = !!user && !!entity && ReadIsRowFiltered(entity, user);
201
- return {
202
- EntityName: payload.entityName,
203
- PrimaryKeyValues: withholdKey ? undefined : (payload.primaryKeyValues ?? undefined),
204
- Action: payload.action,
205
- SourceServerID: payload.sourceServerId,
206
- Timestamp: payload.timestamp,
207
- OriginSessionID: payload.originSessionId ?? undefined,
208
- RecordData: withholdKey ? undefined : (payload.recordData ?? undefined),
209
- };
257
+ return CacheInvalidationBroadcastManager.Instance.Provider.ShapeEventForSubscriber(payload, user, entity);
210
258
  }
211
259
 
212
260
  /** @deprecated Use {@link CacheInvalidationFilter}. */
@@ -223,30 +271,8 @@ export class CacheInvalidationResolver {
223
271
  * Subscription that broadcasts cache invalidation events to connected clients, so cross-server
224
272
  * cache invalidation reaches browsers.
225
273
  *
226
- * Delivery is filtered only by ENTITY-level read permission (see {@link CacheInvalidationFilter}).
227
- * Every session that may read an entity at all still receives every event for it, from every
228
- * other session and tenant.
229
- *
230
- * Because that narrowing stops well short of row level, `RecordData` is only populated for entities a
231
- * deployment has opted in through `cacheSettings.recordDataBroadcastEntities` — see
232
- * {@link MayBroadcastRecordData}, applied at both publish sites.
233
- *
234
- * `EntityName`, `PrimaryKeyValues`, `Action` and `Timestamp` ARE still broadcast to every
235
- * session, and that is a disclosure, not a safe residue. An earlier version of this comment
236
- * called them "safe to broadcast" on the grounds that reading the record still goes through
237
- * the access-controlled path — true of the row's CONTENTS, and beside the point for the
238
- * metadata itself. A session with no relationship to a record still learns that it exists,
239
- * its stable key, and every time it changes; across entities it learns the cadence and volume
240
- * of another tenant's activity.
241
- *
242
- * The key is kept for a subscriber who could read the row anyway, because consumers need it to
243
- * re-read the record they were told about (see `ResolveEntityEventKey` in @memberjunction/core),
244
- * and the coarse "something in this entity changed" forces whole-entity invalidation on the
245
- * hottest write paths. It is withheld, with the row, from a subscriber whose every read of the
246
- * entity goes through a row-level security filter ({@link ReadIsRowFiltered}): a filter the
247
- * subscription cannot evaluate per event stands between them and the row, so they learn only
248
- * that a row of the entity changed, and their caches refresh the entity as a whole. That is the
249
- * same in-memory role match as the entity-level filter, once more per subscriber per event.
274
+ * Delivery is filtered by ENTITY-level read permission (see {@link CacheInvalidationFilter})
275
+ * and shaped per role-fingerprint bucket (see {@link ShapeCacheInvalidationEvent}).
250
276
  */
251
277
  @Subscription(() => CacheInvalidationNotification, {
252
278
  topics: CACHE_INVALIDATION_TOPIC,
@@ -258,8 +284,39 @@ export class CacheInvalidationResolver {
258
284
  @Ctx() context: CacheInvalidationFilterContext | undefined
259
285
  ): CacheInvalidationNotification {
260
286
  const user = context?.userPayload?.userRecord as UserInfo | undefined;
261
- // The same server-wide metadata the filter read; an entity unknown here was delivered whole by the filter's own choice
262
- const entity = payload?.entityName ? new Metadata().EntityByName(payload.entityName) : null; // global-provider-ok: subscription resolver — server-wide metadata, no request-scoped provider exists here
263
- return ShapeCacheInvalidationEvent(payload, user, entity);
287
+ const provider = CacheInvalidationBroadcastManager.Instance.Provider;
288
+ const entity = payload?.entityName ? provider.ResolveEntityForPayload(payload) : null;
289
+ return provider.ShapeEventForSubscriber(payload, user, entity);
290
+ }
291
+
292
+ /**
293
+ * Returns all permission-allowed, RLS-shaped cache invalidation events strictly after
294
+ * `sinceSequence` from the server's bounded circular ring buffer.
295
+ *
296
+ * Invoked by `GraphQLDataProvider` when an HTTP response's `X-MJ-Cache-Seq` header or a
297
+ * WebSocket reconnect reveals missed invalidation sequence numbers.
298
+ */
299
+ @Query(() => CacheInvalidationCatchUpResult)
300
+ GetCacheInvalidationsSince(
301
+ @Arg('sinceSequence', () => Int) sinceSequence: number,
302
+ @Ctx() context: CacheInvalidationFilterContext | undefined
303
+ ): CacheInvalidationCatchUpResult {
304
+ const user = context?.userPayload?.userRecord as UserInfo | undefined;
305
+ return CacheInvalidationBroadcastManager.Instance.Provider.GetChangesSince(sinceSequence, user);
306
+ }
307
+
308
+ /**
309
+ * Negotiates a client broadcast connection (URL, signed token, and authorized role-bucket groups)
310
+ * for the active {@link BaseCacheInvalidationBroadcastProvider}.
311
+ */
312
+ @Query(() => CacheBroadcastConnectionToken)
313
+ async NegotiateCacheBroadcastConnection(
314
+ @Ctx() context: CacheInvalidationFilterContext | undefined
315
+ ): Promise<CacheBroadcastConnectionToken> {
316
+ const user = context?.userPayload?.userRecord as UserInfo | undefined;
317
+ if (!user) {
318
+ throw new Error('Authentication required to negotiate cache broadcast connection.');
319
+ }
320
+ return CacheInvalidationBroadcastManager.Instance.Provider.NegotiateClientConnection(user);
264
321
  }
265
322
  }
@@ -1,8 +1,9 @@
1
1
  import { LogError, LogStatus, RunView } from '@memberjunction/core';
2
- import { IndexByUUID } from '@memberjunction/global';
2
+ import { IndexByUUID, ShutdownRegistry } from '@memberjunction/global';
3
+ import { DEFAULT_CONVERSATION_DETAIL_RECONCILER_SETTINGS, type ConversationDetailReconcilerSettings } from '../backgroundSweepConfigUnits.js';
3
4
  import { UserCache } from '@memberjunction/sqlserver-dataprovider';
4
5
  import type { IMetadataProvider, UserInfo } from '@memberjunction/core';
5
- import type { MJAIAgentRunEntity, MJConversationDetailEntity } from '@memberjunction/core-entities';
6
+ import type { MJAIAgentRunEntity, MJConversationDetailEntity, MJConversationDetailEntityExtended } from '@memberjunction/core-entities';
6
7
 
7
8
  /**
8
9
  * Grace period after a run reaches a terminal state before its conversation detail is considered
@@ -110,7 +111,9 @@ export async function ReconcileOrphanedConversationDetails(
110
111
  LogError(`[OrphanDetailReconciler] No owner resolved for conversation ${detail.ConversationID}; leaving detail ${detail.ID}`);
111
112
  continue;
112
113
  }
113
- const writable = await provider.GetEntityObject<MJConversationDetailEntity>('MJ: Conversation Details', owner);
114
+ const writable = await provider.GetEntityObject<MJConversationDetailEntityExtended>('MJ: Conversation Details', owner);
115
+ // Closing an agent's reply is the server's write: unmarked, the gate refuses any change to what a reply says.
116
+ writable.MarkServerAuthoredReply();
114
117
  if (!(await writable.Load(detail.ID))) {
115
118
  LogError(`[OrphanDetailReconciler] Could not load detail ${detail.ID} for write`);
116
119
  continue;
@@ -265,3 +268,33 @@ async function loadConversationOwners(
265
268
  }
266
269
  return owners;
267
270
  }
271
+
272
+ /**
273
+ * Runs {@link ReconcileOrphanedConversationDetails} once now (closes what a restart orphaned) and,
274
+ * when `settings.enabled`, again every `settings.sweepIntervalMs` (closes mid-life orphans),
275
+ * registering the timer for graceful shutdown. With `enabled` false only the startup pass runs, so an
276
+ * idle server sends no periodic queries for it (`conversationDetailReconciler`; see the Serverless
277
+ * Database Auto-Pause guide). A failed pass is logged, never thrown.
278
+ *
279
+ * @returns The repeat timer, or `null` when no repeat was scheduled.
280
+ */
281
+ export function StartOrphanedConversationDetailReconciler(
282
+ provider: IMetadataProvider,
283
+ contextUser: UserInfo,
284
+ settings: ConversationDetailReconcilerSettings = DEFAULT_CONVERSATION_DETAIL_RECONCILER_SETTINGS
285
+ ): ReturnType<typeof setInterval> | null {
286
+ const pass = (): void => {
287
+ void ReconcileOrphanedConversationDetails(provider, contextUser)
288
+ .catch(err => LogError(`[OrphanDetailReconciler] Pass failed: ${err instanceof Error ? err.message : String(err)}`));
289
+ };
290
+ pass();
291
+ if (!settings.enabled) {
292
+ return null;
293
+ }
294
+ const timer = setInterval(pass, settings.sweepIntervalMs);
295
+ ShutdownRegistry.Instance.Register({
296
+ ShutdownName: 'OrphanDetailReconciler',
297
+ Shutdown: () => { clearInterval(timer); },
298
+ });
299
+ return timer;
300
+ }
@@ -1,5 +1,45 @@
1
1
  import { PubSubEngine } from 'type-graphql';
2
2
  import { BaseSingleton } from '@memberjunction/global';
3
+ import {
4
+ CACHE_INVALIDATION_TOPIC,
5
+ type CacheInvalidationPayload,
6
+ } from './CacheInvalidationResolver.js';
7
+ import {
8
+ GetSessionStatusTopic,
9
+ PUSH_STATUS_UPDATES_TOPIC,
10
+ } from './PushStatusResolver.js';
11
+ import { CacheInvalidationBroadcastManager } from '../broadcast/index.js';
12
+
13
+ const _wrappedPubSubEngines = new WeakSet<PubSubEngine>();
14
+
15
+ /**
16
+ * Wraps a TypeGraphQL `PubSubEngine` so that publishes to {@link PUSH_STATUS_UPDATES_TOPIC}
17
+ * carrying a specific `sessionId` (`sessionId !== '*'`) are dynamically routed in $O(1)$ to
18
+ * `PUSH_STATUS_UPDATES:session:<sessionId>` instead of waking every connected browser tab.
19
+ * Wildcard (`sessionId === '*'`) updates continue to publish on {@link PUSH_STATUS_UPDATES_TOPIC}.
20
+ */
21
+ export function CreateSessionRoutingPubSub(pubSub: PubSubEngine): PubSubEngine {
22
+ if (!pubSub || typeof pubSub.publish !== 'function' || _wrappedPubSubEngines.has(pubSub)) {
23
+ return pubSub;
24
+ }
25
+ const rawPublish = pubSub.publish.bind(pubSub);
26
+ pubSub.publish = async (routingKey: string, payload: unknown): Promise<void> => {
27
+ if (
28
+ routingKey === PUSH_STATUS_UPDATES_TOPIC &&
29
+ typeof payload === 'object' &&
30
+ payload !== null
31
+ ) {
32
+ const sessionId = (payload as { sessionId?: unknown }).sessionId;
33
+ if (typeof sessionId === 'string' && sessionId.trim().length > 0 && sessionId.trim() !== '*') {
34
+ await rawPublish(GetSessionStatusTopic(sessionId), payload);
35
+ return;
36
+ }
37
+ }
38
+ await rawPublish(routingKey, payload);
39
+ };
40
+ _wrappedPubSubEngines.add(pubSub);
41
+ return pubSub;
42
+ }
3
43
 
4
44
  /**
5
45
  * Singleton manager that holds a reference to the type-graphql PubSubEngine,
@@ -20,9 +60,10 @@ export class PubSubManager extends BaseSingleton<PubSubManager> {
20
60
  /**
21
61
  * Sets the PubSubEngine instance. Should be called once during server startup
22
62
  * after buildSchemaSync creates the PubSub instance.
63
+ * Automatically installs $O(1)$ dynamic session routing for `PUSH_STATUS_UPDATES`.
23
64
  */
24
65
  public SetPubSubEngine(pubSub: PubSubEngine): void {
25
- this._pubSub = pubSub;
66
+ this._pubSub = CreateSessionRoutingPubSub(pubSub);
26
67
  }
27
68
 
28
69
  /**
@@ -34,9 +75,21 @@ export class PubSubManager extends BaseSingleton<PubSubManager> {
34
75
 
35
76
  /**
36
77
  * Publishes a payload to the specified topic via the PubSubEngine.
78
+ * For `CACHE_INVALIDATION`, automatically stamps a monotonic sequence number and
79
+ * records the event in the active {@link BaseCacheInvalidationBroadcastProvider}'s ring buffer.
37
80
  * No-op if the PubSubEngine has not been configured yet.
38
81
  */
39
82
  public Publish(topic: string, payload: Record<string, unknown>): void {
83
+ if (topic === CACHE_INVALIDATION_TOPIC) {
84
+ const provider = CacheInvalidationBroadcastManager.Instance.Provider;
85
+ const entityName = typeof payload.entityName === 'string' ? payload.entityName : undefined;
86
+ if (!provider.ShouldBroadcastEntity(entityName)) {
87
+ return;
88
+ }
89
+ if (payload.sequence === undefined) {
90
+ provider.RecordInvalidation(payload as unknown as CacheInvalidationPayload);
91
+ }
92
+ }
40
93
  if (this._pubSub) {
41
94
  this._pubSub.publish(topic, payload);
42
95
  } else {
@@ -1,6 +1,8 @@
1
+ import 'reflect-metadata';
1
2
  import { Arg, Field, ID, ObjectType, PubSubEngine, Resolver, ResolverFilterData, Root, Subscription } from 'type-graphql';
2
3
  import { MJGlobal, UUIDsEqual } from '@memberjunction/global';
3
4
  import { UserPayload } from '../types.js';
5
+ import { ResolveSessionScopeIdentity, type SessionAccessPrincipal } from '../realtimeSessions/sessionAccess.js';
4
6
 
5
7
  export const PUSH_STATUS_UPDATES_TOPIC = 'PUSH_STATUS_UPDATES';
6
8
 
@@ -94,6 +96,57 @@ export function ParseReplicatedStatusUpdate(raw: string, localServerId: string):
94
96
  return { sessionId, ownerUserId, message: body, SourceServerId: source };
95
97
  }
96
98
 
99
+ /**
100
+ * Returns the $O(1)$ session-scoped pub/sub topic name for a given `sessionId`.
101
+ * Wildcard (`'*'`) or empty session IDs fall back to the broadcast {@link PUSH_STATUS_UPDATES_TOPIC}.
102
+ */
103
+ export function GetSessionStatusTopic(sessionId: string): string {
104
+ const normalized = sessionId?.trim();
105
+ if (!normalized || normalized === '*') {
106
+ return PUSH_STATUS_UPDATES_TOPIC;
107
+ }
108
+ return `${PUSH_STATUS_UPDATES_TOPIC}:session:${normalized}`;
109
+ }
110
+
111
+ interface ParsedMessageCacheEntry {
112
+ parsed: Record<string, unknown> | null;
113
+ isJson: boolean;
114
+ }
115
+
116
+ const _parsedMessageMemo = new WeakMap<PushStatusNotificationPayload, ParsedMessageCacheEntry>();
117
+
118
+ /**
119
+ * Parses and memoizes the JSON `message` envelope on a {@link PushStatusNotificationPayload}
120
+ * in a `WeakMap` so multiple consumers (`ShouldReplicateStatusUpdate`, filters, hooks) never
121
+ * call `JSON.parse` more than once per payload object.
122
+ */
123
+ export function ParseStatusUpdateMessage(
124
+ payload: PushStatusNotificationPayload
125
+ ): ParsedMessageCacheEntry {
126
+ const cached = _parsedMessageMemo.get(payload);
127
+ if (cached) {
128
+ return cached;
129
+ }
130
+ if (!payload.message) {
131
+ const emptyEntry: ParsedMessageCacheEntry = { parsed: null, isJson: false };
132
+ _parsedMessageMemo.set(payload, emptyEntry);
133
+ return emptyEntry;
134
+ }
135
+ try {
136
+ const raw: unknown = JSON.parse(payload.message);
137
+ const entry: ParsedMessageCacheEntry = {
138
+ parsed: typeof raw === 'object' && raw !== null ? (raw as Record<string, unknown>) : null,
139
+ isJson: true,
140
+ };
141
+ _parsedMessageMemo.set(payload, entry);
142
+ return entry;
143
+ } catch {
144
+ const plainEntry: ParsedMessageCacheEntry = { parsed: null, isJson: false };
145
+ _parsedMessageMemo.set(payload, plainEntry);
146
+ return plainEntry;
147
+ }
148
+ }
149
+
97
150
  /**
98
151
  * Whether an update is worth sending to other server instances.
99
152
  *
@@ -103,10 +156,20 @@ export function ParseReplicatedStatusUpdate(raw: string, localServerId: string):
103
156
  * Progress and completion are low-rate and each is individually meaningful, which is exactly the
104
157
  * kind of message that must survive landing on the wrong replica.
105
158
  */
106
- export function ShouldReplicateStatusUpdate(message?: string): boolean {
159
+ export function ShouldReplicateStatusUpdate(
160
+ message?: string,
161
+ payload?: PushStatusNotificationPayload
162
+ ): boolean {
107
163
  if (!message) {
108
164
  return false;
109
165
  }
166
+ if (payload && payload.message === message) {
167
+ const entry = ParseStatusUpdateMessage(payload);
168
+ if (!entry.isJson) {
169
+ return true;
170
+ }
171
+ return entry.parsed?.type !== 'StreamingContent';
172
+ }
110
173
  try {
111
174
  const parsed: unknown = JSON.parse(message);
112
175
  const type = (parsed as { type?: unknown })?.type;
@@ -150,7 +213,7 @@ export function PublishStatusUpdate(pubSub: PubSubEngine, params: StatusUpdatePa
150
213
  // Fan out to other instances. Only reached by updates originating HERE: a message arriving from
151
214
  // the bus is republished straight onto the local topic and never comes back through this
152
215
  // function, so there is no loop to break beyond the SourceServerId check on the receiving side.
153
- if (_publishHook && ShouldReplicateStatusUpdate(params.message)) {
216
+ if (_publishHook && ShouldReplicateStatusUpdate(params.message, payload)) {
154
217
  try {
155
218
  _publishHook(payload);
156
219
  } catch {
@@ -170,18 +233,47 @@ export interface StatusUpdatesFilterContext {
170
233
  userPayload?: UserPayload;
171
234
  }
172
235
 
236
+ /**
237
+ * The owner key of a status update for `user`: its user ID, or, for an anonymous visitor, its user ID plus its scope
238
+ * identity (`ResolveSessionScopeIdentity`). Every anonymous visitor shares one Anonymous user and the session id is
239
+ * chosen by the client (`x-session-id`), so the user ID alone would let one visitor receive another's run events.
240
+ * An anonymous visitor with no scope identity gets no key and receives nothing.
241
+ */
242
+ export function StatusUpdateOwnerKey(user: SessionAccessPrincipal | null | undefined): string {
243
+ if (!user?.ID) {
244
+ return '';
245
+ }
246
+ if (!user.IsMagicLinkAnonymous) {
247
+ return user.ID;
248
+ }
249
+ const scope = ResolveSessionScopeIdentity(user);
250
+ return scope ? `${user.ID.toLowerCase()}|${scope}` : '';
251
+ }
252
+
253
+ /**
254
+ * The owner key a status update is published with: that of the request's user, or, on a payload elevated by
255
+ * `ElevateUserPayload`, of the user the elevated principal stands in for (a public widget guest). The guest's socket
256
+ * is authenticated as the guest, so an update stamped with the elevated system user would never pass
257
+ * {@link StatusUpdatesFilter} and the guest would wait forever for its run to finish.
258
+ */
259
+ export function StatusUpdateOwnerID(userPayload: UserPayload | undefined): string {
260
+ return StatusUpdateOwnerKey(userPayload?.ElevatedFrom ?? userPayload?.userRecord);
261
+ }
262
+
173
263
  /**
174
264
  * Filter predicate for the `statusUpdates` subscription. Exported so it can be unit-tested in
175
265
  * isolation (it is the security-critical gate). A push reaches a subscriber only when BOTH hold:
176
- * 1. the push's `sessionId` matches the subscriber's requested `sessionId` (tab routing), AND
177
- * 2. the push's `ownerUserId` matches the subscriber CONNECTION's authenticated identity
178
- * (`context.userPayload.userRecord.ID`, established once at WS connect).
266
+ * 1. the push's `sessionId` matches the subscriber's requested `sessionId` (tab routing), or is `'*'`, AND
267
+ * 2. the push's `ownerUserId` matches the owner key ({@link StatusUpdateOwnerKey}) of the subscriber
268
+ * CONNECTION's authenticated identity (`context.userPayload.userRecord`, established once at WS
269
+ * connect): the user ID for a named user, compared as a UUID; for an anonymous visitor, the user ID
270
+ * plus its scope identity, compared exactly because the scope part is case-significant.
179
271
  *
180
272
  * Condition (2) is the fix for the session-hijack class (B49): `sessionId` is a client-chosen
181
273
  * correlation value, so a subscriber who lifts another user's `sessionId` would previously receive
182
274
  * their pushes. Binding delivery to the connection's server-authenticated identity means knowing a
183
- * `sessionId` is no longer sufficient. Fails CLOSED — a missing owner or connection identity never
184
- * matches.
275
+ * `sessionId` is no longer sufficient; the scope part does the same between anonymous visitors, who all
276
+ * share one Anonymous user. Fails CLOSED — a missing owner or connection key never matches.
185
277
  */
186
278
  export function StatusUpdatesFilter(data: {
187
279
  payload: PushStatusNotificationPayload;
@@ -192,11 +284,13 @@ export function StatusUpdatesFilter(data: {
192
284
  if (payload.sessionId !== '*' && payload.sessionId !== args.sessionId) {
193
285
  return false;
194
286
  }
195
- const connectionUserId: string | undefined = context?.userPayload?.userRecord?.ID;
196
- if (!connectionUserId || !payload.ownerUserId) {
287
+ const connectionUser: SessionAccessPrincipal | undefined = context?.userPayload?.userRecord;
288
+ const connectionKey = StatusUpdateOwnerKey(connectionUser);
289
+ if (!connectionKey || !payload.ownerUserId) {
197
290
  return false; // fail closed — no identity on either side means no delivery
198
291
  }
199
- return UUIDsEqual(payload.ownerUserId, connectionUserId);
292
+ // An anonymous visitor's key carries its scope identity (case-significant), so it must match exactly.
293
+ return connectionUser?.IsMagicLinkAnonymous ? payload.ownerUserId === connectionKey : UUIDsEqual(payload.ownerUserId, connectionKey);
200
294
  }
201
295
 
202
296
  /** @deprecated Use {@link StatusUpdatesFilter}. */
@@ -211,7 +305,10 @@ export function statusUpdatesFilter(data: {
211
305
  @Resolver()
212
306
  export class PushStatusResolver {
213
307
  @Subscription(() => PushStatusNotification, {
214
- topics: PUSH_STATUS_UPDATES_TOPIC,
308
+ topics: ({ args }: { args: PushStatusNotificationArgs }) =>
309
+ args?.sessionId && args.sessionId !== '*'
310
+ ? [GetSessionStatusTopic(args.sessionId), PUSH_STATUS_UPDATES_TOPIC]
311
+ : PUSH_STATUS_UPDATES_TOPIC,
215
312
  filter: (data: ResolverFilterData<PushStatusNotificationPayload, PushStatusNotificationArgs, StatusUpdatesFilterContext>) =>
216
313
  StatusUpdatesFilter(data),
217
314
  })