[ ] GraphQL Electron Tinder |
, . 2016 . - Tinder. , - . :
- . - , - , . , , . Tinder++ Tinder . , .
, , , Electron.
React, react + redux + redux-saga + immutable. , . , , redux : , shouldComponentUpdate, .
, , store Immutable.Map.mergeDeep
, redux redux-saga . , , .
, redux . . , . , .
, redux , react. .
, . , , , , . , .
Inferno MobX. ( , ). , MobX , .
localStorage. localForage. JSON.stringify JSON.parse ( ) . , , .
IndexedDB, Dexie.js. , , . IndexedDB WebWorker .
API Tinder Android-. JS , main Electron.
, :
, stores IndexedDB, MobX . , .
Inferno , . inferno-compat, React- . material-ui, react-vistualized.
, . - React- . , . Inferno, . . - .
. React React, . , , main . MobX , MobX , - .
, - . , GraphQL. Apollo. , , :
, Apollo IPC, . :
import { ipcRenderer } from 'electron'
import { GRAPHQL } from 'shared/constants'
import uuid from 'uuid'
import { print } from 'graphql/language/printer'
export class ElectronInterface {
ipc
listeners = new Map()
constructor(ipc = ipcRenderer) {
this.ipc = ipc
this.ipc.on(GRAPHQL, this.listener)
}
listener = (event, args) => {
const { id, payload } = args
if (!id) {
throw new Error('Listener ID is not present!')
}
const resolve = this.listeners.get(id)
if (!resolve) {
throw new Error(`Listener with id ${id} does not exist!`)
}
resolve(payload)
this.listeners.delete(id)
}
printRequest(request) {
return {
...request,
query: print(request.query)
}
}
generateMessage(id, request) {
return {
id,
payload: this.printRequest(request)
}
}
setListener(request, resolve) {
const id = uuid.v1()
this.listeners.set(id, resolve)
const message = this.generateMessage(id, request)
this.ipc.send(GRAPHQL, message)
}
query = request => {
return new Promise(this.setListener.bind(this, request))
}
}
main . ServerAPI.
GraphQL :
// @flow
import { ServerAPI } from './ServerAPI'
import { graphql } from 'graphql'
export default function callGraphQLFactory(instance: ServerAPI) {
return function callGraphQL(payload: any) {
const { query, variables, operationName } = payload
return graphql(
instance.schema,
query,
null,
instance,
variables,
operationName
)
}
}
:
// @flow
export default function generateMessage(id: string, res: any) {
return {
id,
payload: res
}
}
, :
// @flow
import { ServerAPI } from './ServerAPI'
import { GRAPHQL } from 'shared/constants'
type RequestArguments = {
id: string,
payload: any
}
export default function processRequestFactory(instance: ServerAPI) {
return async function processRequest(event: Event, args: RequestArguments) {
const { id, payload } = args
const res = await instance.callGraphQL(payload)
const message = instance.generateMessage(id, res)
if (instance.app.window !== null) {
instance.app.window.webContents.send(GRAPHQL, message)
}
}
}
, , :
import { ipcMain } from 'electron'
ipcMain.on(GRAPHQL, instance.processRequest)
NeDB, main IPC renderer .
react-router. , API . router5 + middleware, MobX. Electron - URL , . , , .
react-router@v4 Flexbox CSS Grid. . , react-router !
webpack electron-packager, electron-forge. , Electron. electron-packager electron-compile, JS/TS, (Less, Stylus, SCSS), .
GraphQL ( ). . .
, - Electron. GraphQL-over-IPC npm , .
2.0
-> GitHub
->