UNPKG

@graphprotocol/client-polling-live

Version:
98 lines (97 loc) 4.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@envelop/core"); const graphql_1 = require("graphql"); const repeater_1 = require("@repeaterjs/repeater"); const schema_1 = require("@graphql-tools/schema"); function usePollingLive({ config: { defaultInterval = 1000, defaultPauseOnBackground = true } = {}, } = {}) { return { onSchemaChange({ schema, replaceSchema }) { if (!schema.getDirective('live')) { replaceSchema((0, schema_1.mergeSchemas)({ schemas: [schema], typeDefs: /* GraphQL */ ` directive @live(interval: Int = ${defaultInterval}, pauseOnBackground: Boolean = ${defaultPauseOnBackground}) on QUERY `, assumeValid: true, assumeValidSDL: true, })); } }, onExecute({ args, executeFn, setExecuteFn }) { let liveDirectiveNode; args.document = (0, graphql_1.visit)(args.document, { OperationDefinition(node) { if (args.operationName != null && node.name?.value !== args.operationName) { return; } const directives = []; if (node.directives && node.operation === 'query') { for (const directive of node.directives) { if (directive.name.value === 'live') { liveDirectiveNode = directive; } else { directives.push(directive); } } return { ...node, directives, }; } return node; }, }); if (liveDirectiveNode) { const intervalArgNode = liveDirectiveNode.arguments?.find((argNode) => argNode.name.value === 'interval'); let pauseOnBackground = defaultPauseOnBackground; const pauseOnBackgroundArgNode = liveDirectiveNode.arguments?.find((argNode) => argNode.name.value === 'pauseOnBackground'); if (pauseOnBackgroundArgNode?.value?.kind === graphql_1.Kind.BOOLEAN) { pauseOnBackground = pauseOnBackgroundArgNode.value.value; } let intervalMs = defaultInterval; if (intervalArgNode?.value?.kind === graphql_1.Kind.INT) { intervalMs = parseInt(intervalArgNode.value.value); } function checkHidden() { if (!pauseOnBackground) { return false; } return globalThis.document?.hidden ?? false; } setExecuteFn((args) => new repeater_1.Repeater((push, stop) => { let finished = false; async function pump() { if (finished) { return; } if (!checkHidden()) { const result = await executeFn(args); if ((0, core_1.isAsyncIterable)(result)) { push({ data: null, errors: [new graphql_1.GraphQLError('Execution returned AsyncIterable which is not supported!')], isLive: true, }); stop(); return; } result.isLive = true; if (finished) { return; } push(result); } setTimeout(pump, intervalMs); } pump(); stop.then(() => { finished = true; }); })); } }, }; } exports.default = usePollingLive;