• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CaptainFact / captain-fact-frontend / 20020625706

08 Dec 2025 07:49AM UTC coverage: 2.865% (-2.5%) from 5.41%
20020625706

push

github

Betree
refact: Move everythin to GraphQL, remove redux

38 of 2352 branches covered (1.62%)

Branch coverage included in aggregate %.

0 of 922 new or added lines in 45 files covered. (0.0%)

32 existing lines in 8 files now uncovered.

125 of 3338 relevant lines covered (3.74%)

0.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/app/API/graphql_api.js
1
import * as AbsintheSocket from '@absinthe/socket'
2
import {
3
  ApolloClient,
4
  ApolloLink,
5
  createHttpLink,
6
  InMemoryCache,
7
  Observable,
8
  split,
9
} from '@apollo/client'
10
import { setContext } from '@apollo/client/link/context'
11
import { getMainDefinition } from '@apollo/client/utilities'
12
import { print } from 'graphql'
13
import { Socket as PhoenixSocket } from 'phoenix'
14

15
import { GRAPHQL_API_URL } from '../config'
16
import { getFromLocalStorage, LOCAL_STORAGE_KEYS } from '../lib/local_storage'
17

18
// Convert HTTP URL to WebSocket URL
NEW
19
const getWebSocketUrl = (httpUrl) => {
×
NEW
20
  const url = new URL(httpUrl)
×
NEW
21
  const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
×
NEW
22
  return `${protocol}//${url.host}/socket`
×
23
}
24

UNCOV
25
const httpLink = createHttpLink({
×
26
  uri: GRAPHQL_API_URL,
27
})
28

29
const authLink = setContext((_, { headers }) => {
×
30
  const token = getFromLocalStorage(LOCAL_STORAGE_KEYS.TOKEN)
×
31
  if (token) {
×
32
    return { headers: { ...headers, authorization: `Bearer ${token}` } }
×
33
  } else {
34
    return { headers }
×
35
  }
36
})
37

NEW
38
const authedHttpLink = authLink.concat(httpLink)
×
39

40
// Create Phoenix socket connection
NEW
41
const phoenixSocket = new PhoenixSocket(getWebSocketUrl(GRAPHQL_API_URL), {
×
42
  params: () => {
NEW
43
    const token = getFromLocalStorage(LOCAL_STORAGE_KEYS.TOKEN)
×
NEW
44
    if (token) {
×
NEW
45
      return { token }
×
46
    } else {
NEW
47
      return {}
×
48
    }
49
  },
50
})
51

52
// Wrap Phoenix socket in AbsintheSocket
NEW
53
const absintheSocket = AbsintheSocket.create(phoenixSocket)
×
54

55
// Create custom websocket link for Absinthe subscriptions
NEW
56
const createAbsintheLink = () => {
×
NEW
57
  return new ApolloLink((operation) => {
×
NEW
58
    const { query, variables, operationName } = operation
×
NEW
59
    const queryString = print(query)
×
60

NEW
61
    return new Observable((observer) => {
×
NEW
62
      const notifier = AbsintheSocket.send(absintheSocket, {
×
63
        operation: queryString,
64
        variables: variables || {},
×
65
        operationName: operationName,
66
      })
67

NEW
68
      AbsintheSocket.observe(absintheSocket, notifier, {
×
69
        onAbort: () => {
NEW
70
          observer.error(new Error('Subscription aborted'))
×
71
        },
72
        onError: (error) => {
NEW
73
          observer.error(error)
×
74
        },
75
        onStart: () => {
76
          // Subscription started
77
        },
78
        onResult: (result) => {
NEW
79
          if (result.data) {
×
NEW
80
            observer.next({ data: result.data })
×
81
          }
NEW
82
          if (result.errors) {
×
NEW
83
            observer.error(result.errors)
×
84
          }
85
        },
86
      })
87

88
      // Return cleanup function
NEW
89
      return () => {
×
NEW
90
        AbsintheSocket.cancel(absintheSocket, notifier)
×
91
      }
92
    })
93
  })
94
}
95

NEW
96
const websocketLink = createAbsintheLink()
×
97

98
// Split link: subscriptions go through websocket, queries/mutations through HTTP
NEW
99
const link = split(
×
100
  ({ query }) => {
NEW
101
    const definition = getMainDefinition(query)
×
NEW
102
    return definition.kind === 'OperationDefinition' && definition.operation === 'subscription'
×
103
  },
104
  websocketLink,
105
  authedHttpLink,
106
)
107

UNCOV
108
const GraphQLClient = new ApolloClient({
×
109
  link,
110
  cache: new InMemoryCache(),
111
})
112

113
export default GraphQLClient
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc