UNPKG

graphql-yoga

Version:

<div align="center"><img src="./website/public/cover.png" width="720" /></div>

74 lines (73 loc) 2.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processGraphQLSSEResult = void 0; const core_1 = require("@envelop/core"); const error_js_1 = require("../../error.js"); const stringify_js_1 = require("./stringify.js"); function processGraphQLSSEResult(result, fetchAPI) { // TODO: implement "single connection mode" let pingerMs = 12000; // for testing the pings, reduce the timeout significantly if (globalThis.process?.env?.NODE_ENV === 'test') { pingerMs = 100; } const headersInit = { 'Content-Type': 'text/event-stream', Connection: 'keep-alive', 'Cache-Control': 'no-cache', 'Content-Encoding': 'none', }; const responseInit = (0, error_js_1.getResponseInitByRespectingErrors)(result, headersInit, // as per the GraphQL over SSE spec, operation errors must be reported // through the stream and the response head should always be 200: OK true); let iterator; let pinger; const textEncoder = new fetchAPI.TextEncoder(); const readableStream = new fetchAPI.ReadableStream({ start(controller) { // ping client every 12 seconds to keep the connection alive pinger = setInterval(() => { if (controller.desiredSize) { controller.enqueue(textEncoder.encode(':\n\n')); } else { // TODO: why disable pinger when no desired size? clearInterval(pinger); } }, pingerMs); if ((0, core_1.isAsyncIterable)(result)) { iterator = result[Symbol.asyncIterator](); } else { let finished = false; iterator = { next: () => { if (finished) { return Promise.resolve({ done: true, value: null }); } finished = true; return Promise.resolve({ done: false, value: result }); }, }; } }, async pull(controller) { const { done, value } = await iterator.next(); if (value != null) { controller.enqueue(textEncoder.encode(`event: next\ndata: ${(0, stringify_js_1.jsonStringifyResultWithoutInternals)(value)}\n\n`)); } if (done) { clearInterval(pinger); controller.enqueue(textEncoder.encode('event: complete\n\n')); controller.close(); } }, async cancel(e) { clearInterval(pinger); await iterator.return?.(e); }, }); return new fetchAPI.Response(readableStream, responseInit); } exports.processGraphQLSSEResult = processGraphQLSSEResult;