Skip to content

Commit

Permalink
fix: Use sse link with @live directive (redwoodjs#11375)
Browse files Browse the repository at this point in the history
There isn't any defect without the SSE link with live queries but using
explicit SSE links allows proper headers that in turn show proper
requests with the body in browser devtools.

This is something DT and I noticed when pairing. Separately another user
reported this symptom:
redwoodjs#10511 (comment)

Copied over from:
https://github.com/n1ru4l/graphql-live-query/tree/main/packages/todo-example/client-apollo/src/apollo-link
  • Loading branch information
callingmedic911 authored Sep 3, 2024
1 parent f9978fc commit 82ee362
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .changesets/11375.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- fix: Use sse link with `@live` directive (#11375) by @callingmedic911

Use SSE links that allows proper headers that in turn show proper requests with the body in browser devtools.
8 changes: 2 additions & 6 deletions packages/web/src/apollo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
useSuspenseQuery,
} from '@apollo/client/react/hooks/hooks.cjs'
import { getMainDefinition } from '@apollo/client/utilities/utilities.cjs'
import { Kind, OperationTypeNode } from 'graphql'
import { print } from 'graphql/language/printer.js'

import type { UseAuth } from '@redwoodjs/auth'
Expand All @@ -51,7 +50,7 @@ import * as SSELinkExports from './sseLink.js'
import { useCache } from './useCache.js'

// Not sure why we need to import it this way for legacy builds to work
const { SSELink } = SSELinkExports
const { SSELink, isSubscription, isLiveQuery } = SSELinkExports

export type {
CacheKey,
Expand Down Expand Up @@ -240,10 +239,7 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
({ query }) => {
const definition = getMainDefinition(query)

return (
definition.kind === Kind.OPERATION_DEFINITION &&
definition.operation === OperationTypeNode.SUBSCRIPTION
)
return isSubscription(definition) || isLiveQuery(definition)
},
new SSELink({
url: uri,
Expand Down
25 changes: 23 additions & 2 deletions packages/web/src/apollo/sseLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { HttpOptions } from '@apollo/client'
import type { Operation, FetchResult } from '@apollo/client/core'
import { ApolloLink } from '@apollo/client/link/core/core.cjs'
import { Observable } from '@apollo/client/utilities/utilities.cjs'
import { print } from 'graphql'
import type { DefinitionNode } from 'graphql'
import { Kind, OperationTypeNode, print } from 'graphql'
import type { ClientOptions, Client, RequestParams, Sink } from 'graphql-sse'
import { createClient } from 'graphql-sse'
interface SSELinkOptions extends Partial<ClientOptions> {
Expand Down Expand Up @@ -64,6 +65,26 @@ const hasTrustedDocument = (operation: Operation) => {
return operation.extensions?.persistedQuery?.sha256Hash
}

const isSubscription = (definition: DefinitionNode) => {
return (
definition.kind === Kind.OPERATION_DEFINITION &&
definition.operation === OperationTypeNode.SUBSCRIPTION
)
}

// This is a simplified version of the `@n1ru4l/graphql-live-query`.
// See discussion in https://github.com/redwoodjs/redwood/pull/11375
const isLiveQuery = (definition: DefinitionNode) => {
if (
definition.kind !== Kind.OPERATION_DEFINITION ||
definition.operation !== OperationTypeNode.QUERY
) {
return false
}

return !!definition.directives?.find((d) => d.name.value === 'live')
}

/**
* GraphQL over Server-Sent Events (SSE) spec link for Apollo Client
*/
Expand Down Expand Up @@ -125,4 +146,4 @@ class SSELink extends ApolloLink {
}
}

export { SSELink }
export { SSELink, isSubscription, isLiveQuery }

0 comments on commit 82ee362

Please sign in to comment.