From b515d09157f995e5470593aa6151f9c5b5a0a810 Mon Sep 17 00:00:00 2001 From: mikeslee Date: Mon, 6 Jan 2025 17:11:30 -0800 Subject: [PATCH 1/2] Allow connectionParams to be passed in wsOptions --- src/plugins/replication-graphql/graphql-websocket.ts | 3 ++- src/types/plugins/replication-graphql.d.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/replication-graphql/graphql-websocket.ts b/src/plugins/replication-graphql/graphql-websocket.ts index e8209df639a..58e91aefe08 100644 --- a/src/plugins/replication-graphql/graphql-websocket.ts +++ b/src/plugins/replication-graphql/graphql-websocket.ts @@ -24,12 +24,13 @@ export function getGraphQLWebSocket( GRAPHQL_WEBSOCKET_BY_URL, url, () => { + const connectionParamsHeaders = headers ? { headers } : undefined; const wsClient = createClient({ ...options, url, shouldRetry: () => true, webSocketImpl: IsomorphicWebSocket, - connectionParams: headers ? { headers } : undefined, + connectionParams: options.connectionParams || connectionParamsHeaders, }); return { url, diff --git a/src/types/plugins/replication-graphql.d.ts b/src/types/plugins/replication-graphql.d.ts index e346daeab2d..dc0188cc6bf 100644 --- a/src/types/plugins/replication-graphql.d.ts +++ b/src/types/plugins/replication-graphql.d.ts @@ -28,7 +28,7 @@ export type RxGraphQLReplicationPushQueryBuilder = ( rows: RxReplicationWriteToMasterRow[] ) => RxGraphQLReplicationQueryBuilderResponse; -export type RxGraphQLPullWSOptions = Omit; +export type RxGraphQLPullWSOptions = Omit; export type RxGraphQLReplicationPullQueryBuilder = ( latestPulledCheckpoint: CheckpointType | undefined, From 21708f710deb7bb43dd81344782bf42df39f6f51 Mon Sep 17 00:00:00 2001 From: mikeslee Date: Tue, 7 Jan 2025 07:19:34 -0800 Subject: [PATCH 2/2] Add test and documentation --- docs-src/docs/replication-graphql.md | 4 +++- test/unit/replication-graphql.test.ts | 15 +++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs-src/docs/replication-graphql.md b/docs-src/docs/replication-graphql.md index fa6fca90d5d..3ad3fc084d2 100644 --- a/docs-src/docs/replication-graphql.md +++ b/docs-src/docs/replication-graphql.md @@ -333,7 +333,9 @@ const replicationState = replicateGraphQL( // Websocket options that can be passed as a parameter to initialize the subscription // Can be applied anything from the graphql-ws ClientOptions - https://the-guild.dev/graphql/ws/docs/interfaces/client.ClientOptions - // Excepting parameters: 'url', 'shouldRetry', 'webSocketImpl', 'connectionParams' - locked for the internal usage + // Except these parameters: 'url', 'shouldRetry', 'webSocketImpl' - locked for internal usage + // Note: if you provide connectionParams as a wsOption, make sure it returns any necessary headers (e.g. authorization) + // because providing your own connectionParams prevents headers from being included automatically wsOptions: { retryAttempts: 10, } diff --git a/test/unit/replication-graphql.test.ts b/test/unit/replication-graphql.test.ts index 246c00fa355..fe162b117ad 100644 --- a/test/unit/replication-graphql.test.ts +++ b/test/unit/replication-graphql.test.ts @@ -1693,8 +1693,14 @@ describe('replication-graphql.test.ts', () => { }, 'error': () => { capturedWSStates.push('error'); - } - } + }, + }, + connectionParams: () => { + capturedWSStates.push('connectionParams'); + return { + token: 'Bearer token' + }; + }, }, }, headers: { @@ -1709,18 +1715,19 @@ describe('replication-graphql.test.ts', () => { await replicationState.awaitInitialReplication(); await waitUntil(() => { - return capturedWSStates.length === 2; + return capturedWSStates.length === 3; }); assert.equal(capturedWSStates.includes('connected'), true); assert.equal(capturedWSStates.includes('connecting'), true); + assert.equal(capturedWSStates.includes('connectionParams'), true); assert.equal(capturedWSStates.includes('closed'), false); assert.equal(capturedWSStates.includes('error'), false); replicationState.cancel(); await waitUntil(() => { - return capturedWSStates.length === 3; + return capturedWSStates.length === 4; }); assert.equal(capturedWSStates.includes('closed'), true);