doover-js 0.11.0 → 0.13.0
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 +106 -0
- package/dist/apis/_args.js +5 -5
- package/dist/apis/agents-api.d.ts +4 -4
- package/dist/apis/agents-api.js +2 -2
- package/dist/apis/aggregates-api.d.ts +4 -4
- package/dist/apis/aggregates-api.js +5 -5
- package/dist/apis/alarms-api.d.ts +2 -2
- package/dist/apis/alarms-api.js +3 -3
- package/dist/apis/channels-api.d.ts +3 -3
- package/dist/apis/channels-api.js +6 -6
- package/dist/apis/connections-api.d.ts +2 -2
- package/dist/apis/connections-api.js +6 -6
- package/dist/apis/messages-api.d.ts +4 -4
- package/dist/apis/messages-api.js +11 -11
- package/dist/apis/notifications-api.d.ts +2 -2
- package/dist/apis/notifications-api.js +4 -4
- package/dist/apis/organisations-api.d.ts +2 -2
- package/dist/apis/permissions-api.d.ts +2 -2
- package/dist/apis/permissions-api.js +3 -3
- package/dist/apis/processors-api.d.ts +2 -2
- package/dist/apis/turn-api.d.ts +2 -2
- package/dist/apis/users-api.d.ts +2 -2
- package/dist/auth/auth-store.d.ts +1 -1
- package/dist/auth/build-auth.d.ts +3 -3
- package/dist/auth/build-auth.js +8 -8
- package/dist/auth/cookie-auth.d.ts +1 -1
- package/dist/auth/cookie-auth.js +2 -2
- package/dist/auth/doover-auth.d.ts +2 -2
- package/dist/auth/doover-token-auth.d.ts +3 -3
- package/dist/auth/doover-token-auth.js +13 -13
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.js +15 -0
- package/dist/client/data-client.d.ts +17 -14
- package/dist/client/doover-client.d.ts +9 -7
- package/dist/client/doover-client.js +44 -42
- package/dist/client/errors.d.ts +2 -2
- package/dist/client/errors.js +4 -4
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +12 -0
- package/dist/client/local-agent-client.d.ts +3 -3
- package/dist/client/local-agent-client.js +19 -19
- package/dist/client/multiplex-client.d.ts +5 -5
- package/dist/client/multiplex-client.js +25 -25
- package/dist/client/multiplex-gateway.d.ts +3 -3
- package/dist/client/multiplex-merge.d.ts +1 -1
- package/dist/client/network-status.d.ts +17 -0
- package/dist/client/network-status.js +70 -0
- package/dist/client/offline-cache.d.ts +9 -4
- package/dist/client/offline-cache.js +34 -22
- package/dist/client/provenance.d.ts +1 -1
- package/dist/client/request-options.d.ts +1 -1
- package/dist/client/singleton.d.ts +2 -2
- package/dist/client/singleton.js +2 -2
- package/dist/client/status-tracker.d.ts +1 -1
- package/dist/esm/apis/_args.d.ts +16 -0
- package/dist/esm/apis/_args.js +27 -0
- package/dist/esm/apis/agents-api.d.ts +196 -0
- package/dist/esm/apis/agents-api.js +327 -0
- package/dist/esm/apis/aggregates-api.d.ts +67 -0
- package/dist/esm/apis/aggregates-api.js +64 -0
- package/dist/esm/apis/alarms-api.d.ts +48 -0
- package/dist/esm/apis/alarms-api.js +75 -0
- package/dist/esm/apis/channels-api.d.ts +83 -0
- package/dist/esm/apis/channels-api.js +65 -0
- package/dist/esm/apis/connections-api.d.ts +45 -0
- package/dist/esm/apis/connections-api.js +44 -0
- package/dist/esm/apis/messages-api.d.ts +128 -0
- package/dist/esm/apis/messages-api.js +179 -0
- package/dist/esm/apis/notifications-api.d.ts +94 -0
- package/dist/esm/apis/notifications-api.js +153 -0
- package/dist/esm/apis/organisations-api.d.ts +26 -0
- package/dist/esm/apis/organisations-api.js +41 -0
- package/dist/esm/apis/permissions-api.d.ts +17 -0
- package/dist/esm/apis/permissions-api.js +23 -0
- package/dist/esm/apis/processors-api.d.ts +56 -0
- package/dist/esm/apis/processors-api.js +97 -0
- package/dist/esm/apis/turn-api.d.ts +7 -0
- package/dist/esm/apis/turn-api.js +8 -0
- package/dist/esm/apis/users-api.d.ts +8 -0
- package/dist/esm/apis/users-api.js +9 -0
- package/dist/esm/auth/auth-profile.d.ts +45 -0
- package/dist/esm/auth/auth-profile.js +68 -0
- package/dist/esm/auth/auth-store.d.ts +14 -0
- package/dist/esm/auth/build-auth.d.ts +38 -0
- package/dist/esm/auth/build-auth.js +92 -0
- package/dist/esm/auth/cookie-auth.d.ts +91 -0
- package/dist/esm/auth/cookie-auth.js +196 -0
- package/dist/esm/auth/doover-auth.d.ts +52 -0
- package/dist/esm/auth/doover-auth.js +28 -0
- package/dist/esm/auth/doover-token-auth.d.ts +39 -0
- package/dist/esm/auth/doover-token-auth.js +217 -0
- package/dist/esm/auth/errors.d.ts +3 -0
- package/dist/esm/auth/errors.js +6 -0
- package/dist/esm/auth/index.d.ts +10 -0
- package/dist/esm/auth/index.js +6 -0
- package/dist/esm/auth/jwt.d.ts +6 -0
- package/dist/esm/auth/jwt.js +26 -0
- package/dist/esm/client/capabilities.d.ts +10 -0
- package/dist/esm/client/capabilities.js +42 -0
- package/dist/esm/client/data-client.d.ts +107 -0
- package/dist/esm/client/doover-client.d.ts +48 -0
- package/dist/esm/client/doover-client.js +96 -0
- package/dist/esm/client/errors.d.ts +32 -0
- package/dist/esm/client/errors.js +64 -0
- package/dist/esm/client/index.d.ts +6 -0
- package/dist/esm/client/index.js +3 -0
- package/dist/esm/client/local-agent-client.d.ts +65 -0
- package/dist/esm/client/local-agent-client.js +225 -0
- package/dist/esm/client/multiplex-client.d.ts +165 -0
- package/dist/esm/client/multiplex-client.js +842 -0
- package/dist/esm/client/multiplex-gateway.d.ts +49 -0
- package/dist/esm/client/multiplex-gateway.js +110 -0
- package/dist/esm/client/multiplex-merge.d.ts +12 -0
- package/dist/esm/client/multiplex-merge.js +38 -0
- package/dist/esm/client/network-status.d.ts +17 -0
- package/dist/esm/client/network-status.js +66 -0
- package/dist/esm/client/offline-cache.d.ts +167 -0
- package/dist/esm/client/offline-cache.js +769 -0
- package/dist/esm/client/provenance.d.ts +60 -0
- package/dist/esm/client/provenance.js +108 -0
- package/dist/esm/client/request-options.d.ts +23 -0
- package/dist/esm/client/request-options.js +23 -0
- package/dist/esm/client/singleton.d.ts +26 -0
- package/dist/esm/client/singleton.js +54 -0
- package/dist/esm/client/stats.d.ts +79 -0
- package/dist/esm/client/stats.js +155 -0
- package/dist/esm/client/status-tracker.d.ts +24 -0
- package/dist/esm/client/status-tracker.js +86 -0
- package/dist/esm/gateway/gateway-client.d.ts +86 -0
- package/dist/esm/gateway/gateway-client.js +463 -0
- package/dist/esm/gateway/index.d.ts +3 -0
- package/dist/esm/gateway/index.js +1 -0
- package/dist/esm/gateway/types.d.ts +142 -0
- package/dist/esm/http/errors.d.ts +19 -0
- package/dist/esm/http/errors.js +22 -0
- package/dist/esm/http/index.d.ts +3 -0
- package/dist/esm/http/index.js +2 -0
- package/dist/esm/http/rest-client.d.ts +64 -0
- package/dist/esm/http/rest-client.js +181 -0
- package/dist/esm/index.d.ts +64 -0
- package/dist/esm/index.js +38 -0
- package/dist/esm/node/config-manager.d.ts +34 -0
- package/dist/esm/node/config-manager.js +140 -0
- package/dist/esm/node/index.d.ts +1 -0
- package/dist/esm/node/index.js +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/react/context.d.ts +23 -0
- package/dist/esm/react/context.js +28 -0
- package/dist/esm/react/index.d.ts +38 -0
- package/dist/esm/react/index.js +21 -0
- package/dist/esm/react/messageRangeStore.d.ts +93 -0
- package/dist/esm/react/messageRangeStore.js +140 -0
- package/dist/esm/react/sharedQueryClient.d.ts +21 -0
- package/dist/esm/react/sharedQueryClient.js +35 -0
- package/dist/esm/react/useAgentChannel.d.ts +8 -0
- package/dist/esm/react/useAgentChannel.js +9 -0
- package/dist/esm/react/useAgentConnections.d.ts +8 -0
- package/dist/esm/react/useAgentConnections.js +20 -0
- package/dist/esm/react/useAgentTokenState.d.ts +70 -0
- package/dist/esm/react/useAgentTokenState.js +127 -0
- package/dist/esm/react/useChannelAggregate.d.ts +64 -0
- package/dist/esm/react/useChannelAggregate.js +77 -0
- package/dist/esm/react/useChannelMessage.d.ts +45 -0
- package/dist/esm/react/useChannelMessage.js +79 -0
- package/dist/esm/react/useChannelMessages.d.ts +83 -0
- package/dist/esm/react/useChannelMessages.js +214 -0
- package/dist/esm/react/useChannelSubscription.d.ts +27 -0
- package/dist/esm/react/useChannelSubscription.js +30 -0
- package/dist/esm/react/useClientStatus.d.ts +10 -0
- package/dist/esm/react/useClientStatus.js +19 -0
- package/dist/esm/react/useConnectionState.d.ts +26 -0
- package/dist/esm/react/useConnectionState.js +45 -0
- package/dist/esm/react/useDeviceMap.d.ts +109 -0
- package/dist/esm/react/useDeviceMap.js +59 -0
- package/dist/esm/react/useInvocationLogs.d.ts +23 -0
- package/dist/esm/react/useInvocationLogs.js +37 -0
- package/dist/esm/react/useMultiAgentAggregates.d.ts +38 -0
- package/dist/esm/react/useMultiAgentAggregates.js +104 -0
- package/dist/esm/react/useMultiAgentChannelMessages.d.ts +79 -0
- package/dist/esm/react/useMultiAgentChannelMessages.js +169 -0
- package/dist/esm/react/useOfflineStatus.d.ts +8 -0
- package/dist/esm/react/useOfflineStatus.js +37 -0
- package/dist/esm/react/useSendMessage.d.ts +16 -0
- package/dist/esm/react/useSendMessage.js +26 -0
- package/dist/esm/react/useSendRpc.d.ts +68 -0
- package/dist/esm/react/useSendRpc.js +164 -0
- package/dist/esm/react/useTurnCredentials.d.ts +12 -0
- package/dist/esm/react/useTurnCredentials.js +22 -0
- package/dist/esm/react/useUpdateAggregate.d.ts +27 -0
- package/dist/esm/react/useUpdateAggregate.js +39 -0
- package/dist/esm/react/useUpdateMessage.d.ts +38 -0
- package/dist/esm/react/useUpdateMessage.js +36 -0
- package/dist/esm/refine/index.d.ts +72 -0
- package/dist/esm/refine/index.js +215 -0
- package/dist/esm/rpc/errors.d.ts +10 -0
- package/dist/esm/rpc/errors.js +19 -0
- package/dist/esm/rpc/index.d.ts +3 -0
- package/dist/esm/rpc/index.js +2 -0
- package/dist/esm/rpc/rpc-dispatcher.d.ts +41 -0
- package/dist/esm/rpc/rpc-dispatcher.js +141 -0
- package/dist/esm/types/audit.d.ts +53 -0
- package/dist/esm/types/audit.js +11 -0
- package/dist/esm/types/batch.d.ts +85 -0
- package/dist/esm/types/batch.js +42 -0
- package/dist/esm/types/common.d.ts +250 -0
- package/dist/esm/types/connection.d.ts +72 -0
- package/dist/esm/types/connection.js +7 -0
- package/dist/esm/types/index.d.ts +9 -0
- package/dist/esm/types/openapi.d.ts +195 -0
- package/dist/esm/types/provenance.d.ts +45 -0
- package/dist/esm/types/viewer.d.ts +122 -0
- package/dist/esm/utils/snowflake.d.ts +21 -0
- package/dist/esm/utils/snowflake.js +33 -0
- package/dist/esm/viewer/doover-data-provider.d.ts +90 -0
- package/dist/esm/viewer/doover-data-provider.js +189 -0
- package/dist/esm/viewer/path-parsing.d.ts +5 -0
- package/dist/esm/viewer/path-parsing.js +35 -0
- package/dist/gateway/gateway-client.d.ts +5 -5
- package/dist/gateway/gateway-client.js +5 -5
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.js +5 -0
- package/dist/gateway/types.d.ts +1 -1
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +9 -0
- package/dist/http/rest-client.d.ts +5 -3
- package/dist/http/rest-client.js +2 -2
- package/dist/index.d.ts +64 -62
- package/dist/index.js +92 -89
- package/dist/node/config-manager.d.ts +2 -2
- package/dist/node/config-manager.js +5 -5
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.js +2 -2
- package/dist/react/context.d.ts +1 -1
- package/dist/react/index.d.ts +38 -38
- package/dist/react/index.js +59 -59
- package/dist/react/messageRangeStore.d.ts +1 -1
- package/dist/react/useAgentChannel.d.ts +3 -3
- package/dist/react/useAgentChannel.js +2 -2
- package/dist/react/useAgentConnections.d.ts +1 -1
- package/dist/react/useAgentConnections.js +2 -2
- package/dist/react/useAgentTokenState.d.ts +3 -3
- package/dist/react/useAgentTokenState.js +8 -8
- package/dist/react/useChannelAggregate.d.ts +3 -3
- package/dist/react/useChannelAggregate.js +8 -8
- package/dist/react/useChannelMessage.d.ts +2 -2
- package/dist/react/useChannelMessage.js +4 -4
- package/dist/react/useChannelMessages.d.ts +3 -3
- package/dist/react/useChannelMessages.js +10 -10
- package/dist/react/useChannelSubscription.d.ts +2 -2
- package/dist/react/useChannelSubscription.js +2 -2
- package/dist/react/useClientStatus.d.ts +1 -1
- package/dist/react/useClientStatus.js +2 -2
- package/dist/react/useConnectionState.js +2 -2
- package/dist/react/useDeviceMap.js +2 -2
- package/dist/react/useInvocationLogs.d.ts +1 -1
- package/dist/react/useInvocationLogs.js +2 -2
- package/dist/react/useMultiAgentAggregates.d.ts +1 -1
- package/dist/react/useMultiAgentAggregates.js +5 -5
- package/dist/react/useMultiAgentChannelMessages.d.ts +1 -1
- package/dist/react/useMultiAgentChannelMessages.js +2 -2
- package/dist/react/useOfflineStatus.d.ts +2 -2
- package/dist/react/useOfflineStatus.js +31 -17
- package/dist/react/useSendMessage.d.ts +2 -2
- package/dist/react/useSendMessage.js +2 -2
- package/dist/react/useSendRpc.d.ts +2 -2
- package/dist/react/useSendRpc.js +2 -2
- package/dist/react/useTurnCredentials.d.ts +2 -2
- package/dist/react/useTurnCredentials.js +2 -2
- package/dist/react/useUpdateAggregate.d.ts +3 -3
- package/dist/react/useUpdateAggregate.js +4 -4
- package/dist/react/useUpdateMessage.d.ts +2 -2
- package/dist/react/useUpdateMessage.js +2 -2
- package/dist/refine/index.d.ts +1 -1
- package/dist/rpc/errors.d.ts +1 -1
- package/dist/rpc/index.d.ts +3 -0
- package/dist/rpc/index.js +7 -0
- package/dist/rpc/rpc-dispatcher.d.ts +4 -4
- package/dist/rpc/rpc-dispatcher.js +2 -2
- package/dist/types/common.d.ts +1 -1
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +2 -0
- package/dist/types/openapi.d.ts +1 -1
- package/dist/types/viewer.d.ts +2 -2
- package/dist/viewer/doover-data-provider.d.ts +10 -10
- package/dist/viewer/doover-data-provider.js +25 -25
- package/dist/viewer/path-parsing.d.ts +1 -1
- package/package.json +795 -8
- package/dist/test/api-args.test.js +0 -48
- package/dist/test/api-overloads.test.d.ts +0 -9
- package/dist/test/api-overloads.test.js +0 -330
- package/dist/test/apis.test.js +0 -408
- package/dist/test/auth.test.js +0 -708
- package/dist/test/batch-apis.test.js +0 -183
- package/dist/test/capabilities.test.js +0 -27
- package/dist/test/config-manager.test.js +0 -160
- package/dist/test/data-client-errors.test.js +0 -24
- package/dist/test/data-client-shape.test.js +0 -28
- package/dist/test/doover-client-dataclient.test.d.ts +0 -1
- package/dist/test/doover-client-dataclient.test.js +0 -58
- package/dist/test/doover-client-provenance.test.d.ts +0 -1
- package/dist/test/doover-client-provenance.test.js +0 -32
- package/dist/test/doover-client.test.d.ts +0 -1
- package/dist/test/doover-client.test.js +0 -42
- package/dist/test/doover-data-provider.test.d.ts +0 -1
- package/dist/test/doover-data-provider.test.js +0 -657
- package/dist/test/exports.test.d.ts +0 -1
- package/dist/test/exports.test.js +0 -80
- package/dist/test/gateway-client.test.d.ts +0 -1
- package/dist/test/gateway-client.test.js +0 -474
- package/dist/test/gateway-provenance.test.d.ts +0 -1
- package/dist/test/gateway-provenance.test.js +0 -29
- package/dist/test/gateway-subscriptions.test.d.ts +0 -1
- package/dist/test/gateway-subscriptions.test.js +0 -95
- package/dist/test/helpers.d.ts +0 -32
- package/dist/test/helpers.js +0 -115
- package/dist/test/local-agent-client.test.d.ts +0 -1
- package/dist/test/local-agent-client.test.js +0 -202
- package/dist/test/message-range-store.test.d.ts +0 -1
- package/dist/test/message-range-store.test.js +0 -183
- package/dist/test/multiplex-capabilities.test.d.ts +0 -1
- package/dist/test/multiplex-capabilities.test.js +0 -37
- package/dist/test/multiplex-conflicts.test.d.ts +0 -1
- package/dist/test/multiplex-conflicts.test.js +0 -35
- package/dist/test/multiplex-gateway.test.d.ts +0 -1
- package/dist/test/multiplex-gateway.test.js +0 -103
- package/dist/test/multiplex-merge.test.d.ts +0 -1
- package/dist/test/multiplex-merge.test.js +0 -19
- package/dist/test/multiplex-noncore.test.d.ts +0 -1
- package/dist/test/multiplex-noncore.test.js +0 -82
- package/dist/test/multiplex-passthrough.test.d.ts +0 -1
- package/dist/test/multiplex-passthrough.test.js +0 -35
- package/dist/test/multiplex-reads.test.d.ts +0 -1
- package/dist/test/multiplex-reads.test.js +0 -87
- package/dist/test/multiplex-registry.test.d.ts +0 -1
- package/dist/test/multiplex-registry.test.js +0 -81
- package/dist/test/multiplex-routing.test.d.ts +0 -1
- package/dist/test/multiplex-routing.test.js +0 -45
- package/dist/test/multiplex-status.test.d.ts +0 -1
- package/dist/test/multiplex-status.test.js +0 -63
- package/dist/test/multiplex-writes.test.d.ts +0 -1
- package/dist/test/multiplex-writes.test.js +0 -93
- package/dist/test/offline-cache.test.d.ts +0 -1
- package/dist/test/offline-cache.test.js +0 -289
- package/dist/test/provenance-regression.test.d.ts +0 -1
- package/dist/test/provenance-regression.test.js +0 -45
- package/dist/test/provenance-stamper.test.d.ts +0 -1
- package/dist/test/provenance-stamper.test.js +0 -41
- package/dist/test/provenance-type.test.d.ts +0 -1
- package/dist/test/provenance-type.test.js +0 -15
- package/dist/test/react-channel-messages-forward.test.d.ts +0 -1
- package/dist/test/react-channel-messages-forward.test.js +0 -139
- package/dist/test/react-channel-messages-range.test.d.ts +0 -1
- package/dist/test/react-channel-messages-range.test.js +0 -109
- package/dist/test/react-client-status.test.d.ts +0 -1
- package/dist/test/react-client-status.test.js +0 -35
- package/dist/test/react-dataclient.test.d.ts +0 -1
- package/dist/test/react-dataclient.test.js +0 -28
- package/dist/test/react-exports.test.d.ts +0 -1
- package/dist/test/react-exports.test.js +0 -46
- package/dist/test/react-multiagent-messages.test.d.ts +0 -1
- package/dist/test/react-multiagent-messages.test.js +0 -113
- package/dist/test/react-sources-option.test.d.ts +0 -1
- package/dist/test/react-sources-option.test.js +0 -41
- package/dist/test/react.test.d.ts +0 -1
- package/dist/test/react.test.js +0 -482
- package/dist/test/refine.test.d.ts +0 -1
- package/dist/test/refine.test.js +0 -71
- package/dist/test/rest-client.test.d.ts +0 -1
- package/dist/test/rest-client.test.js +0 -197
- package/dist/test/rpc-dispatcher.test.d.ts +0 -1
- package/dist/test/rpc-dispatcher.test.js +0 -251
- package/dist/test/singleton.test.d.ts +0 -1
- package/dist/test/singleton.test.js +0 -62
- package/dist/test/stats-rpc.test.d.ts +0 -1
- package/dist/test/stats-rpc.test.js +0 -69
- package/dist/test/status-tracker.test.d.ts +0 -1
- package/dist/test/status-tracker.test.js +0 -85
- package/dist/test/users-api.test.d.ts +0 -1
- package/dist/test/users-api.test.js +0 -19
- package/dist/test/utils.test.d.ts +0 -1
- package/dist/test/utils.test.js +0 -64
- /package/dist/{test/api-args.test.d.ts → esm/auth/auth-store.js} +0 -0
- /package/dist/{test/apis.test.d.ts → esm/client/data-client.js} +0 -0
- /package/dist/{test/auth.test.d.ts → esm/gateway/types.js} +0 -0
- /package/dist/{test/batch-apis.test.d.ts → esm/types/common.js} +0 -0
- /package/dist/{test/capabilities.test.d.ts → esm/types/index.js} +0 -0
- /package/dist/{test/config-manager.test.d.ts → esm/types/openapi.js} +0 -0
- /package/dist/{test/data-client-errors.test.d.ts → esm/types/provenance.js} +0 -0
- /package/dist/{test/data-client-shape.test.d.ts → esm/types/viewer.js} +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ConnectionStatus = "connecting" | "open";
|
|
2
|
+
export interface ConnectionState {
|
|
3
|
+
/**
|
|
4
|
+
* `"open"` once the gateway has received a `Ready` frame;
|
|
5
|
+
* `"connecting"` any time the socket is reconnecting or awaiting Ready.
|
|
6
|
+
*/
|
|
7
|
+
status: ConnectionStatus;
|
|
8
|
+
/** Timestamp of the most recent `Ready` frame, or `null` until the first one. */
|
|
9
|
+
lastOpenedAt: number | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated Prefer `useClientStatus()` — it works for both `DooverClient` and
|
|
13
|
+
* `MultiplexClient`, and carries session, latency, last error and per-source
|
|
14
|
+
* state. `useConnectionState` is gateway-flavoured and single-source only;
|
|
15
|
+
* it will remain but new code should not use it.
|
|
16
|
+
*
|
|
17
|
+
* Subscribes to the gateway's connection lifecycle and returns a snapshot
|
|
18
|
+
* suitable for a connection-indicator UI.
|
|
19
|
+
*
|
|
20
|
+
* The gateway doesn't measure application-level latency — liveness is
|
|
21
|
+
* handled at the WebSocket-protocol layer via ping/pong frames (opcodes
|
|
22
|
+
* 0x9 / 0xA) which browsers answer automatically but don't expose to JS.
|
|
23
|
+
* Dead connections surface as the `close` event, which we already handle
|
|
24
|
+
* via auto-reconnect.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useConnectionState(): ConnectionState;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useDooverClient } from "./context.js";
|
|
3
|
+
const INITIAL = {
|
|
4
|
+
status: "connecting",
|
|
5
|
+
lastOpenedAt: null,
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Prefer `useClientStatus()` — it works for both `DooverClient` and
|
|
9
|
+
* `MultiplexClient`, and carries session, latency, last error and per-source
|
|
10
|
+
* state. `useConnectionState` is gateway-flavoured and single-source only;
|
|
11
|
+
* it will remain but new code should not use it.
|
|
12
|
+
*
|
|
13
|
+
* Subscribes to the gateway's connection lifecycle and returns a snapshot
|
|
14
|
+
* suitable for a connection-indicator UI.
|
|
15
|
+
*
|
|
16
|
+
* The gateway doesn't measure application-level latency — liveness is
|
|
17
|
+
* handled at the WebSocket-protocol layer via ping/pong frames (opcodes
|
|
18
|
+
* 0x9 / 0xA) which browsers answer automatically but don't expose to JS.
|
|
19
|
+
* Dead connections surface as the `close` event, which we already handle
|
|
20
|
+
* via auto-reconnect.
|
|
21
|
+
*/
|
|
22
|
+
export function useConnectionState() {
|
|
23
|
+
const client = useDooverClient();
|
|
24
|
+
const [state, setState] = useState(() => client.gateway.isConnected() && client.gateway.getSession()
|
|
25
|
+
? {
|
|
26
|
+
status: "open",
|
|
27
|
+
lastOpenedAt: Date.now(),
|
|
28
|
+
}
|
|
29
|
+
: INITIAL);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const onReady = () => setState((prev) => ({
|
|
32
|
+
...prev,
|
|
33
|
+
status: "open",
|
|
34
|
+
lastOpenedAt: Date.now(),
|
|
35
|
+
}));
|
|
36
|
+
const onClose = () => setState((prev) => ({ ...prev, status: "connecting" }));
|
|
37
|
+
client.gateway.on("ready", onReady);
|
|
38
|
+
client.gateway.on("close", onClose);
|
|
39
|
+
return () => {
|
|
40
|
+
client.gateway.off("ready", onReady);
|
|
41
|
+
client.gateway.off("close", onClose);
|
|
42
|
+
};
|
|
43
|
+
}, [client]);
|
|
44
|
+
return state;
|
|
45
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default shape for entries in an agent's `DEVICE_MAP` — covers every field
|
|
3
|
+
* an app may request via `x-extraDeviceFields` on its
|
|
4
|
+
* `dv_proc_extended_permissions` schema (see doover-control's
|
|
5
|
+
* `ALLOWED_DEVICE_MAP_EXTRA_FIELDS` / `COMPOUND_DEVICE_MAP_SUBFIELDS`). All
|
|
6
|
+
* fields are optional because the app picks which to include — `id` is the
|
|
7
|
+
* one constant (the platform always uses it as the dict key, and the hook
|
|
8
|
+
* ensures it's also present on the entry value).
|
|
9
|
+
*
|
|
10
|
+
* Pass a narrower type as the hook's generic argument when you know exactly
|
|
11
|
+
* which fields your app requested.
|
|
12
|
+
*/
|
|
13
|
+
export interface DeviceMapEntry {
|
|
14
|
+
/** Snowflake id — always present (the hook fills it from the dict key). */
|
|
15
|
+
id: string;
|
|
16
|
+
name?: string | null;
|
|
17
|
+
display_name?: string | null;
|
|
18
|
+
type?: {
|
|
19
|
+
id?: string | number | null;
|
|
20
|
+
name?: string | null;
|
|
21
|
+
/** `type.config` is the device-type's JSON config; shape depends on the type. */
|
|
22
|
+
config?: Record<string, unknown> | null;
|
|
23
|
+
} | null;
|
|
24
|
+
group?: {
|
|
25
|
+
id?: string | number | null;
|
|
26
|
+
name?: string | null;
|
|
27
|
+
} | null;
|
|
28
|
+
organisation?: {
|
|
29
|
+
id?: string | number | null;
|
|
30
|
+
name?: string | null;
|
|
31
|
+
} | null;
|
|
32
|
+
latitude?: number | null;
|
|
33
|
+
longitude?: number | null;
|
|
34
|
+
fa_icon?: string | null;
|
|
35
|
+
notes?: string | null;
|
|
36
|
+
/** `extra_config` is a free-form JSON dict on the device; shape depends on org/usage. */
|
|
37
|
+
extra_config?: Record<string, unknown> | null;
|
|
38
|
+
/** Each app installation visible to this app, when `app_installs` (or any subfield) was requested. */
|
|
39
|
+
app_installs?: Array<{
|
|
40
|
+
id?: string | number | null;
|
|
41
|
+
name?: string | null;
|
|
42
|
+
display_name?: string | null;
|
|
43
|
+
application_id?: string | number | null;
|
|
44
|
+
application_name?: string | null;
|
|
45
|
+
}>;
|
|
46
|
+
/** Each solution installation, when `solution_installs` (or any subfield) was requested. */
|
|
47
|
+
solution_installs?: Array<{
|
|
48
|
+
id?: string | number | null;
|
|
49
|
+
display_name?: string | null;
|
|
50
|
+
solution_id?: string | number | null;
|
|
51
|
+
solution_display_name?: string | null;
|
|
52
|
+
}>;
|
|
53
|
+
/** Any other field requested via `x-extraDeviceFields` ends up here. */
|
|
54
|
+
[extra: string]: unknown;
|
|
55
|
+
}
|
|
56
|
+
export interface UseDeviceMapOptions {
|
|
57
|
+
/**
|
|
58
|
+
* Drop the agent's own id from the returned set. Defaults true — a
|
|
59
|
+
* dashboard generally doesn't want to render itself as a "device". Set
|
|
60
|
+
* false to include it.
|
|
61
|
+
*/
|
|
62
|
+
excludeSelf?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface UseDeviceMapResult<TEntry extends DeviceMapEntry> {
|
|
65
|
+
/** The device entries, in `DEVICE_MAP` insertion order, with `id` populated from each entry's dict key. */
|
|
66
|
+
devices: TEntry[];
|
|
67
|
+
/** Just the device ids — handy as the input to `useMultiAgentAggregates` etc. */
|
|
68
|
+
deviceIds: string[];
|
|
69
|
+
/** The `DEVICE_MAP` keyed by id — for O(1) per-device lookups. */
|
|
70
|
+
raw: Record<string, TEntry>;
|
|
71
|
+
/** True while the agent's `deployment_config` is loading for the first time. */
|
|
72
|
+
isLoading: boolean;
|
|
73
|
+
/** True if the underlying channel fetch errored. */
|
|
74
|
+
isError: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* True when both `agentId` and `appKey` were supplied and the loaded
|
|
77
|
+
* `deployment_config` actually contains a `DEVICE_MAP` at
|
|
78
|
+
* `applications[appKey].DEVICE_MAP`. False indicates the hook is either
|
|
79
|
+
* still warming up or the app isn't configured to expose a DEVICE_MAP —
|
|
80
|
+
* use this to distinguish "no devices granted yet" from "look at your config".
|
|
81
|
+
*/
|
|
82
|
+
hasDeviceMap: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Read an agent's `DEVICE_MAP` — the platform-populated list of devices a
|
|
86
|
+
* given app instance has been granted permission to see — from the agent's
|
|
87
|
+
* `deployment_config` channel. Returns the entries flattened, keyed, and with
|
|
88
|
+
* `id` filled in from the dict key, plus a ready-to-use `deviceIds` array.
|
|
89
|
+
*
|
|
90
|
+
* Pass a narrower entry type as the generic when your app declares specific
|
|
91
|
+
* `x-extraDeviceFields`, e.g.:
|
|
92
|
+
*
|
|
93
|
+
* ```ts
|
|
94
|
+
* interface MyEntry extends DeviceMapEntry {
|
|
95
|
+
* type?: { id?: string | null; name?: string | null; config?: { battery_voltage_tag?: string | null } | null } | null;
|
|
96
|
+
* }
|
|
97
|
+
* const { devices, deviceIds } = useDeviceMap<MyEntry>(agentId, "my_dashboard");
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* If `appKey` is missing or `applications[appKey].DEVICE_MAP` isn't present,
|
|
101
|
+
* the hook returns an empty result with `hasDeviceMap: false` — it does not
|
|
102
|
+
* silently fall back to whichever other app block happens to carry a
|
|
103
|
+
* DEVICE_MAP, since that masks misconfiguration.
|
|
104
|
+
*
|
|
105
|
+
* @param agentId The agent's id (typically from `customer_site/useRemoteParams`).
|
|
106
|
+
* @param appKey The app's key, e.g. `"connectivity_dashboard"`. `DEVICE_MAP` lives at `deployment_config.applications[appKey].DEVICE_MAP`.
|
|
107
|
+
* @param options See `UseDeviceMapOptions`.
|
|
108
|
+
*/
|
|
109
|
+
export declare function useDeviceMap<TEntry extends DeviceMapEntry = DeviceMapEntry>(agentId: string | undefined, appKey: string | undefined, options?: UseDeviceMapOptions): UseDeviceMapResult<TEntry>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useAgentChannel } from "./useAgentChannel.js";
|
|
3
|
+
/**
|
|
4
|
+
* Read an agent's `DEVICE_MAP` — the platform-populated list of devices a
|
|
5
|
+
* given app instance has been granted permission to see — from the agent's
|
|
6
|
+
* `deployment_config` channel. Returns the entries flattened, keyed, and with
|
|
7
|
+
* `id` filled in from the dict key, plus a ready-to-use `deviceIds` array.
|
|
8
|
+
*
|
|
9
|
+
* Pass a narrower entry type as the generic when your app declares specific
|
|
10
|
+
* `x-extraDeviceFields`, e.g.:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* interface MyEntry extends DeviceMapEntry {
|
|
14
|
+
* type?: { id?: string | null; name?: string | null; config?: { battery_voltage_tag?: string | null } | null } | null;
|
|
15
|
+
* }
|
|
16
|
+
* const { devices, deviceIds } = useDeviceMap<MyEntry>(agentId, "my_dashboard");
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* If `appKey` is missing or `applications[appKey].DEVICE_MAP` isn't present,
|
|
20
|
+
* the hook returns an empty result with `hasDeviceMap: false` — it does not
|
|
21
|
+
* silently fall back to whichever other app block happens to carry a
|
|
22
|
+
* DEVICE_MAP, since that masks misconfiguration.
|
|
23
|
+
*
|
|
24
|
+
* @param agentId The agent's id (typically from `customer_site/useRemoteParams`).
|
|
25
|
+
* @param appKey The app's key, e.g. `"connectivity_dashboard"`. `DEVICE_MAP` lives at `deployment_config.applications[appKey].DEVICE_MAP`.
|
|
26
|
+
* @param options See `UseDeviceMapOptions`.
|
|
27
|
+
*/
|
|
28
|
+
export function useDeviceMap(agentId, appKey, options) {
|
|
29
|
+
const excludeSelf = options?.excludeSelf ?? true;
|
|
30
|
+
const { data: deploymentConfig, isLoading, isError } = useAgentChannel(agentId, "deployment_config");
|
|
31
|
+
return useMemo(() => {
|
|
32
|
+
const empty = {
|
|
33
|
+
devices: [],
|
|
34
|
+
deviceIds: [],
|
|
35
|
+
raw: {},
|
|
36
|
+
isLoading,
|
|
37
|
+
isError,
|
|
38
|
+
hasDeviceMap: false,
|
|
39
|
+
};
|
|
40
|
+
if (!appKey)
|
|
41
|
+
return empty;
|
|
42
|
+
const block = deploymentConfig?.applications?.[appKey];
|
|
43
|
+
const map = block?.DEVICE_MAP;
|
|
44
|
+
if (!map || typeof map !== "object")
|
|
45
|
+
return empty;
|
|
46
|
+
const raw = {};
|
|
47
|
+
const devices = [];
|
|
48
|
+
for (const [id, entry] of Object.entries(map)) {
|
|
49
|
+
if (excludeSelf && id === agentId)
|
|
50
|
+
continue;
|
|
51
|
+
// dict key is the source of truth for `id` — the platform only puts it
|
|
52
|
+
// on the entry value when the app explicitly requested "id" in extra_fields
|
|
53
|
+
const filled = { ...(entry ?? {}), id };
|
|
54
|
+
raw[id] = filled;
|
|
55
|
+
devices.push(filled);
|
|
56
|
+
}
|
|
57
|
+
return { devices, deviceIds: devices.map((d) => d.id), raw, isLoading, isError, hasDeviceMap: true };
|
|
58
|
+
}, [deploymentConfig, appKey, agentId, excludeSelf, isLoading, isError]);
|
|
59
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { ChannelIdentifier } from "../types/viewer.js";
|
|
3
|
+
export declare function invocationLogsQueryKey(agentId: string | undefined, channelName: string | undefined, messageId: string | undefined): readonly ["doover", "agent", string | undefined, "channel", string | undefined, "message", string | undefined, "logs"];
|
|
4
|
+
export interface UseInvocationLogsOptions {
|
|
5
|
+
/** Defaults to true. Set false to skip the query (e.g. dialog closed). */
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* react-query retry behaviour. Defaults to false — the logs endpoint
|
|
9
|
+
* commonly 404s while logs are still materialising server-side, and a
|
|
10
|
+
* manual refetch button is friendlier than silent retry.
|
|
11
|
+
*/
|
|
12
|
+
retry?: boolean | number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Fetch the log entries for a single invocation message. The `/logs`
|
|
16
|
+
* endpoint is only meaningful for invocation messages (channel name like
|
|
17
|
+
* `dv-proc-inv-…`); other message types return 404.
|
|
18
|
+
*
|
|
19
|
+
* Generic on `TLog` — the shape of a single log entry. Defaults to `unknown`
|
|
20
|
+
* because log payloads are domain-specific (lambda telemetry, app-level
|
|
21
|
+
* structured logs, etc.) and doover-js does not own the canonical shape.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useInvocationLogs<TLog = unknown>(identifier: ChannelIdentifier, messageId: string | undefined, options?: UseInvocationLogsOptions): UseQueryResult<TLog[]>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useDooverClient } from "./context.js";
|
|
3
|
+
export function invocationLogsQueryKey(agentId, channelName, messageId) {
|
|
4
|
+
return [
|
|
5
|
+
"doover",
|
|
6
|
+
"agent",
|
|
7
|
+
agentId,
|
|
8
|
+
"channel",
|
|
9
|
+
channelName,
|
|
10
|
+
"message",
|
|
11
|
+
messageId,
|
|
12
|
+
"logs",
|
|
13
|
+
];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Fetch the log entries for a single invocation message. The `/logs`
|
|
17
|
+
* endpoint is only meaningful for invocation messages (channel name like
|
|
18
|
+
* `dv-proc-inv-…`); other message types return 404.
|
|
19
|
+
*
|
|
20
|
+
* Generic on `TLog` — the shape of a single log entry. Defaults to `unknown`
|
|
21
|
+
* because log payloads are domain-specific (lambda telemetry, app-level
|
|
22
|
+
* structured logs, etc.) and doover-js does not own the canonical shape.
|
|
23
|
+
*/
|
|
24
|
+
export function useInvocationLogs(identifier, messageId, options) {
|
|
25
|
+
const client = useDooverClient();
|
|
26
|
+
const { agentId, channelName } = identifier;
|
|
27
|
+
return useQuery({
|
|
28
|
+
queryKey: invocationLogsQueryKey(agentId, channelName, messageId),
|
|
29
|
+
queryFn: () => client.messages.getInvocationLogs(agentId, channelName, messageId),
|
|
30
|
+
enabled: !!agentId &&
|
|
31
|
+
!!channelName &&
|
|
32
|
+
!!messageId &&
|
|
33
|
+
(options?.enabled ?? true),
|
|
34
|
+
retry: options?.retry ?? false,
|
|
35
|
+
staleTime: Infinity,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { Aggregate, JSONValue, AgentAggregate } from "../types/common.js";
|
|
3
|
+
export declare function multiAgentAggregatesQueryKey(channelName: string, agentIds: string[], fields?: readonly string[], sources?: string[]): readonly ["doover", "channel", string, "aggregates", string, "src", string] | readonly ["doover", "channel", string, "aggregates", string, "src", string, {
|
|
4
|
+
readonly fields: string[];
|
|
5
|
+
}];
|
|
6
|
+
export interface UseMultiAgentAggregatesOptions {
|
|
7
|
+
/** If false, skip per-agent live subscriptions. Defaults true. */
|
|
8
|
+
liveUpdates?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Project the response to only the named top-level keys of each aggregate's
|
|
11
|
+
* `data`. Forwarded as `field_name`. Useful for large aggregates (e.g.
|
|
12
|
+
* `tag_values`) when you only need a handful of subtrees. Live updates that
|
|
13
|
+
* arrive via the per-agent subscription are *not* projected — the gateway
|
|
14
|
+
* pushes whatever it has, so consumers should still tolerate the full shape.
|
|
15
|
+
*/
|
|
16
|
+
fields?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Restrict to these source ids on a `MultiplexClient`. Ignored for a plain
|
|
19
|
+
* `DooverClient` or `LocalAgentClient`. When set, the query key is
|
|
20
|
+
* source-dimensioned so data from different source subsets is cached
|
|
21
|
+
* independently.
|
|
22
|
+
*/
|
|
23
|
+
sources?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface UseMultiAgentAggregatesResult<TData> {
|
|
26
|
+
/** Keyed by `agent_id` for O(1) lookup. */
|
|
27
|
+
aggregatesByAgent: Record<string, Aggregate<TData>>;
|
|
28
|
+
query: UseQueryResult<{
|
|
29
|
+
results: AgentAggregate<TData>[];
|
|
30
|
+
count: number;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Batch-fetch aggregates for a channel across many agents, then keep each
|
|
35
|
+
* agent's slot live via its own gateway subscription. Reconciles per-agent
|
|
36
|
+
* `channelSync`/`aggregateUpdate` events into the batched query cache.
|
|
37
|
+
*/
|
|
38
|
+
export declare function useMultiAgentAggregates<TData = Record<string, JSONValue>>(channelName: string, agentIds: string[], options?: UseMultiAgentAggregatesOptions): UseMultiAgentAggregatesResult<TData>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo } from "react";
|
|
2
|
+
import { useQuery, useQueryClient, } from "@tanstack/react-query";
|
|
3
|
+
import { useDooverClient } from "./context.js";
|
|
4
|
+
import { channelAggregateQueryKey } from "./useChannelAggregate.js";
|
|
5
|
+
export function multiAgentAggregatesQueryKey(channelName, agentIds, fields, sources) {
|
|
6
|
+
const sourceDim = sources && sources.length ? [...sources].sort().join(",") : "*";
|
|
7
|
+
const base = [
|
|
8
|
+
"doover",
|
|
9
|
+
"channel",
|
|
10
|
+
channelName,
|
|
11
|
+
"aggregates",
|
|
12
|
+
[...agentIds].sort().join(","),
|
|
13
|
+
"src",
|
|
14
|
+
sourceDim,
|
|
15
|
+
];
|
|
16
|
+
return fields && fields.length > 0
|
|
17
|
+
? [...base, { fields: [...fields].sort() }]
|
|
18
|
+
: base;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Batch-fetch aggregates for a channel across many agents, then keep each
|
|
22
|
+
* agent's slot live via its own gateway subscription. Reconciles per-agent
|
|
23
|
+
* `channelSync`/`aggregateUpdate` events into the batched query cache.
|
|
24
|
+
*/
|
|
25
|
+
export function useMultiAgentAggregates(channelName, agentIds, options) {
|
|
26
|
+
const client = useDooverClient();
|
|
27
|
+
const queryClient = useQueryClient();
|
|
28
|
+
const liveUpdates = options?.liveUpdates ?? true;
|
|
29
|
+
const sources = options?.sources;
|
|
30
|
+
const fields = options?.fields;
|
|
31
|
+
const key = multiAgentAggregatesQueryKey(channelName, agentIds, fields, sources);
|
|
32
|
+
const query = useQuery({
|
|
33
|
+
queryKey: key,
|
|
34
|
+
enabled: agentIds.length > 0,
|
|
35
|
+
staleTime: Infinity,
|
|
36
|
+
queryFn: async () => {
|
|
37
|
+
const params = {
|
|
38
|
+
agent_id: agentIds,
|
|
39
|
+
...(fields && fields.length > 0 ? { field_name: fields } : {}),
|
|
40
|
+
};
|
|
41
|
+
// Pass `{ sources }` as a trailing bag only when set — cast through
|
|
42
|
+
// `never` since the TypeScript overloads don't declare it.
|
|
43
|
+
const sourcesArg = sources ? { sources } : undefined;
|
|
44
|
+
const response = await (sourcesArg
|
|
45
|
+
? client.agents.getMultiAgentAggregates(channelName, params, sourcesArg)
|
|
46
|
+
: client.agents.getMultiAgentAggregates(channelName, params));
|
|
47
|
+
// Seed the per-agent `channelAggregateQueryKey` cache so that
|
|
48
|
+
// sibling `useChannelAggregate(id, channelName)` calls for any
|
|
49
|
+
// of these agents get an instant cache hit rather than issuing
|
|
50
|
+
// a second fetch for data we already have.
|
|
51
|
+
for (const result of response.results) {
|
|
52
|
+
const { agent_id, ...aggregate } = result;
|
|
53
|
+
queryClient.setQueryData(channelAggregateQueryKey(agent_id, channelName, sources), aggregate);
|
|
54
|
+
}
|
|
55
|
+
return response;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
const patchAgentAggregate = useCallback((agentId, aggregate) => {
|
|
59
|
+
queryClient.setQueryData(key, (current) => {
|
|
60
|
+
if (!current)
|
|
61
|
+
return current;
|
|
62
|
+
const idx = current.results.findIndex((r) => r.agent_id === agentId);
|
|
63
|
+
const next = {
|
|
64
|
+
agent_id: agentId,
|
|
65
|
+
...aggregate,
|
|
66
|
+
};
|
|
67
|
+
const results = idx === -1
|
|
68
|
+
? [...current.results, next]
|
|
69
|
+
: current.results.map((r, i) => (i === idx ? next : r));
|
|
70
|
+
return { ...current, results };
|
|
71
|
+
});
|
|
72
|
+
// Mirror live updates into the per-agent cache so sibling
|
|
73
|
+
// `useChannelAggregate` consumers see them too.
|
|
74
|
+
queryClient.setQueryData(channelAggregateQueryKey(agentId, channelName, sources), aggregate);
|
|
75
|
+
},
|
|
76
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
77
|
+
[queryClient, channelName, agentIds.join(","), sources?.join(",")]);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!liveUpdates || agentIds.length === 0)
|
|
80
|
+
return;
|
|
81
|
+
const offs = agentIds.map((agentId) => {
|
|
82
|
+
const channel = { agent_id: agentId, name: channelName };
|
|
83
|
+
return client.gateway.subscribeToChannel(channel, {
|
|
84
|
+
onAggregate: (agg) => patchAgentAggregate(agentId, agg),
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
void client.gateway.connect();
|
|
88
|
+
return () => {
|
|
89
|
+
for (const off of offs)
|
|
90
|
+
off();
|
|
91
|
+
};
|
|
92
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
93
|
+
}, [client, channelName, liveUpdates, agentIds.join(",")]);
|
|
94
|
+
const aggregatesByAgent = useMemo(() => {
|
|
95
|
+
const map = {};
|
|
96
|
+
for (const entry of query.data?.results ?? []) {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
98
|
+
const { agent_id, ...aggregate } = entry;
|
|
99
|
+
map[agent_id] = aggregate;
|
|
100
|
+
}
|
|
101
|
+
return map;
|
|
102
|
+
}, [query.data]);
|
|
103
|
+
return { aggregatesByAgent, query };
|
|
104
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type InfiniteData, type UseInfiniteQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { MessageStructure } from "../types/common.js";
|
|
3
|
+
export declare function multiAgentChannelMessagesQueryKey(channelName: string, agentIds: string[], sources?: string[], scope?: {
|
|
4
|
+
after?: string;
|
|
5
|
+
fields?: readonly string[];
|
|
6
|
+
}): readonly ["doover", "channel", string, "messages", string, "src", string] | readonly ["doover", "channel", string, "messages", string, "src", string, Record<string, unknown>];
|
|
7
|
+
export interface UseMultiAgentChannelMessagesOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Global cap on the total number of messages returned across all agents
|
|
10
|
+
* for a single request. The server distributes this budget across agents
|
|
11
|
+
* in newest-first order, so a noisy agent can starve quieter ones.
|
|
12
|
+
* Prefer `agentMessageLimit` when you want a fair per-agent slice.
|
|
13
|
+
*/
|
|
14
|
+
limit?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Per-agent cap on messages returned. Forwarded as `agent_message_limit`.
|
|
17
|
+
* Use this when fanning out across many agents that have wildly different
|
|
18
|
+
* message rates and you want each agent's window represented.
|
|
19
|
+
*/
|
|
20
|
+
agentMessageLimit?: number;
|
|
21
|
+
/** If false, skip live subscriptions per agent. Defaults true. */
|
|
22
|
+
liveUpdates?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Restrict the returned messages to those whose payload contains any
|
|
25
|
+
* of these top-level field names. Forwarded as `field_name`.
|
|
26
|
+
*/
|
|
27
|
+
fields?: string[];
|
|
28
|
+
/** Optional first-page `before` cursor (snowflake id). */
|
|
29
|
+
initialBefore?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Keep paging older automatically until `hasNextPage` is false. Each page
|
|
32
|
+
* resumes only the agents that hit `agentMessageLimit`, using their own
|
|
33
|
+
* cursors, so a noisy agent doesn't drag the quiet ones back through
|
|
34
|
+
* messages they've already returned. Almost always combined with `after`
|
|
35
|
+
* — without a lower bound this walks every agent's channel back to its
|
|
36
|
+
* first message. `maxPages` caps the walk.
|
|
37
|
+
*/
|
|
38
|
+
autoPaginate?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Hard cap on pages fetched when `autoPaginate` is set. Defaults to 20.
|
|
41
|
+
* Guards against a window that's wider than `agentMessageLimit × maxPages`
|
|
42
|
+
* messages turning into an unbounded fetch loop.
|
|
43
|
+
*/
|
|
44
|
+
maxPages?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Optional lower-bound snowflake id. Forwarded server-side so each
|
|
47
|
+
* agent's pagination stops on its own once it walks past the bound —
|
|
48
|
+
* mirrors `useChannelMessages`'s `after`. Use this to fetch a bounded
|
|
49
|
+
* time window (e.g. last 24h) across many agents without filtering
|
|
50
|
+
* on the client.
|
|
51
|
+
*/
|
|
52
|
+
after?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Restrict to these source ids on a `MultiplexClient`. Ignored for a plain
|
|
55
|
+
* `DooverClient` or `LocalAgentClient`. When set, the query key is
|
|
56
|
+
* source-dimensioned so data from different source subsets is cached
|
|
57
|
+
* independently.
|
|
58
|
+
*/
|
|
59
|
+
sources?: string[];
|
|
60
|
+
}
|
|
61
|
+
interface Page<TData> {
|
|
62
|
+
results: MessageStructure<TData>[];
|
|
63
|
+
/**
|
|
64
|
+
* Per-agent resume cursors, keyed by agent id. Present (and non-empty)
|
|
65
|
+
* only for agents that hit the per-agent limit before draining the
|
|
66
|
+
* window. This is the canonical "there is more" signal.
|
|
67
|
+
*/
|
|
68
|
+
next_cursors?: Record<string, string>;
|
|
69
|
+
/** Legacy single-cursor signal, for servers predating `next_cursors`. */
|
|
70
|
+
next?: string | null;
|
|
71
|
+
/** Legacy: agent ids that may have more older messages. */
|
|
72
|
+
at_limit_agent_ids?: string[];
|
|
73
|
+
}
|
|
74
|
+
export interface UseMultiAgentChannelMessagesResult<TData> extends Omit<UseInfiniteQueryResult<InfiniteData<Page<TData>>>, "data"> {
|
|
75
|
+
messages: MessageStructure<TData>[];
|
|
76
|
+
data: InfiniteData<Page<TData>> | undefined;
|
|
77
|
+
}
|
|
78
|
+
export declare function useMultiAgentChannelMessages<TData = unknown>(channelName: string, agentIds: string[], options?: UseMultiAgentChannelMessagesOptions): UseMultiAgentChannelMessagesResult<TData>;
|
|
79
|
+
export {};
|