diff --git a/README.md b/README.md
index 72a731424..a500143c5 100644
--- a/README.md
+++ b/README.md
@@ -132,6 +132,7 @@ The React component `` and all middlewares expose the following op
- `props` (Middlewares & React Component)
- `endpoint` [`string`](optional) - the GraphQL endpoint url.
- `subscriptionEndpoint` [`string`](optional) - the GraphQL subscriptions endpoint url.
+ - `subscriptionEndpointConnectionTimeout` [`number`](optional) - the GraphQL subscriptions endpoint connection timeout.
- `workspaceName` [`string`](optional) - in case you provide a GraphQL Config, you can name your workspace here
- `config` [`string`](optional) - the JSON of a GraphQL Config. See an example [here](https://github.com/prismagraphql/graphql-playground/blob/master/packages/graphql-playground-react/src/localDevIndex.tsx#L47)
- `settings` [`ISettings`](optional) - Editor settings in json format as [described here](https://github.com/prismagraphql/graphql-playground#settings)
diff --git a/packages/graphql-playground-html/src/render-playground-page.ts b/packages/graphql-playground-html/src/render-playground-page.ts
index 5d37e98f4..b44c8e0ce 100644
--- a/packages/graphql-playground-html/src/render-playground-page.ts
+++ b/packages/graphql-playground-html/src/render-playground-page.ts
@@ -5,6 +5,7 @@ import getLoadingMarkup from './get-loading-markup'
export interface MiddlewareOptions {
endpoint?: string
subscriptionEndpoint?: string
+ subscriptionEndpointConnectionTimeout?: number
workspaceName?: string
env?: any
config?: any
diff --git a/packages/graphql-playground-react/src/components/Playground.tsx b/packages/graphql-playground-react/src/components/Playground.tsx
index c3fae7b40..8c3bfcf58 100644
--- a/packages/graphql-playground-react/src/components/Playground.tsx
+++ b/packages/graphql-playground-react/src/components/Playground.tsx
@@ -44,6 +44,7 @@ import {
setLinkCreator,
schemaFetcher,
setSubscriptionEndpoint,
+ setSubscriptionEndpointConnectionTimeout,
} from '../state/sessions/fetchingSagas'
import { Session } from '../state/sessions/reducers'
import { getWorkspaceId } from './Playground/util/getWorkspaceId'
@@ -62,6 +63,7 @@ export interface Props {
endpoint: string
sessionEndpoint: string
subscriptionEndpoint?: string
+ subscriptionEndpointConnectionTimeout?: number
projectId?: string
shareEnabled?: boolean
fixedEndpoint?: boolean
@@ -194,6 +196,11 @@ export class Playground extends React.PureComponent {
setLinkCreator(props.createApolloLink)
this.getSchema()
setSubscriptionEndpoint(props.subscriptionEndpoint)
+ if (props.subscriptionEndpointConnectionTimeout) {
+ setSubscriptionEndpointConnectionTimeout(
+ props.subscriptionEndpointConnectionTimeout,
+ )
+ }
}
UNSAFE_componentWillMount() {
@@ -262,15 +269,15 @@ export class Playground extends React.PureComponent {
props.sessionHeaders && props.sessionHeaders.length > 0
? props.sessionHeaders
: props.headers && Object.keys(props.headers).length > 0
- ? JSON.stringify(props.headers)
- : undefined,
+ ? JSON.stringify(props.headers)
+ : undefined,
credentials: props.settings['request.credentials'],
useTracingHeader:
!this.initialSchemaFetch &&
props.settings['tracing.tracingSupported'],
}
const schema = await schemaFetcher.fetch(data)
- schemaFetcher.subscribe(data, newSchema => {
+ schemaFetcher.subscribe(data, (newSchema) => {
if (
data.endpoint === this.props.endpoint ||
data.endpoint === this.props.sessionEndpoint
@@ -413,24 +420,21 @@ const mapStateToProps = createStructuredSelector({
sessionEndpoint: getEndpoint,
})
-export default connect(
- mapStateToProps,
- {
- selectTabIndex,
- selectNextTab,
- selectPrevTab,
- newSession,
- closeSelectedTab,
- initState,
- saveSettings,
- saveConfig,
- setTracingSupported,
- injectHeaders,
- setConfigString,
- schemaFetchingError,
- schemaFetchingSuccess,
- },
-)(Playground)
+export default connect(mapStateToProps, {
+ selectTabIndex,
+ selectNextTab,
+ selectPrevTab,
+ newSession,
+ closeSelectedTab,
+ initState,
+ saveSettings,
+ saveConfig,
+ setTracingSupported,
+ injectHeaders,
+ setConfigString,
+ schemaFetchingError,
+ schemaFetchingSuccess,
+})(Playground)
const PlaygroundContainer = styled.div`
flex: 1;
diff --git a/packages/graphql-playground-react/src/components/PlaygroundWrapper.tsx b/packages/graphql-playground-react/src/components/PlaygroundWrapper.tsx
index 834549286..4d9c1c7dd 100644
--- a/packages/graphql-playground-react/src/components/PlaygroundWrapper.tsx
+++ b/packages/graphql-playground-react/src/components/PlaygroundWrapper.tsx
@@ -42,6 +42,7 @@ export interface PlaygroundWrapperProps {
endpoint?: string
endpointUrl?: string
subscriptionEndpoint?: string
+ subscriptionEndpointConnectionTimeout?: number
setTitle?: boolean
settings?: ISettings
shareEnabled?: boolean
@@ -199,7 +200,9 @@ class PlaygroundWrapper extends React.Component<
return endpoint.replace(/^http/, 'ws')
}
- UNSAFE_componentWillReceiveProps(nextProps: PlaygroundWrapperProps & ReduxProps) {
+ UNSAFE_componentWillReceiveProps(
+ nextProps: PlaygroundWrapperProps & ReduxProps,
+ ) {
// Reactive props (props that cause a state change upon being changed)
if (
nextProps.endpoint !== this.props.endpoint ||
@@ -361,25 +364,27 @@ class PlaygroundWrapper extends React.Component<
}}
>
- {this.props.config &&
- this.state.activeEnv && (
-
- )}
+ {this.props.config && this.state.activeEnv && (
+
+ )}
{
+ getPlaygroundRef = (ref) => {
this.playground = ref
if (typeof this.props.getRef === 'function') {
this.props.getRef(ref)
@@ -450,11 +455,11 @@ class PlaygroundWrapper extends React.Component<
})
}
- private handleChangeEndpoint = endpoint => {
+ private handleChangeEndpoint = (endpoint) => {
this.setState({ endpoint })
}
- private handleChangeSubscriptionsEndpoint = subscriptionEndpoint => {
+ private handleChangeSubscriptionsEndpoint = (subscriptionEndpoint) => {
this.setState({ subscriptionEndpoint })
}
@@ -475,7 +480,7 @@ class PlaygroundWrapper extends React.Component<
private async updateSubscriptionsUrl() {
const candidates = this.getSubscriptionsUrlCandidated(this.state.endpoint)
- const validCandidate = await find(candidates, candidate =>
+ const validCandidate = await find(candidates, (candidate) =>
this.wsEndpointValid(candidate),
)
if (validCandidate) {
@@ -502,18 +507,18 @@ class PlaygroundWrapper extends React.Component<
}
private wsEndpointValid(url): Promise {
- return new Promise(resolve => {
+ return new Promise((resolve) => {
const socket = new WebSocket(url, 'graphql-ws')
- socket.addEventListener('open', event => {
+ socket.addEventListener('open', (event) => {
socket.send(JSON.stringify({ type: 'connection_init' }))
})
- socket.addEventListener('message', event => {
+ socket.addEventListener('message', (event) => {
const data = JSON.parse(event.data)
if (data.type === 'connection_ack') {
resolve(true)
}
})
- socket.addEventListener('error', event => {
+ socket.addEventListener('error', (event) => {
resolve(false)
})
setTimeout(() => {
@@ -533,10 +538,7 @@ const mapStateToProps = (state, ownProps) => {
return { theme, settings }
}
-export default connect(
- mapStateToProps,
- { injectTabs },
-)(PlaygroundWrapper)
+export default connect(mapStateToProps, { injectTabs })(PlaygroundWrapper)
async function find(
iterable: any[],
diff --git a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts
index b45d1fcbb..f160f443d 100644
--- a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts
+++ b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts
@@ -41,11 +41,16 @@ import { set } from 'immutable'
// tslint:disable
let subscriptionEndpoint
+let subscriptionTimeout = 20000
export function setSubscriptionEndpoint(endpoint) {
subscriptionEndpoint = endpoint
}
+export function setSubscriptionEndpointConnectionTimeout(timeout) {
+ subscriptionTimeout = timeout
+}
+
export interface LinkCreatorProps {
endpoint: string
headers?: Headers
@@ -78,7 +83,8 @@ export const defaultLinkCreator = (
}
const subscriptionClient = new SubscriptionClient(subscriptionEndpoint, {
- timeout: 20000,
+ minTimeout: subscriptionTimeout,
+ timeout: subscriptionTimeout,
lazy: true,
connectionParams,
})
@@ -86,7 +92,7 @@ export const defaultLinkCreator = (
const webSocketLink = new WebSocketLink(subscriptionClient)
return {
link: ApolloLink.split(
- operation => isSubscription(operation),
+ (operation) => isSubscription(operation),
webSocketLink as any,
httpLink,
),
@@ -137,7 +143,7 @@ function* runQuerySaga(action) {
yield put(setCurrentQueryStartTime(new Date()))
let firstResponse = false
- const channel = eventChannel(emitter => {
+ const channel = eventChannel((emitter) => {
let closed = false
if (subscriptionClient && operationIsSubscription) {
subscriptionClient.onDisconnected(() => {
@@ -151,10 +157,10 @@ function* runQuerySaga(action) {
})
}
const subscription = execute(link, operation).subscribe({
- next: function(value) {
+ next: function (value) {
emitter({ value })
},
- error: error => {
+ error: (error) => {
emitter({ error })
emitter(END)
},