@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.
- package/README.md +96 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
- package/dist/agentSessions/BridgeHostInstance.js +14 -4
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
- package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
- package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
- package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
- package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +34 -11
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +88 -44
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +29 -9
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +62 -16
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
- package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
- package/dist/agentSessions/conversationBrowsers.js +118 -0
- package/dist/agentSessions/conversationBrowsers.js.map +1 -0
- package/dist/agentSessions/sessionDeadline.d.ts +43 -0
- package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
- package/dist/agentSessions/sessionDeadline.js +68 -0
- package/dist/agentSessions/sessionDeadline.js.map +1 -0
- package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.js +5 -4
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +2 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +51 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +10 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +37 -1
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/localDevAuth.d.ts +79 -0
- package/dist/auth/localDevAuth.d.ts.map +1 -0
- package/dist/auth/localDevAuth.js +439 -0
- package/dist/auth/localDevAuth.js.map +1 -0
- package/dist/auth/loginEmailResolution.d.ts +41 -0
- package/dist/auth/loginEmailResolution.d.ts.map +1 -0
- package/dist/auth/loginEmailResolution.js +47 -0
- package/dist/auth/loginEmailResolution.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +51 -3
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +130 -13
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +221 -9
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +1 -1
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +1 -1
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +7 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +39 -3
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/magicLink/types.js +0 -4
- package/dist/auth/magicLink/types.js.map +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +1 -0
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/auth/sessionUserClone.d.ts +1 -1
- package/dist/auth/sessionUserClone.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.js +3 -2
- package/dist/auth/sessionUserClone.js.map +1 -1
- package/dist/backgroundSweepConfigUnits.d.ts +231 -0
- package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
- package/dist/backgroundSweepConfigUnits.js +180 -0
- package/dist/backgroundSweepConfigUnits.js.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
- package/dist/broadcast/index.d.ts +6 -0
- package/dist/broadcast/index.d.ts.map +1 -0
- package/dist/broadcast/index.js +6 -0
- package/dist/broadcast/index.js.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
- package/dist/cache.d.ts +3 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +1402 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +120 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +5 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +64 -12
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +3 -1
- package/dist/coreRoutes.d.ts.map +1 -1
- package/dist/coreRoutes.js +20 -4
- package/dist/coreRoutes.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +863 -14
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +4167 -62
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +50 -30
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +154 -79
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +29 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/PubSubManager.d.ts +10 -0
- package/dist/generic/PubSubManager.d.ts.map +1 -1
- package/dist/generic/PubSubManager.js +44 -1
- package/dist/generic/PubSubManager.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +39 -6
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +93 -11
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +114 -29
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +509 -220
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +15 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +126 -20
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
- package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
- package/dist/generic/actionOutputFieldSecurity.js +47 -0
- package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
- package/dist/generic/fieldSecurityTransport.d.ts +30 -0
- package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
- package/dist/generic/fieldSecurityTransport.js +30 -0
- package/dist/generic/fieldSecurityTransport.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +262 -84
- package/dist/index.js.map +1 -1
- package/dist/integration/ConnectionPause.d.ts +121 -0
- package/dist/integration/ConnectionPause.d.ts.map +1 -0
- package/dist/integration/ConnectionPause.js +183 -0
- package/dist/integration/ConnectionPause.js.map +1 -0
- package/dist/integration/CustomColumnPromoter.d.ts +72 -6
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +93 -47
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +78 -4
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +199 -5
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/integration/InactiveRowWarnings.d.ts +31 -0
- package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
- package/dist/integration/InactiveRowWarnings.js +29 -0
- package/dist/integration/InactiveRowWarnings.js.map +1 -1
- package/dist/integration/ObjectNamesByID.d.ts +28 -0
- package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
- package/dist/integration/ObjectNamesByID.js +87 -0
- package/dist/integration/ObjectNamesByID.js.map +1 -0
- package/dist/integration/PostRestartIntrospect.d.ts +26 -0
- package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
- package/dist/integration/PostRestartIntrospect.js +27 -0
- package/dist/integration/PostRestartIntrospect.js.map +1 -0
- package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
- package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
- package/dist/integration/RSUPostRestartProgress.js +323 -0
- package/dist/integration/RSUPostRestartProgress.js.map +1 -0
- package/dist/integration/RSUProgressBridge.d.ts +41 -2
- package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
- package/dist/integration/RSUProgressBridge.js +84 -1
- package/dist/integration/RSUProgressBridge.js.map +1 -1
- package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
- package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
- package/dist/integration/RunArtifactAuthorization.js +45 -0
- package/dist/integration/RunArtifactAuthorization.js.map +1 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
- package/dist/integration/SchemaRefreshLaunch.js +3 -2
- package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
- package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
- package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
- package/dist/integration/ScopedFieldsForBuild.js +91 -0
- package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
- package/dist/integration/TargetConfigGuard.d.ts +40 -0
- package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
- package/dist/integration/TargetConfigGuard.js +40 -0
- package/dist/integration/TargetConfigGuard.js.map +1 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +50 -1
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +8 -6
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.js +14 -6
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
- package/dist/realtimeSessions/sessionAccess.d.ts +103 -11
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +147 -22
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.js +19 -3
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +203 -19
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/host-identity.d.ts +1 -1
- package/dist/realtimeWidget/host-identity.js +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +1 -0
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +21 -8
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +3 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/requestOrigin.d.ts +22 -0
- package/dist/requestOrigin.d.ts.map +1 -0
- package/dist/requestOrigin.js +60 -0
- package/dist/requestOrigin.js.map +1 -0
- package/dist/resolvers/ActionResolver.d.ts +19 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +63 -12
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +1 -0
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
- package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
- package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +44 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +2 -1
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
- package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
- package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +28 -0
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +117 -21
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +1 -0
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +5 -0
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +13 -4
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +34 -13
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2713 -1290
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +13 -2
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +31 -3
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
- package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.js +5 -3
- package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +20 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +184 -88
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RSUResolver.d.ts.map +1 -1
- package/dist/resolvers/RSUResolver.js +12 -0
- package/dist/resolvers/RSUResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +22 -2
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +118 -33
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +224 -39
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +80 -16
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +388 -125
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +19 -18
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +7 -5
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +3 -1
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +4 -0
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +1 -0
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +17 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +60 -15
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +2 -1
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +2 -0
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts +6 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +19 -5
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
- package/dist/rest/MediaAccessKeys.js +6 -2
- package/dist/rest/MediaAccessKeys.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +11 -5
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +8 -5
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.js +6 -8
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +6 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +24 -6
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +3 -1
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +11 -2
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverRoleConfigUnits.d.ts +29 -0
- package/dist/serverRoleConfigUnits.d.ts.map +1 -0
- package/dist/serverRoleConfigUnits.js +33 -0
- package/dist/serverRoleConfigUnits.js.map +1 -0
- package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +2 -26
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +38 -0
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +5 -0
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +43 -15
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/services/WorkQueueHostService.d.ts +2 -1
- package/dist/services/WorkQueueHostService.d.ts.map +1 -1
- package/dist/services/WorkQueueHostService.js +19 -4
- package/dist/services/WorkQueueHostService.js.map +1 -1
- package/dist/services/workQueueConfig.d.ts +2 -2
- package/dist/services/workQueueConfig.js +5 -5
- package/dist/services/workQueueConfig.js.map +1 -1
- package/dist/sharedCache.js +1 -1
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +98 -98
- package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
- package/src/__tests__/ActiveOperations.test.ts +68 -0
- package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
- package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +150 -0
- package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
- package/src/__tests__/BatchApplyParity.test.ts +109 -0
- package/src/__tests__/BridgeHostInstance.test.ts +42 -0
- package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
- package/src/__tests__/ConnectionPause.test.ts +192 -0
- package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
- package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
- package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
- package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
- package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
- package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
- package/src/__tests__/MagicLinkKeys.test.ts +102 -0
- package/src/__tests__/MediaAccessKeys.test.ts +57 -10
- package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
- package/src/__tests__/ObjectNamesByID.test.ts +176 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
- package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
- package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
- package/src/__tests__/RSUProgressBridge.test.ts +188 -5
- package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
- package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +346 -46
- package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
- package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +100 -0
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
- package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +344 -14
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +227 -0
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +83 -1
- package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
- package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +72 -13
- package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +19 -27
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +10 -2
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +91 -13
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
- package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
- package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
- package/src/__tests__/SessionJanitor.test.ts +195 -4
- package/src/__tests__/SessionManager.test.ts +164 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
- package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +114 -3
- package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
- package/src/__tests__/ViewOperationsHandler.test.ts +9 -7
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/WorkQueueHostService.test.ts +25 -7
- package/src/__tests__/apiRootBoot.test.ts +1 -1
- package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
- package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
- package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +45 -0
- package/src/__tests__/contextRequestOrigin.test.ts +105 -0
- package/src/__tests__/conversationBrowsers.test.ts +62 -0
- package/src/__tests__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +3 -3
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
- package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +24 -2
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +224 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- package/src/__tests__/requestOrigin.test.ts +104 -0
- package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
- package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
- package/src/__tests__/resolverBase.fls.test.ts +146 -97
- package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
- package/src/__tests__/runParamsTimeZone.test.ts +179 -0
- package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
- package/src/__tests__/runViewProperties.test.ts +114 -0
- package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
- package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
- package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
- package/src/__tests__/sessionDeadline.test.ts +51 -0
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/sharedCache.test.ts +11 -0
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +101 -1
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/BridgeHostInstance.ts +20 -5
- package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
- package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
- package/src/agentSessions/SessionJanitor.ts +95 -45
- package/src/agentSessions/SessionManager.ts +73 -20
- package/src/agentSessions/conversationBrowsers.ts +143 -0
- package/src/agentSessions/sessionDeadline.ts +81 -0
- package/src/auth/APIKeyScopeAuth.ts +5 -4
- package/src/auth/AuthProviderCatalogRouter.ts +3 -0
- package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
- package/src/auth/index.ts +56 -12
- package/src/auth/initializeProviders.ts +43 -1
- package/src/auth/localDevAuth.ts +528 -0
- package/src/auth/loginEmailResolution.ts +67 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +147 -15
- package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
- package/src/auth/magicLink/MagicLinkService.ts +250 -10
- package/src/auth/magicLink/index.ts +1 -1
- package/src/auth/magicLink/redeemLanding.ts +7 -4
- package/src/auth/magicLink/types.ts +38 -3
- package/src/auth/newUsers.ts +1 -0
- package/src/auth/sessionUserClone.ts +3 -2
- package/src/backgroundSweepConfigUnits.ts +213 -0
- package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
- package/src/broadcast/index.ts +5 -0
- package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
- package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
- package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
- package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
- package/src/cache.ts +2 -1
- package/src/config.ts +138 -0
- package/src/context.ts +71 -14
- package/src/coreRoutes.ts +29 -7
- package/src/generated/graphql-schemas/__mj.ts +4145 -1193
- package/src/generic/CacheInvalidationResolver.ts +135 -78
- package/src/generic/OrphanedConversationDetailReconciler.ts +36 -3
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +108 -11
- package/src/generic/ResolverBase.ts +635 -234
- package/src/generic/RunViewResolver.ts +176 -64
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/index.ts +310 -85
- package/src/integration/ConnectionPause.ts +222 -0
- package/src/integration/CustomColumnPromoter.ts +129 -54
- package/src/integration/EntityMapLifecycle.ts +229 -6
- package/src/integration/InactiveRowWarnings.ts +50 -0
- package/src/integration/ObjectNamesByID.ts +97 -0
- package/src/integration/PostRestartIntrospect.ts +49 -0
- package/src/integration/RSUPostRestartProgress.ts +359 -0
- package/src/integration/RSUProgressBridge.ts +85 -2
- package/src/integration/RunArtifactAuthorization.ts +65 -0
- package/src/integration/SchemaRefreshLaunch.ts +12 -2
- package/src/integration/ScopedFieldsForBuild.ts +113 -0
- package/src/integration/TargetConfigGuard.ts +71 -0
- package/src/logging/variablesLoggingMiddleware.ts +59 -3
- package/src/realtimeSessions/README.md +7 -3
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +16 -6
- package/src/realtimeSessions/sessionAccess.ts +211 -25
- package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
- package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
- package/src/realtimeSessions/verificationWorkflow.ts +3 -1
- package/src/realtimeWidget/WidgetRouter.ts +22 -4
- package/src/realtimeWidget/WidgetSessionService.ts +254 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/visitorIdentity.ts +1 -0
- package/src/realtimeWidget/widgetCore.ts +34 -9
- package/src/realtimeWidget/widgetGuestElevation.ts +3 -1
- package/src/requestOrigin.ts +64 -0
- package/src/resolvers/ActionResolver.ts +78 -15
- package/src/resolvers/AdhocQueryResolver.ts +1 -0
- package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
- package/src/resolvers/AgentSessionResolver.ts +50 -18
- package/src/resolvers/AutotagPipelineResolver.ts +2 -1
- package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
- package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +14 -4
- package/src/resolvers/GetDataResolver.ts +35 -13
- package/src/resolvers/IntegrationDiscoveryResolver.ts +1570 -209
- package/src/resolvers/MCPResolver.ts +15 -2
- package/src/resolvers/MergeRecordsResolver.ts +23 -2
- package/src/resolvers/PipelineProgressResolver.ts +12 -3
- package/src/resolvers/QueryResolver.ts +20 -6
- package/src/resolvers/QuerySystemUserResolver.ts +207 -99
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +144 -40
- package/src/resolvers/RemoteBrowserActionResolver.ts +252 -37
- package/src/resolvers/RunAIAgentResolver.ts +518 -163
- package/src/resolvers/RunAIPromptResolver.ts +18 -18
- package/src/resolvers/RunTemplateResolver.ts +9 -5
- package/src/resolvers/RunTestResolver.ts +3 -1
- package/src/resolvers/SyncDataResolver.ts +4 -0
- package/src/resolvers/TestQuerySQLResolver.ts +1 -0
- package/src/resolvers/TransactionGroupResolver.ts +66 -15
- package/src/resolvers/UserViewResolver.ts +2 -1
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
- package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
- package/src/resolvers/meetingRecordingRegistration.ts +2 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/MediaAccessKeys.ts +6 -2
- package/src/rest/OAuthCallbackHandler.ts +13 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +9 -10
- package/src/rest/ViewOperationsHandler.ts +26 -7
- package/src/rest/setupRESTEndpoints.ts +11 -2
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
- package/src/services/TaskGraphActionRunner.ts +2 -23
- package/src/services/TaskGraphAgentRunner.ts +43 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +53 -20
- package/src/services/WorkQueueHostService.ts +26 -4
- package/src/services/workQueueConfig.ts +5 -5
- package/src/sharedCache.ts +1 -1
- package/src/types.ts +41 -1
- package/src/services/TaskOrchestration-Integration.md +0 -188
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The second half of an RSU run's progress stream — the half that happens in a
|
|
3
|
+
* different process from the first.
|
|
4
|
+
*
|
|
5
|
+
* The RSU pipeline restarts the API as one of its own steps. Everything after that restart —
|
|
6
|
+
* creating the entity maps and field maps, then starting the first sync — runs in the NEW process,
|
|
7
|
+
* from the durable pending-work queue. Until now none of it was observable: the pre-restart process
|
|
8
|
+
* died mid-run, so its emitter never wrote a terminal result and the run stayed flagged in-flight
|
|
9
|
+
* forever, while the post-restart work reported nothing at all. A client watching the setup journey
|
|
10
|
+
* saw the stream stop at "restart instance" and had no way to learn whether the connector ever
|
|
11
|
+
* became live.
|
|
12
|
+
*
|
|
13
|
+
* This module re-attaches to that same run and finishes it. Re-attaching (rather than opening a new
|
|
14
|
+
* run) is the entire point: the tail API returns strictly `seq > cursor`, and a fresh emitter
|
|
15
|
+
* restarts its sequence at 1 — so a brand-new run's events would sort BELOW the cursor of every
|
|
16
|
+
* client already tailing, permanently invisible to them, while the resolver echoed their unchanged
|
|
17
|
+
* cursor back and they polled forever receiving nothing.
|
|
18
|
+
*
|
|
19
|
+
* Correlation is by MANIFEST, not by checkpoint. The manifest is written when the run opens, minutes
|
|
20
|
+
* before the restart; the checkpoint is written in the last moments before the kill signal. Keying
|
|
21
|
+
* off the durable artifact and treating the checkpoint as enrichment means a lost checkpoint costs
|
|
22
|
+
* step numbers, not the whole re-attachment.
|
|
23
|
+
*/
|
|
24
|
+
import {
|
|
25
|
+
IntegrationProgressEmitter,
|
|
26
|
+
IntegrationProgressReader,
|
|
27
|
+
IntegrationRunResumeError,
|
|
28
|
+
SweepInterruptedRuns,
|
|
29
|
+
} from '@memberjunction/integration-progress-artifacts';
|
|
30
|
+
import type { EmitterOptions, IntegrationProgressEvent, IntegrationRunSnapshot } from '@memberjunction/integration-progress-artifacts';
|
|
31
|
+
import { RuntimeSchemaManager } from '@memberjunction/schema-engine';
|
|
32
|
+
import { LogError, LogStatus } from '@memberjunction/core';
|
|
33
|
+
import { RESTART_STAGE } from './RSUProgressBridge.js';
|
|
34
|
+
|
|
35
|
+
/** The two stages this module owns, in order. Named by the pipeline so the halves cannot drift. */
|
|
36
|
+
const [ENTITY_MAPS_STAGE, START_SYNC_STAGE] = RuntimeSchemaManager.EXPECTED_STEPS_POST_RESTART;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* How many in-flight RSU runs to consider for a single connection before giving up.
|
|
40
|
+
*
|
|
41
|
+
* More than one can exist only when an earlier run's post-restart work never completed (its process
|
|
42
|
+
* died again, or its pending-work rows were consumed on a boot that then crashed). The newest is the
|
|
43
|
+
* one this pending-work item belongs to; the window is small so a pathological backlog cannot turn
|
|
44
|
+
* one item's re-attachment into a directory scan of the whole run history.
|
|
45
|
+
*/
|
|
46
|
+
const CANDIDATE_RUN_WINDOW = 25;
|
|
47
|
+
|
|
48
|
+
/** Step position carried across the restart, when the checkpoint survived. */
|
|
49
|
+
interface RestartPosition {
|
|
50
|
+
/** 1-based index of `RestartMJAPI`; the post-restart steps follow it. */
|
|
51
|
+
stepIndex?: number;
|
|
52
|
+
stepTotal?: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* One re-attached RSU run. Emits the two post-restart stages into the run the pre-restart process
|
|
57
|
+
* opened, and terminates it exactly once.
|
|
58
|
+
*
|
|
59
|
+
* Obtained from {@link RSUPostRestartProgressSession}, never constructed directly — the session is
|
|
60
|
+
* what guarantees a run is attached (and terminated) once even when several pending-work items in
|
|
61
|
+
* one sweep belong to the same batch.
|
|
62
|
+
*/
|
|
63
|
+
export class RSUPostRestartProgress {
|
|
64
|
+
private entityMapsOpen = false;
|
|
65
|
+
private syncOpen = false;
|
|
66
|
+
private failed = false;
|
|
67
|
+
private readonly failures: string[] = [];
|
|
68
|
+
|
|
69
|
+
/** @internal — use {@link RSUPostRestartProgressSession.For}. */
|
|
70
|
+
public constructor(
|
|
71
|
+
private readonly emitter: IntegrationProgressEmitter,
|
|
72
|
+
private readonly position: RestartPosition
|
|
73
|
+
) {}
|
|
74
|
+
|
|
75
|
+
/** The run being continued, so a caller can log or hand it to a client. */
|
|
76
|
+
public get RunID(): string {
|
|
77
|
+
return this.emitter.RunID;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* "step 12 of 14" for a post-restart step, or undefined when the checkpoint did not survive.
|
|
82
|
+
*
|
|
83
|
+
* `offset` is the step's position AFTER `RestartMJAPI` (1 for CreateEntityMaps, 2 for StartSync).
|
|
84
|
+
* Derived from the checkpoint rather than recomputed, because the pipeline skips steps
|
|
85
|
+
* conditionally (`SkipGitCommit`) and a recomputed index would disagree with the one the client
|
|
86
|
+
* has already been shown.
|
|
87
|
+
*/
|
|
88
|
+
private positionLabel(offset: number): string | undefined {
|
|
89
|
+
const { stepIndex, stepTotal } = this.position;
|
|
90
|
+
if (stepIndex == null || stepTotal == null) return undefined;
|
|
91
|
+
return `step ${stepIndex + offset} of ${stepTotal}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Opens the `CreateEntityMaps` stage for one pending-work item. */
|
|
95
|
+
public BeginEntityMaps(objectCount: number): void {
|
|
96
|
+
this.emitter.stageStart(ENTITY_MAPS_STAGE, this.positionLabel(1));
|
|
97
|
+
this.entityMapsOpen = true;
|
|
98
|
+
this.emitter.heartbeat(ENTITY_MAPS_STAGE, `Mapping ${objectCount} object(s)`, { processed: 0, totalKnown: objectCount });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Reports one object's entity map + field maps as done.
|
|
103
|
+
*
|
|
104
|
+
* A heartbeat rather than a `records.batch.complete`: heartbeat counts are explicitly excluded
|
|
105
|
+
* from the run's applied aggregate, so per-object liveness cannot double-count against the
|
|
106
|
+
* stage rollup that follows.
|
|
107
|
+
*/
|
|
108
|
+
public ObjectMapped(objectName: string, processed: number, totalKnown: number): void {
|
|
109
|
+
this.emitter.heartbeat(ENTITY_MAPS_STAGE, `Mapped ${objectName} (${processed}/${totalKnown})`, { processed, totalKnown });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Closes `CreateEntityMaps` with the applied quartet, in OBJECTS.
|
|
114
|
+
*
|
|
115
|
+
* The run's aggregate is in objects, not migrations, for a resumed run: the migration quartet is
|
|
116
|
+
* emitted by `run.end`, which a restarting run by definition never reaches. Emitting both here
|
|
117
|
+
* would sum two different units into one number (2 migrations + 12 objects reported as
|
|
118
|
+
* "processed: 14"), so the migration counts stay in the terminal message instead.
|
|
119
|
+
*/
|
|
120
|
+
public CompleteEntityMaps(processed: number, succeeded: number, failed: number): void {
|
|
121
|
+
if (!this.entityMapsOpen) return;
|
|
122
|
+
this.entityMapsOpen = false;
|
|
123
|
+
this.emitter.stageComplete(ENTITY_MAPS_STAGE, { processed, succeeded, failed, totalKnown: processed });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Closes `CreateEntityMaps` as an ERROR, naming the objects that were never mapped.
|
|
128
|
+
*
|
|
129
|
+
* Naming them is the requirement, not a nicety: when this half fails, those objects have tables
|
|
130
|
+
* in the database and no way to sync into them, and the operator's only signal that something
|
|
131
|
+
* needs re-applying is this message.
|
|
132
|
+
*/
|
|
133
|
+
public FailEntityMaps(message: string, unmappedObjects: string[]): void {
|
|
134
|
+
this.entityMapsOpen = false;
|
|
135
|
+
this.failed = true;
|
|
136
|
+
const named = unmappedObjects.length > 0
|
|
137
|
+
? ` Objects never mapped: ${unmappedObjects.slice(0, 20).join(', ')}${unmappedObjects.length > 20 ? ` (+${unmappedObjects.length - 20} more)` : ''}.`
|
|
138
|
+
: '';
|
|
139
|
+
const full = `${message}${named}`;
|
|
140
|
+
this.failures.push(full);
|
|
141
|
+
this.emitter.stageError(ENTITY_MAPS_STAGE, full, {
|
|
142
|
+
code: 'RSU_POST_RESTART_ENTITY_MAPS_FAILED',
|
|
143
|
+
unmappedObjects,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Opens the `StartSync` stage. */
|
|
148
|
+
public BeginStartSync(): void {
|
|
149
|
+
this.emitter.stageStart(START_SYNC_STAGE, this.positionLabel(2));
|
|
150
|
+
this.syncOpen = true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Closes `StartSync`, carrying the sync run's ID so a client can hop from this stream to the
|
|
155
|
+
* sync's own.
|
|
156
|
+
*
|
|
157
|
+
* Deliberately carries NO `counts`: the records belong to the sync run, and counting them here
|
|
158
|
+
* would add another unit to this run's aggregate. `syncRunID` may be null when the sync was
|
|
159
|
+
* launched but its run row was not yet readable — the stage still completes, because the sync
|
|
160
|
+
* did start; the client simply has to find the run itself.
|
|
161
|
+
*/
|
|
162
|
+
public CompleteStartSync(syncRunID: string | null): void {
|
|
163
|
+
if (!this.syncOpen) return;
|
|
164
|
+
this.syncOpen = false;
|
|
165
|
+
this.emitter.emit('stage.complete', {
|
|
166
|
+
stage: START_SYNC_STAGE,
|
|
167
|
+
level: 'info',
|
|
168
|
+
message: syncRunID ? `Sync started — run ${syncRunID}` : 'Sync started',
|
|
169
|
+
data: { syncRunID },
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Closes `StartSync` as skipped — the caller asked for no initial sync. */
|
|
174
|
+
public SkipStartSync(reason: string): void {
|
|
175
|
+
if (!this.syncOpen) return;
|
|
176
|
+
this.syncOpen = false;
|
|
177
|
+
this.emitter.emit('stage.complete', {
|
|
178
|
+
stage: START_SYNC_STAGE,
|
|
179
|
+
level: 'info',
|
|
180
|
+
message: `Sync not started — ${reason}`,
|
|
181
|
+
data: { syncRunID: null, skipped: true, reason },
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Closes `StartSync` as an error — the sync could not be launched. */
|
|
186
|
+
public FailStartSync(message: string): void {
|
|
187
|
+
this.syncOpen = false;
|
|
188
|
+
this.failed = true;
|
|
189
|
+
this.failures.push(message);
|
|
190
|
+
this.emitter.stageError(START_SYNC_STAGE, message, { code: 'RSU_POST_RESTART_SYNC_START_FAILED' });
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Records a failure that happened outside either stage (connector resolution, for example). */
|
|
194
|
+
public RecordFailure(stage: string, message: string): void {
|
|
195
|
+
this.failed = true;
|
|
196
|
+
this.failures.push(message);
|
|
197
|
+
this.emitter.stageError(stage, message, { code: 'RSU_POST_RESTART_FAILED' });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Terminates the run. Idempotent — the emitter refuses a second terminal write, and the result
|
|
202
|
+
* file is created-not-truncated, so a duplicate call cannot rewrite an outcome a client has
|
|
203
|
+
* already read.
|
|
204
|
+
*/
|
|
205
|
+
public async Finish(): Promise<void> {
|
|
206
|
+
// An unclosed stage would leave a client's stepper stuck on it forever; a run must never end
|
|
207
|
+
// with a stage still open.
|
|
208
|
+
if (this.entityMapsOpen) this.FailEntityMaps('Post-restart processing ended with entity-map creation still open', []);
|
|
209
|
+
if (this.syncOpen) this.FailStartSync('Post-restart processing ended with sync start still open');
|
|
210
|
+
if (this.failed) {
|
|
211
|
+
await this.emitter.fail(
|
|
212
|
+
`RSU post-restart work failed — ${this.failures.join(' | ')}`,
|
|
213
|
+
'rsu-post-restart-failed'
|
|
214
|
+
);
|
|
215
|
+
} else {
|
|
216
|
+
await this.emitter.complete('RSU pipeline complete — entity maps created and sync started');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Owns the re-attachments for ONE pass of the post-restart pending-work queue.
|
|
223
|
+
*
|
|
224
|
+
* A single RSU batch registers one pending-work row per input, so several rows in one sweep can
|
|
225
|
+
* belong to the same run. Attaching per row would try to resume — and terminate — the same run
|
|
226
|
+
* repeatedly; the second attempt would be refused as already-terminal and its work would go
|
|
227
|
+
* unreported. Memoizing by run ID makes the run's stream a single coherent continuation, with one
|
|
228
|
+
* `run.resumed` at the top and one terminal event at the bottom.
|
|
229
|
+
*/
|
|
230
|
+
export class RSUPostRestartProgressSession {
|
|
231
|
+
private readonly byRunID = new Map<string, RSUPostRestartProgress>();
|
|
232
|
+
private readonly byCompanyIntegrationID = new Map<string, RSUPostRestartProgress | null>();
|
|
233
|
+
/**
|
|
234
|
+
* Every run any session in this process re-attached to. Process-wide on purpose: the startup
|
|
235
|
+
* sweep that left restart-killed runs in flight and the pass that resumes them live in
|
|
236
|
+
* different places, and the one question that joins them — "did anything pick this run up?" —
|
|
237
|
+
* must survive the resuming pass throwing halfway.
|
|
238
|
+
*/
|
|
239
|
+
private static readonly attachedRunIDs = new Set<string>();
|
|
240
|
+
public static get AttachedRunIDs(): ReadonlySet<string> {
|
|
241
|
+
return RSUPostRestartProgressSession.attachedRunIDs;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
constructor(private readonly emitterOptions: EmitterOptions = {}) {}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* The continuation handle for a connection's RSU run, or null when there is nothing to continue
|
|
248
|
+
* (no in-flight run for that connection, or it was already finished).
|
|
249
|
+
*
|
|
250
|
+
* Null is a normal outcome, not an error: pending work can legitimately be processed on a boot
|
|
251
|
+
* whose run artifact has been pruned, or after a retry that already closed the run. The caller
|
|
252
|
+
* does its work either way — progress reporting never gates the work itself.
|
|
253
|
+
*/
|
|
254
|
+
public async For(companyIntegrationID: string): Promise<RSUPostRestartProgress | null> {
|
|
255
|
+
const cached = this.byCompanyIntegrationID.get(companyIntegrationID);
|
|
256
|
+
if (cached !== undefined) return cached;
|
|
257
|
+
|
|
258
|
+
const attached = await this.attach(companyIntegrationID);
|
|
259
|
+
this.byCompanyIntegrationID.set(companyIntegrationID, attached);
|
|
260
|
+
return attached;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** Terminates every run this session re-attached to. Safe to call more than once. */
|
|
264
|
+
public async FinishAll(): Promise<void> {
|
|
265
|
+
for (const progress of this.byRunID.values()) {
|
|
266
|
+
await progress.Finish().catch(err => LogError(`[RSU] post-restart terminal write failed for run ${progress.RunID}: ${err}`));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private async attach(companyIntegrationID: string): Promise<RSUPostRestartProgress | null> {
|
|
271
|
+
try {
|
|
272
|
+
const reader = new IntegrationProgressReader(this.emitterOptions.rootDir);
|
|
273
|
+
const candidates = await reader.ListRuns(
|
|
274
|
+
{ runKind: 'RSU', companyIntegrationID, inFlightOnly: true },
|
|
275
|
+
CANDIDATE_RUN_WINDOW
|
|
276
|
+
);
|
|
277
|
+
// A run this session already picked up no longer LOOKS killed-at-the-restart — its latest
|
|
278
|
+
// event is now the `run.resumed` this session wrote. So an already-attached run must be
|
|
279
|
+
// matched first, or the second pending-work item of the same batch would find nothing to
|
|
280
|
+
// report into and its work would go unobserved.
|
|
281
|
+
const snapshot = candidates.find(s => this.byRunID.has(s.manifest.runID))
|
|
282
|
+
?? candidates.find(RSUPostRestartProgressSession.WasKilledAtRestart);
|
|
283
|
+
if (!snapshot) return null;
|
|
284
|
+
|
|
285
|
+
const runID = snapshot.manifest.runID;
|
|
286
|
+
const existing = this.byRunID.get(runID);
|
|
287
|
+
if (existing) return existing;
|
|
288
|
+
|
|
289
|
+
const checkpoint = await reader.LatestCheckpoint(runID);
|
|
290
|
+
const emitter = await IntegrationProgressEmitter.Resume(runID, this.emitterOptions);
|
|
291
|
+
emitter.RunResumed(
|
|
292
|
+
`Resumed after the RSU restart — continuing with ${RuntimeSchemaManager.EXPECTED_STEPS_POST_RESTART.join(' then ')}`,
|
|
293
|
+
{ companyIntegrationID }
|
|
294
|
+
);
|
|
295
|
+
const progress = new RSUPostRestartProgress(emitter, RSUPostRestartProgressSession.PositionFrom(checkpoint));
|
|
296
|
+
this.byRunID.set(runID, progress);
|
|
297
|
+
RSUPostRestartProgressSession.attachedRunIDs.add(runID);
|
|
298
|
+
LogStatus(`[RSU] Re-attached to run ${runID} for connection ${companyIntegrationID}`);
|
|
299
|
+
return progress;
|
|
300
|
+
} catch (err: unknown) {
|
|
301
|
+
// A run that is already terminal, or has no manifest, is not an error condition worth
|
|
302
|
+
// failing the actual work over — the work still has to happen, unobserved.
|
|
303
|
+
if (err instanceof IntegrationRunResumeError) {
|
|
304
|
+
LogStatus(`[RSU] Not resuming progress for ${companyIntegrationID}: ${err.message}`);
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
LogError(`[RSU] Could not re-attach progress for ${companyIntegrationID}: ${err instanceof Error ? err.message : String(err)}`);
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Whether a run's stream stops at the restart — which is the signature of a run this process is
|
|
314
|
+
* the continuation of.
|
|
315
|
+
*
|
|
316
|
+
* Checking the LAST stage, not the presence of the checkpoint, on purpose. The checkpoint is
|
|
317
|
+
* written in the moments before the kill signal and can be lost; the `stage.start RestartMJAPI`
|
|
318
|
+
* that precedes it cannot, because the pipeline waits on nothing between emitting it and dying.
|
|
319
|
+
* Requiring the checkpoint would trade a recoverable loss of step numbers for an unrecoverable
|
|
320
|
+
* loss of the whole continuation.
|
|
321
|
+
*/
|
|
322
|
+
public static WasKilledAtRestart(snapshot: IntegrationRunSnapshot): boolean {
|
|
323
|
+
return snapshot.latestEvent?.stage === RESTART_STAGE;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Closes out the restart-killed runs the startup sweep left in flight that NO session then
|
|
327
|
+
* re-attached to — because there was no system user, or the pending work was stale and
|
|
328
|
+
* dropped, or it simply failed before reaching the run. Without this they would read as in
|
|
329
|
+
* flight forever, which is the state the sweep exists to end.
|
|
330
|
+
*
|
|
331
|
+
* Only the runs in `leftInFlight` (the sweep's `Skipped` list) are candidates: anything else
|
|
332
|
+
* in flight by now may be a run this process started, and is not ours to judge. A candidate
|
|
333
|
+
* a session attached to is live — its session terminates it — and is left alone.
|
|
334
|
+
*/
|
|
335
|
+
public static async SweepUnattached(
|
|
336
|
+
leftInFlight: readonly string[],
|
|
337
|
+
rootDir?: string,
|
|
338
|
+
log: (message: string) => void = () => {},
|
|
339
|
+
): Promise<{ Swept: string[]; Failed: string[]; Skipped: string[] }> {
|
|
340
|
+
if (leftInFlight.length === 0) return { Swept: [], Failed: [], Skipped: [] };
|
|
341
|
+
const candidates = new Set(leftInFlight);
|
|
342
|
+
return SweepInterruptedRuns(rootDir, log, snapshot => {
|
|
343
|
+
const runID = snapshot.manifest.runID;
|
|
344
|
+
return !candidates.has(runID) || RSUPostRestartProgressSession.attachedRunIDs.has(runID);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/** Reads the step position out of a restart checkpoint, tolerating a missing or partial one. */
|
|
349
|
+
public static PositionFrom(checkpoint: IntegrationProgressEvent | undefined): RestartPosition {
|
|
350
|
+
const state = checkpoint?.stage === RESTART_STAGE ? checkpoint.resumableState : undefined;
|
|
351
|
+
if (!state) return {};
|
|
352
|
+
const stepIndex = state.stepIndex;
|
|
353
|
+
const stepTotal = state.stepTotal;
|
|
354
|
+
return {
|
|
355
|
+
stepIndex: typeof stepIndex === 'number' ? stepIndex : undefined,
|
|
356
|
+
stepTotal: typeof stepTotal === 'number' ? stepTotal : undefined,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
@@ -24,6 +24,13 @@ import { BaseSingleton } from '@memberjunction/global';
|
|
|
24
24
|
/** The emitter stage name used for run-level (non-step) events. */
|
|
25
25
|
const RUN_STAGE = 'RSUPipeline';
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* The pipeline step that kills this process. Named here because BOTH sides of the restart use it:
|
|
29
|
+
* this bridge closes the stage and checkpoints under it, and the post-restart consumer recognises a
|
|
30
|
+
* run as resumable by finding it as the run's last stage.
|
|
31
|
+
*/
|
|
32
|
+
export const RESTART_STAGE = 'RestartMJAPI';
|
|
33
|
+
|
|
27
34
|
/**
|
|
28
35
|
* How often an in-flight step reports that it is still alive.
|
|
29
36
|
*
|
|
@@ -53,6 +60,15 @@ export class RSUProgressBridge extends BaseSingleton<RSUProgressBridge> {
|
|
|
53
60
|
private currentRunID: string | null = null;
|
|
54
61
|
/** Liveness timer for the step currently in flight — see {@link HEARTBEAT_INTERVAL_MS}. */
|
|
55
62
|
private heartbeat: ReturnType<typeof setInterval> | null = null;
|
|
63
|
+
/**
|
|
64
|
+
* The stage the live heartbeat belongs to, held on the INSTANCE rather than only captured in
|
|
65
|
+
* the timer closure. A closure-only stage name is a leak waiting to happen: a timer that
|
|
66
|
+
* outlives its step (or its whole run) keeps firing with the name it was created with, and
|
|
67
|
+
* writes that stale name into whatever emitter the bridge is pointing at by then. Comparing the
|
|
68
|
+
* tick's captured name against this field makes that structurally impossible — a stopped or
|
|
69
|
+
* superseded heartbeat writes nothing.
|
|
70
|
+
*/
|
|
71
|
+
private heartbeatStage: string | null = null;
|
|
56
72
|
private emitterOptions: EmitterOptions = {};
|
|
57
73
|
|
|
58
74
|
/** The one bridge for this process. */
|
|
@@ -96,8 +112,14 @@ export class RSUProgressBridge extends BaseSingleton<RSUProgressBridge> {
|
|
|
96
112
|
this.currentRunID = null;
|
|
97
113
|
}
|
|
98
114
|
|
|
99
|
-
/**
|
|
100
|
-
|
|
115
|
+
/**
|
|
116
|
+
* The observer to hand to {@link RuntimeSchemaManager.PipelineObserver}.
|
|
117
|
+
*
|
|
118
|
+
* Returns a promise ONLY for `restart.pending` — the pipeline awaits that one (bounded) because
|
|
119
|
+
* the process is about to be killed and an unflushed write would be lost. Every other event
|
|
120
|
+
* stays fire-and-forget.
|
|
121
|
+
*/
|
|
122
|
+
public readonly Observe = (event: RSUObserverEvent): void | Promise<void> => {
|
|
101
123
|
switch (event.Kind) {
|
|
102
124
|
case 'run.start':
|
|
103
125
|
return this.onRunStart(event);
|
|
@@ -105,24 +127,76 @@ export class RSUProgressBridge extends BaseSingleton<RSUProgressBridge> {
|
|
|
105
127
|
return this.onStepStart(event);
|
|
106
128
|
case 'step.end':
|
|
107
129
|
return this.onStepEnd(event);
|
|
130
|
+
case 'restart.pending':
|
|
131
|
+
return this.onRestartPending(event);
|
|
108
132
|
case 'run.end':
|
|
109
133
|
return this.onRunEnd(event);
|
|
110
134
|
}
|
|
111
135
|
};
|
|
112
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Closes the `RestartMJAPI` stage and writes the checkpoint the next process re-attaches from,
|
|
139
|
+
* then FLUSHES — the caller awaits this, and pm2 kills the process moments later.
|
|
140
|
+
*
|
|
141
|
+
* Two separate things are written here, and they matter for different reasons:
|
|
142
|
+
*
|
|
143
|
+
* - the `stage.complete` for `RestartMJAPI`, because `step.end` for that step is unreachable
|
|
144
|
+
* (the process dies inside the step), so without it the stream ends on an open stage and a
|
|
145
|
+
* determinate stepper stalls one short of the restart;
|
|
146
|
+
* - the `checkpoint`, carrying the step position and the pending-work correlation, so the
|
|
147
|
+
* consumer on the other side can resume the stepper where this process left it.
|
|
148
|
+
*
|
|
149
|
+
* The checkpoint is deliberately NOT the consumer's only way back to this run. Re-attachment
|
|
150
|
+
* keys off the MANIFEST — written minutes earlier, when the run opened — precisely because this
|
|
151
|
+
* write is the one racing a kill signal. If it is lost the run is still found and still
|
|
152
|
+
* resumed; only the step indices degrade to defaults.
|
|
153
|
+
*/
|
|
154
|
+
private async onRestartPending(event: Extract<RSUObserverEvent, { Kind: 'restart.pending' }>): Promise<void> {
|
|
155
|
+
this.stopHeartbeat();
|
|
156
|
+
const emitter = this.emitter;
|
|
157
|
+
if (!emitter) return;
|
|
158
|
+
emitter.stageComplete(RESTART_STAGE);
|
|
159
|
+
emitter.checkpoint(RESTART_STAGE, {
|
|
160
|
+
runID: emitter.RunID,
|
|
161
|
+
remainingSteps: event.RemainingSteps,
|
|
162
|
+
stepIndex: event.StepIndex,
|
|
163
|
+
stepTotal: event.StepTotal,
|
|
164
|
+
companyIntegrationIDs: event.CompanyIntegrationIDs,
|
|
165
|
+
pendingWorkIDs: event.PendingWorkIDs,
|
|
166
|
+
migrationTotalCount: event.TotalCount,
|
|
167
|
+
migrationSuccessCount: event.SuccessCount,
|
|
168
|
+
});
|
|
169
|
+
// A failed flush must not stop the restart — the pipeline swallows this, but say so.
|
|
170
|
+
await emitter.flush().catch(err => LogError(`RSUProgressBridge: pre-restart flush failed — ${err}`));
|
|
171
|
+
}
|
|
172
|
+
|
|
113
173
|
private onRunStart(event: Extract<RSUObserverEvent, { Kind: 'run.start' }>): void {
|
|
174
|
+
// Unconditional, and BEFORE the emitter check below. Stopping the previous run's liveness
|
|
175
|
+
// timer must not be reachable only via `closeCurrent`, whose call is gated on there being
|
|
176
|
+
// an emitter — that gate is the one path on which a live heartbeat could survive into the
|
|
177
|
+
// next run and stamp the previous run's stage name onto it.
|
|
178
|
+
this.stopHeartbeat();
|
|
114
179
|
// A retry re-enters RunPipelineBatch, so it legitimately starts a NEW run. If a previous
|
|
115
180
|
// emitter is still open (a throw escaped before run.end), close it rather than leak it.
|
|
116
181
|
if (this.emitter) this.closeCurrent('Superseded by a new RSU run');
|
|
117
182
|
|
|
118
183
|
const runID = IntegrationProgressEmitter.newRunID('rsu');
|
|
119
184
|
this.currentRunID = runID;
|
|
185
|
+
const companyIntegrationIDs = event.CompanyIntegrationIDs ?? [];
|
|
120
186
|
this.emitter = new IntegrationProgressEmitter(
|
|
121
187
|
{
|
|
122
188
|
runID,
|
|
123
189
|
runKind: 'RSU',
|
|
124
190
|
triggerType: 'Pipeline',
|
|
125
191
|
startedAt: new Date().toISOString(),
|
|
192
|
+
// The run's IDENTITY, and the reason an RSU run is readable over the API at all: the
|
|
193
|
+
// run-artifact authorization check tests the caller against the connections on the
|
|
194
|
+
// manifest, and an RSU manifest never carried any. The plural field is the whole set
|
|
195
|
+
// (a batch may span connections); the singular one is populated ONLY for a
|
|
196
|
+
// single-connection run, so everything that reports "the" connection of a run keeps
|
|
197
|
+
// reporting one unambiguous answer rather than an arbitrary member of a set.
|
|
198
|
+
companyIntegrationIDs,
|
|
199
|
+
companyIntegrationID: companyIntegrationIDs.length === 1 ? companyIntegrationIDs[0] : undefined,
|
|
126
200
|
context: {
|
|
127
201
|
itemCount: event.ItemCount,
|
|
128
202
|
descriptions: event.Descriptions,
|
|
@@ -195,7 +269,12 @@ export class RSUProgressBridge extends BaseSingleton<RSUProgressBridge> {
|
|
|
195
269
|
private startHeartbeat(stage: string): void {
|
|
196
270
|
this.stopHeartbeat();
|
|
197
271
|
const startedAt = Date.now();
|
|
272
|
+
this.heartbeatStage = stage;
|
|
198
273
|
this.heartbeat = setInterval(() => {
|
|
274
|
+
// Guard on the INSTANCE's current stage, not just the captured one. A tick that fires
|
|
275
|
+
// after the heartbeat was stopped, or after a different step/run took over, must not
|
|
276
|
+
// write this step's name into someone else's stream.
|
|
277
|
+
if (this.heartbeatStage !== stage) return;
|
|
199
278
|
const elapsedSec = Math.round((Date.now() - startedAt) / 1000);
|
|
200
279
|
this.emitter?.heartbeat(stage, `${stage} still running — ${elapsedSec}s elapsed`);
|
|
201
280
|
}, HEARTBEAT_INTERVAL_MS);
|
|
@@ -205,6 +284,10 @@ export class RSUProgressBridge extends BaseSingleton<RSUProgressBridge> {
|
|
|
205
284
|
|
|
206
285
|
/** Stops the liveness timer. Safe to call when none is running. */
|
|
207
286
|
private stopHeartbeat(): void {
|
|
287
|
+
// Deliberately unconditional on the stage: clearing the name is what disarms a tick that is
|
|
288
|
+
// already queued on the event loop, so it must happen even when there is no timer handle
|
|
289
|
+
// left to clear.
|
|
290
|
+
this.heartbeatStage = null;
|
|
208
291
|
if (!this.heartbeat) return;
|
|
209
292
|
clearInterval(this.heartbeat);
|
|
210
293
|
this.heartbeat = null;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Who may read an integration run artifact.
|
|
3
|
+
*
|
|
4
|
+
* A security boundary, kept in its own module so the rule is stated once, testable on its own, and
|
|
5
|
+
* not buried among a resolver's several thousand lines.
|
|
6
|
+
*/
|
|
7
|
+
import { IntegrationProgressReader } from '@memberjunction/integration-progress-artifacts';
|
|
8
|
+
import type { IntegrationRunManifest } from '@memberjunction/integration-progress-artifacts';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Answers "may the calling user read this one connection?".
|
|
12
|
+
*
|
|
13
|
+
* Supplied by the resolver, which implements it as a `RunView` on `MJ: Company Integrations` under
|
|
14
|
+
* the CALLER's context — so the data provider applies the same row-level security it applies to
|
|
15
|
+
* every other user-context read, and no row coming back means unauthorized.
|
|
16
|
+
*/
|
|
17
|
+
export type CompanyIntegrationReadCheck = (companyIntegrationID: string) => Promise<boolean>;
|
|
18
|
+
|
|
19
|
+
/** The verdict, carrying the connection that blocked it so a denial can name it. */
|
|
20
|
+
export interface RunArtifactAuthorizationResult {
|
|
21
|
+
Authorized: boolean;
|
|
22
|
+
/** The first connection the caller could not read. Absent when the run has no identity at all. */
|
|
23
|
+
DeniedCompanyIntegrationID?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Authorizes a caller for a run artifact against EVERY connection the run touched.
|
|
28
|
+
*
|
|
29
|
+
* ── The rule ───────────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
* A run is readable only if the caller is authorized for ALL of its connections. Not any — all.
|
|
31
|
+
*
|
|
32
|
+
* Most runs touch exactly one connection and the rule collapses to the obvious check. But a schema
|
|
33
|
+
* update (RSU) run is a BATCH: the pipeline takes N inputs, and those inputs may legitimately
|
|
34
|
+
* belong to different connectors. A run artifact is one undivided event stream — its migration
|
|
35
|
+
* descriptions, affected table names and error messages interleave every connection in the batch,
|
|
36
|
+
* and there is no mechanism to serve a caller a partial view of it. "Authorized for any one of
|
|
37
|
+
* them" would therefore hand connection A's schema-change descriptions to a user who only holds
|
|
38
|
+
* rights on connection B. AND is the only rule that cannot leak; a cross-tenant batch simply
|
|
39
|
+
* becomes readable to nobody but a caller holding rights to both, which is the correct conservative
|
|
40
|
+
* answer rather than a silent disclosure.
|
|
41
|
+
*
|
|
42
|
+
* A run with NO connection identity is denied: non-tenant-scoped artifacts are not exposed through
|
|
43
|
+
* the per-company endpoints, and that must not change as a side effect of runs gaining a set.
|
|
44
|
+
*
|
|
45
|
+
* Short-circuits on the first denial, so an unauthorized caller cannot use the number of permission
|
|
46
|
+
* lookups to probe which connections a run covers.
|
|
47
|
+
*/
|
|
48
|
+
export async function AuthorizeRunArtifact(
|
|
49
|
+
manifest: IntegrationRunManifest,
|
|
50
|
+
canReadCompanyIntegration: CompanyIntegrationReadCheck
|
|
51
|
+
): Promise<RunArtifactAuthorizationResult> {
|
|
52
|
+
// Reads the SET, not the singular field: a batch spanning connections leaves the singular field
|
|
53
|
+
// deliberately empty, and testing only that would make such a run look connection-less — and so
|
|
54
|
+
// unreadable to everyone, including its rightful owner.
|
|
55
|
+
const companyIntegrationIDs = IntegrationProgressReader.CompanyIntegrationIDsFor(manifest);
|
|
56
|
+
if (companyIntegrationIDs.length === 0) {
|
|
57
|
+
return { Authorized: false };
|
|
58
|
+
}
|
|
59
|
+
for (const companyIntegrationID of companyIntegrationIDs) {
|
|
60
|
+
if (!await canReadCompanyIntegration(companyIntegrationID)) {
|
|
61
|
+
return { Authorized: false, DeniedCompanyIntegrationID: companyIntegrationID };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { Authorized: true };
|
|
65
|
+
}
|
|
@@ -30,6 +30,15 @@ export interface SchemaRefreshSummaryLike {
|
|
|
30
30
|
FailureMessage?: string;
|
|
31
31
|
ObjectsCreated: number;
|
|
32
32
|
ObjectsUpdated: number;
|
|
33
|
+
/**
|
|
34
|
+
* FIELD counts, not an optional nicety: a connector whose objects are PRESUPPOSED (declared in
|
|
35
|
+
* its own metadata) creates no objects on any run, so the object counts of a refresh that
|
|
36
|
+
* created 69 fields and updated 487 are "0 and 0" — which reads as "the refresh found nothing".
|
|
37
|
+
* Both counts were already carried on the pipeline result; only this type stopped them reaching
|
|
38
|
+
* the sentence.
|
|
39
|
+
*/
|
|
40
|
+
FieldsCreated: number;
|
|
41
|
+
FieldsUpdated: number;
|
|
33
42
|
UnresolvedObjects: string[];
|
|
34
43
|
}
|
|
35
44
|
|
|
@@ -38,8 +47,9 @@ function describeFinishedRefresh(summary: SchemaRefreshSummaryLike): string {
|
|
|
38
47
|
if (!summary.Succeeded) {
|
|
39
48
|
return `schema refresh FAILED (${summary.FailureMessage ?? 'no reason reported'}) — see run ${summary.RunID}`;
|
|
40
49
|
}
|
|
41
|
-
return `schema refresh: ${summary.ObjectsCreated} created, ` +
|
|
42
|
-
`${summary.ObjectsUpdated} updated, ${summary.
|
|
50
|
+
return `schema refresh: ${summary.ObjectsCreated} objects created, ` +
|
|
51
|
+
`${summary.ObjectsUpdated} updated, ${summary.FieldsCreated} fields created, ` +
|
|
52
|
+
`${summary.FieldsUpdated} updated, ${summary.UnresolvedObjects.length} PK-unresolved`;
|
|
43
53
|
}
|
|
44
54
|
|
|
45
55
|
/**
|