-
Notifications
You must be signed in to change notification settings - Fork 375
/
environment.js
179 lines (153 loc) · 4.82 KB
/
environment.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import 'regenerator-runtime/runtime'
import { NativeModules, Platform } from 'react-native'
import {
RelayNetworkLayer,
retryMiddleware,
urlMiddleware,
perfMiddleware,
} from 'react-relay-network-modern/node8'
import { SubscriptionClient } from 'subscriptions-transport-ws'
import { Environment, RecordSource, Store } from 'relay-runtime'
const logStyle = {
relayOK:
'font-weight:bold;color:#FFFFFF;background-color:#F26B02;letter-spacing:1pt;word-spacing:2pt;font-size:12px;text-align:left;font-family:arial, helvetica, sans-serif;line-height:1;',
relayERROR:
'font-weight:bold;color:#FFFFFF;background-color:#880606;letter-spacing:1pt;word-spacing:2pt;font-size:12px;text-align:left;font-family:arial, helvetica, sans-serif;line-height:1;',
title:
'font-weight:normal;font-style:italic;color:#FFFFFF;background-color:#000000;',
}
// eslint-disable-next-line
// if (__DEV__) {
// installRelayDevTools()
// }
// @TODO: patch web CoreModule
if (Platform.OS === 'web') {
const CoreModule = {
start: async () => {},
restart: async () => console.warn('not implemented in web'),
dropDatabase: async () => console.warn('not implemented in web'),
// TODO: remove circle dependencies with containers to implem directly panic here
panic: async () => console.warn('not implemented in web'),
throwException: () => {
throw new Error('thrown exception')
},
getPort: async () => {
const url = new URL(window.location.href)
return url.searchParams.get('gql-port') || '8700'
},
isBotRunning: async () => console.warn('not implemented in web'),
startBot: async () => console.warn('not implemented in web'),
stopBot: async () => console.warn('not implemented in web'),
getNetworkConfig: async () => console.warn('not implemented in web'),
updateNetworkConfig: async () => console.warn('not implemented in web'),
}
NativeModules.CoreModule = CoreModule
}
const { CoreModule } = NativeModules
let getIP = () =>
new Promise(resolve => {
if (Platform.OS === 'web') {
return resolve(window.location.hostname)
}
return resolve('127.0.0.1')
})
const setupSubscription = async (config, variables, cacheConfig, observer) => {
try {
const query = config.text
const subscriptionClient = new SubscriptionClient(
`ws://${await getIP()}:${await CoreModule.getPort()}/query`,
{
reconnect: true,
}
)
const onNext = result => {
observer.onNext(result)
}
const onError = error => {
observer.onError(error)
}
const onComplete = () => {
observer.onCompleted()
}
subscriptionClient
.request({ query, variables })
.subscribe(onNext, onError, onComplete)
} catch (err) {
console.error(err)
}
// client.unsubscribe()
}
const perfLogger = (msg, req, res) => {
try {
if (res.ok) {
console.groupCollapsed(
'%c RELAY %c %s',
logStyle.relayOK,
logStyle.title,
msg
)
} else {
const errorReason = res.text
? res.text
: `Server return empty response with Status Code: ${res.status}.`
console.group('%c RELAY %c %s', logStyle.relayERROR, logStyle.title, msg)
console.error(errorReason)
}
if (typeof req !== 'undefined') {
console.dir(req)
}
if (typeof res !== 'undefined') {
console.dir(res)
}
console.groupEnd()
} catch (_) {
console.log('[RELAY_NETWORK]', msg, req, res)
}
}
const _fetchQuery = async () => `http://${await getIP()}:${await CoreModule.getPort()}/query`
const fetchQuery = req => new Promise((resolve, reject) => {
_fetchQuery().then(resolve)
.catch(err => {
console.log('waiting for daemon', err)
setTimeout(() => resolve(fetchQuery(req)), 1000)
})
})
let middlewares = [
// eslint-disable-next-line
__DEV__ ? perfMiddleware({ logger: perfLogger }) : null,
urlMiddleware({
url: fetchQuery,
}),
retryMiddleware({
fetchTimeout: 10000,
retryDelays: () => 1000,
beforeRetry: ({ forceRetry, abort, delay, attempt, lastError, req }) => {
// Unlock query
console.groupCollapsed('%c RELAY %c %s', logStyle.relayERROR, logStyle.title, 'fetch query error')
console.warn(lastError)
// eslint-disable-next-line
if (__DEV__) {
window.forceRelayRetry = forceRetry
console.warn(
'call `forceRelayRetry()` for immediately retry! Or wait ' +
delay +
' ms.'
)
}
console.groupEnd()
if (attempt > 5) abort()
},
}),
]
const opts = {
subscribeFn: setupSubscription,
}
// Create a network layer from the fetch function
const network = new RelayNetworkLayer(middlewares, opts)
const store = new Store(new RecordSource())
const environment = new Environment({
network,
store,
// ... other options
})
export default environment