-
-
Notifications
You must be signed in to change notification settings - Fork 812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding apollo dev tools. #298
Changes from 13 commits
8d14e45
8a22e49
768bcaf
d918322
b03ae54
d5253d3
a71c1a5
8730ab2
94a6690
00bf432
7c9083d
42bf06b
1208575
d5828e4
4b05639
d2af214
e81a778
d35416d
57169aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,18 @@ let socket; | |
|
||
const workerOnMessage = message => { | ||
const { data } = message; | ||
|
||
if (data && data.source === 'apollo-devtools-backend') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we get at least one message from apollo backend (the code in the worker) it means that apollo client is being used in the app. So we tell apollo dev tools to display its panel in chrome dev tools. Also we forward the message from webworker to react native debugger web part. |
||
if (!window.__APOLLO_DEVTOOLS_SHOULD_DISPLAY_PANEL__) { | ||
window.__APOLLO_DEVTOOLS_SHOULD_DISPLAY_PANEL__ = true; | ||
} | ||
|
||
postMessage({ | ||
source: 'apollo-devtools-backend', | ||
payload: data, | ||
}, '*'); | ||
} | ||
|
||
if (data && (data.__IS_REDUX_NATIVE_MESSAGE__ || data.__REPORT_REACT_DEVTOOLS_PORT__)) { | ||
return true; | ||
} | ||
|
@@ -43,14 +55,22 @@ const workerOnMessage = message => { | |
socket.send(JSON.stringify(data)); | ||
}; | ||
|
||
const onWindowMessage = e => { | ||
const {data} = e; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we receive data from panel in web part, we forward the message to the worker. There are some checks for payload, but they are there since apollo dev tools don't strictly follow api for event emitter. |
||
if (data && data.source === 'apollo-devtools-proxy') { | ||
const message = typeof data.payload === 'string' ? { event: data.payload } : data.payload; | ||
worker.postMessage({ source: 'apollo-devtools-proxy', ...message }); | ||
} | ||
}; | ||
|
||
const createJSRuntime = () => { | ||
// This worker will run the application javascript code, | ||
// making sure that it's run in an environment without a global | ||
// document, to make it consistent with the JSC executor environment. | ||
// eslint-disable-next-line | ||
worker = new Worker(`${__webpack_public_path__}RNDebuggerWorker.js`); | ||
worker.addEventListener('message', workerOnMessage); | ||
|
||
window.addEventListener('message', onWindowMessage); | ||
actions.setDebuggerWorker(worker, 'connected'); | ||
}; | ||
|
||
|
@@ -59,6 +79,7 @@ const shutdownJSRuntime = () => { | |
scriptExecuted = false; | ||
if (worker) { | ||
worker.terminate(); | ||
window.removeEventListener('messsage', onWindowMessage); | ||
setDevMenuMethods([]); | ||
} | ||
worker = null; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,24 @@ export const getClearAsyncStorageFn = AsyncStorage => { | |
return () => AsyncStorage.clear().catch(f => f); | ||
}; | ||
|
||
export const getSafeAsyncStorage = AsyncStorage => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sometimes Async storage throws errors, we want to silence them |
||
return { | ||
async getItem(key) { | ||
try { | ||
return AsyncStorage.getItem(key); | ||
} catch (e) { | ||
return null; | ||
} | ||
}, | ||
async setItem(key, value) { | ||
try { | ||
return AsyncStorage.setItem(key, value); | ||
} catch (e) { | ||
} | ||
} | ||
} | ||
}; | ||
|
||
export const getShowAsyncStorageFn = AsyncStorage => { | ||
if (!AsyncStorage.getAllKeys || !AsyncStorage.getItem) return; | ||
return async () => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,10 @@ import devToolsEnhancer, { composeWithDevTools } from './reduxAPI'; | |
import * as RemoteDev from './remotedev'; | ||
import { getRequiredModules, ignoreRNDIntervalSpy } from './utils'; | ||
import { toggleNetworkInspect } from './networkInspect'; | ||
|
||
import { getSafeAsyncStorage } from './asyncStorage'; | ||
import Bridge from 'apollo-client-devtools/bridge'; | ||
import { initBackend, sendBridgeReady } from 'apollo-client-devtools/backend'; | ||
import { version as devToolsVersion } from 'apollo-client-devtools/package.json'; | ||
/* eslint-disable no-underscore-dangle */ | ||
self.__REMOTEDEV__ = RemoteDev; | ||
|
||
|
@@ -51,6 +54,48 @@ const setupRNDebugger = async message => { | |
checkAvailableDevMenuMethods(modules, message.networkInspect); | ||
reportDefaultReactDevToolsPort(modules); | ||
} | ||
|
||
const interval = setInterval(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apollo client doesn't have any event emitted when it is set up. To overcome that I just poll the client till it appears. |
||
if (!self.__APOLLO_CLIENT__) { | ||
return; | ||
} | ||
|
||
clearInterval(interval); | ||
|
||
const hook = { | ||
ApolloClient: self.__APOLLO_CLIENT__, | ||
devToolsVersion | ||
}; | ||
|
||
let listener; | ||
|
||
const bridge = new Bridge({ | ||
listen(fn) { | ||
listener = self.addEventListener('message', evt => { | ||
if (evt.data.source === 'apollo-devtools-proxy') { | ||
return fn(evt.data); | ||
} | ||
}); | ||
}, | ||
send(data) { | ||
postMessage({ | ||
...data, | ||
source: 'apollo-devtools-backend', | ||
}); | ||
}, | ||
}); | ||
|
||
bridge.on('init', () => { | ||
sendBridgeReady(); | ||
}); | ||
|
||
bridge.on("shutdown", () => { | ||
self.removeEventListener('message', listener); | ||
}); | ||
|
||
initBackend(bridge, hook, getSafeAsyncStorage(modules.AsyncStorage)); | ||
|
||
}, 1000); | ||
}; | ||
|
||
const messageHandlers = { | ||
|
@@ -66,6 +111,7 @@ const messageHandlers = { | |
} catch (err) { | ||
error = err.message; | ||
} | ||
|
||
sendReply(null /* result */, error); | ||
|
||
if (!error) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apollo dev tools are not displayed in the chrome dev tools by default.
It tries to check if window.apolloClient is set. Because we don't have apollo client in window (it is in web worker), I've created a separate bool for it.