Timeout Plugin for each request
There isn't any plugin to support timeout. I created one and does not seem to do the intended task.

The problem is it executes the entire request lifecycle, and when its out, checks if timer expired and then throws the error. 
To implement something that is in realtime timeout would be great feature. That is it should timeout even while it is processing.

```
export const TimeOutPlugin = function (timeoutMs: number) {
    return {

        async requestDidStart(requestContext: any): Promise<any> {
            const start = performance.now();
            let operation: string | null;
            let currTimeoutMs = timeoutMs;
            const elapsed1 = Math.round(performance.now() - start);
            let size = JSON.stringify(requestContext.response).length * 2;
            if (elapsed1 > currTimeoutMs) {
                console.log("Timeout is set at (currTimeoutMs):", `${currTimeoutMs}ms`);
                console.log('requestDidStart() Timeout occurred for operation=', operation, '\t duration=', elapsed1, 'ms\t bytes=', size);
                throw new CustomGraphQLError('This query exceeds our TIMEOUT limits.', 403);
            }
            return {
                // eslint-disable-next-line require-await
                async didResolveOperation(context) {
                    operation = context.operationName;
                    const elapsed2 = Math.round(performance.now() - start);
                    if (elapsed2 > currTimeoutMs) {
                        console.log("Timeout is set at (currTimeoutMs):", `${currTimeoutMs}ms`);
                        console.log('didResolveOperation() Timeout occurred for operation=', operation, '\t duration=', elapsed2, 'ms\t bytes=', size);
                        throw new GraphQLError("This query exceeds our TIMEOUT limits.", {
                            extensions: { code: 'Forbidden', statusCode: 403 }
                        });
                    }
                },
                // eslint-disable-next-line require-await
                async willSendResponse(context) {
                    size = JSON.stringify(context.response).length * 2;
                    const elapsed3 = Math.round(performance.now() - start);
                    if (elapsed3 > currTimeoutMs) {
                        console.log("Timeout is set at (currTimeoutMs):", `${currTimeoutMs}ms`);
                        console.log('willSendResponse() Timeout occurred for operation=', operation, '\t duration=', elapsed3, 'ms\t bytes=', size);
                        throw new CustomGraphQLError('This query exceeds our TIMEOUT limits.', 403);
                    }
                }
            };
        },
        // eslint-disable-next-line require-await
        async unexpectedErrorProcessingRequest({ error }: any, requestContext: any): Promise<any> {
            // Handle unexpected errors and set the desired status code
            if (error instanceof CustomGraphQLError) {
                throw error;
            }
        }
    };
};
```