mirror of
https://github.com/wassname/talk.git
synced 2026-07-01 01:27:39 +08:00
129 lines
4.1 KiB
JavaScript
129 lines
4.1 KiB
JavaScript
import {createStore} from './store';
|
|
import {createClient, apolloErrorReporter} from './client';
|
|
import pym from './pym';
|
|
import EventEmitter from 'eventemitter2';
|
|
import {createReduxEmitter} from './events';
|
|
import {createRestClient} from './rest';
|
|
import thunk from 'redux-thunk';
|
|
import {loadTranslations} from './i18n';
|
|
import bowser from 'bowser';
|
|
import {BASE_PATH} from 'coral-framework/constants/url';
|
|
import {createPluginsService} from './plugins';
|
|
import {createNotificationService} from './notification';
|
|
import {createGraphQLRegistry} from './graphqlRegistry';
|
|
import globalFragments from 'coral-framework/graphql/fragments';
|
|
import {createStorage} from 'coral-framework/services/storage';
|
|
import {createHistory} from 'coral-framework/services/history';
|
|
|
|
/**
|
|
* getAuthToken returns the active auth token or null
|
|
* Note: this method does not have access to the cookie based token used by
|
|
* browsers that don't allow us to use cross domain iframe local storage.
|
|
* @return {string|null}
|
|
*/
|
|
const getAuthToken = (store, storage) => {
|
|
let state = store.getState();
|
|
|
|
if (state.config.auth_token) {
|
|
|
|
// if an auth_token exists in config, use it.
|
|
return state.config.auth_token;
|
|
|
|
} else if (!bowser.safari && !bowser.ios && storage) {
|
|
|
|
// Use local storage auth tokens where there's a stable api.
|
|
return storage.getItem('token');
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
/**
|
|
* createContext setups and returns Talk dependencies that should be
|
|
* passed to `TalkProvider`.
|
|
* @param {Object} [config] configuration
|
|
* @param {Object} [config.reducers] extra reducers to add to redux
|
|
* @param {Array} [config.pluginsConfig] plugin configuration as returned by importing pluginsConfig
|
|
* @param {Object} [config.graphqlExtensions] additional extension to the graphql framework
|
|
* @param {Object} [config.notification] replace default notification service
|
|
* @return {Object} context
|
|
*/
|
|
export function createContext({reducers = {}, pluginsConfig = [], graphqlExtension = {}, notification} = {}) {
|
|
const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
const eventEmitter = new EventEmitter({wildcard: true});
|
|
const storage = createStorage();
|
|
const history = createHistory(BASE_PATH);
|
|
let store = null;
|
|
const token = () => {
|
|
|
|
// Try to get the token from localStorage. If it isn't here, it may
|
|
// be passed as a cookie.
|
|
|
|
// NOTE: THIS IS ONLY EVER EVALUATED ONCE, IN ORDER TO SEND A DIFFERNT
|
|
// TOKEN YOU MUST DISCONNECT AND RECONNECT THE WEBSOCKET CLIENT.
|
|
return getAuthToken(store, storage);
|
|
};
|
|
const rest = createRestClient({
|
|
uri: `${BASE_PATH}api/v1`,
|
|
token,
|
|
});
|
|
const client = createClient({
|
|
uri: `${BASE_PATH}api/v1/graph/ql`,
|
|
liveUri: `${protocol}://${location.host}${BASE_PATH}api/v1/live`,
|
|
token,
|
|
});
|
|
const plugins = createPluginsService(pluginsConfig);
|
|
const graphqlRegistry = createGraphQLRegistry(plugins.getSlotFragments.bind(plugins));
|
|
if (!notification) {
|
|
|
|
// Use default notification service (pym based)
|
|
notification = createNotificationService(pym);
|
|
}
|
|
const context = {
|
|
client,
|
|
pym,
|
|
plugins,
|
|
eventEmitter,
|
|
rest,
|
|
graphqlRegistry,
|
|
notification,
|
|
storage,
|
|
history,
|
|
};
|
|
|
|
// Load framework fragments.
|
|
Object.keys(globalFragments).forEach((key) => graphqlRegistry.addFragment(key, globalFragments[key]));
|
|
|
|
// Register graphql extension
|
|
graphqlRegistry.add(graphqlExtension);
|
|
|
|
// Register plugin graphql extensions.
|
|
plugins.getGraphQLExtensions().forEach((ext) => graphqlRegistry.add(ext));
|
|
|
|
// Load plugin translations.
|
|
plugins.getTranslations().forEach((t) => loadTranslations(t));
|
|
|
|
// Pass any events through our parent.
|
|
eventEmitter.onAny((eventName, value) => {
|
|
pym.sendMessage('event', JSON.stringify({eventName, value}));
|
|
});
|
|
|
|
const finalReducers = {
|
|
...reducers,
|
|
...plugins.getReducers(),
|
|
apollo: client.reducer(),
|
|
};
|
|
|
|
store = createStore(finalReducers, [
|
|
client.middleware(),
|
|
thunk.withExtraArgument(context),
|
|
apolloErrorReporter,
|
|
createReduxEmitter(eventEmitter),
|
|
]);
|
|
|
|
return {
|
|
...context,
|
|
store,
|
|
};
|
|
}
|