Restart graphql subscriptions after ws client recreation

Disposing the client does not restart active subscriptions.
This commit is contained in:
schroda
2025-11-06 02:41:58 +01:00
parent 71b70ab0da
commit 1d639f45ca
2 changed files with 27 additions and 1 deletions

View File

@@ -1186,11 +1186,16 @@ export class RequestManager {
abortRequest,
};
case GQLMethod.USE_SUBSCRIPTION:
return useSubscription<Data, Variables>(operation, {
// eslint-disable-next-line no-case-declarations
const subscription = useSubscription<Data, Variables>(operation, {
client: this.graphQLClient.client,
variables,
...(options as SubscriptionHookOptions<Data, Variables>),
});
this.graphQLClient.useRestartSubscription(subscription.restart);
return subscription;
default:
throw new Error(`unexpected GQLRequest type "${method}"`);
}

View File

@@ -26,6 +26,8 @@ import { getMainDefinition } from '@apollo/client/utilities';
import { TypePolicies } from '@apollo/client/cache';
import { removeTypenameFromVariables } from '@apollo/client/link/remove-typename';
import { d } from 'koration';
import { useId } from '@mantine/hooks';
import { useEffect } from 'react';
import { BaseClient } from '@/lib/requests/client/BaseClient.ts';
import { StrictTypedTypePolicies } from '@/lib/graphql/generated/apollo-helpers.ts';
import { AuthManager } from '@/features/authentication/AuthManager.ts';
@@ -197,6 +199,8 @@ export class GraphQLClient extends BaseClient<
private wsClientAliveCheckInterval: NodeJS.Timeout | undefined = undefined;
private activeConnectionSubscriptions = new Map<string, () => void>();
constructor(handleRefreshToken: (refreshToken: string) => AbortableApolloMutationResponse<UserRefreshMutation>) {
super(handleRefreshToken);
@@ -335,6 +339,8 @@ export class GraphQLClient extends BaseClient<
this.createWSClient(false);
this.client.setLink(this.createLink());
this.activeConnectionSubscriptions.forEach((callback) => callback());
}
}, checkHeartbeatInterval);
}
@@ -356,4 +362,19 @@ export class GraphQLClient extends BaseClient<
}
public override updateConfig() {}
public useRestartSubscription(restart: () => void) {
const id = useId();
this.activeConnectionSubscriptions.set(id, () => {
restart();
});
useEffect(
() => () => {
this.activeConnectionSubscriptions.delete(id);
},
[id],
);
}
}