Skip to content

Commit

Permalink
use http2
Browse files Browse the repository at this point in the history
  • Loading branch information
enisdenjo committed Dec 18, 2022
1 parent 5b1bcb5 commit fe1f93a
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ graphql-sse
- [handler](modules/handler.md)
- [use/fetch](modules/use_fetch.md)
- [use/http](modules/use_http.md)
- [use/http2](modules/use_http2.md)
17 changes: 17 additions & 0 deletions docs/interfaces/use_http2.RequestContext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[graphql-sse](../README.md) / [use/http2](../modules/use_http2.md) / RequestContext

# Interface: RequestContext

[use/http2](../modules/use_http2.md).RequestContext

## Table of contents

### Properties

- [res](use_http2.RequestContext.md#res)

## Properties

### res

**res**: `Http2ServerResponse`
48 changes: 48 additions & 0 deletions docs/modules/use_http2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[graphql-sse](../README.md) / use/http2

# Module: use/http2

## Table of contents

### Interfaces

- [RequestContext](../interfaces/use_http2.RequestContext.md)

### Functions

- [createHandler](use_http2.md#createhandler)

## Functions

### createHandler

**createHandler**<`Context`\>(`options`): (`req`: `Http2ServerRequest`, `res`: `Http2ServerResponse`) => `Promise`<`void`\>

#### Type parameters

| Name | Type |
| :------ | :------ |
| `Context` | extends [`OperationContext`](handler.md#operationcontext) = `undefined` |

#### Parameters

| Name | Type |
| :------ | :------ |
| `options` | [`HandlerOptions`](../interfaces/handler.HandlerOptions.md)<`Http2ServerRequest`, [`RequestContext`](../interfaces/use_http2.RequestContext.md), `Context`\> |

#### Returns

`fn`

▸ (`req`, `res`): `Promise`<`void`\>

##### Parameters

| Name | Type |
| :------ | :------ |
| `req` | `Http2ServerRequest` |
| `res` | `Http2ServerResponse` |

##### Returns

`Promise`<`void`\>
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
"require": "./lib/use/http.js",
"import": "./lib/use/http.mjs"
},
"./lib/use/http2": {
"types": "./lib/use/http2.d.ts",
"require": "./lib/use/http2.js",
"import": "./lib/use/http2.mjs"
},
"./package.json": "./package.json"
},
"types": "lib/index.d.ts",
Expand Down
54 changes: 54 additions & 0 deletions src/use/http2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { Http2ServerRequest, Http2ServerResponse } from 'http2';
import {
createHandler as createRawHandler,
HandlerOptions,
OperationContext,
} from '../handler';

export interface RequestContext {
res: Http2ServerResponse;
}

export function createHandler<Context extends OperationContext = undefined>(
options: HandlerOptions<Http2ServerRequest, RequestContext, Context>,
): (req: Http2ServerRequest, res: Http2ServerResponse) => Promise<void> {
const handler = createRawHandler(options);
return async function handleRequest(req, res) {
const [body, init] = await handler({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- The method will always be available with http requests.
method: req.method!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- The url will always be available with http requests.
url: req.url!,
headers: req.headers,
body: () =>
new Promise((resolve, reject) => {
let body = '';
req.on('data', (chunk) => (body += chunk));
req.once('error', reject);
req.once('end', () => {
req.off('error', reject);
resolve(body);
});
}),
raw: req,
context: { res },
});

res.writeHead(init.status, init.statusText, init.headers);

if (!body || typeof body === 'string') {
return new Promise<void>((resolve) =>
res.end(body || '', () => resolve()),
);
}

res.once('close', body.return);
for await (const value of body) {
await new Promise<void>((resolve, reject) =>
res.write(value, (err) => (err ? reject(err) : resolve())),
);
}
res.off('close', body.return);
return new Promise((resolve) => res.end(resolve));
};
}

0 comments on commit fe1f93a

Please sign in to comment.