UNPKG

@graphql-tools/executor

Version:

Fork of GraphQL.js' execute function

81 lines (80 loc) 2.79 kB
/** @internal */ export class DeferredFragmentRecord { path; label; id; parentDeferUsage; pendingExecutionGroups; successfulExecutionGroups; children; pending; fns; constructor(path, label, parentDeferUsage) { this.path = path; this.label = label; this.parentDeferUsage = parentDeferUsage; this.pendingExecutionGroups = new Set(); this.successfulExecutionGroups = new Set(); this.children = new Set(); this.pending = false; this.fns = []; } onPending(fn) { this.fns.push(fn); } setAsPending() { this.pending = true; for (const fn of this.fns) { fn(); } } } export function isDeferredFragmentRecord(deliveryGroup) { return deliveryGroup instanceof DeferredFragmentRecord; } /** * @internal */ export class DeferredFragmentFactory { _rootDeferredFragments = new Map(); get(deferUsage, path) { const deferUsagePath = this._pathAtDepth(path, deferUsage.depth); let deferredFragmentRecords; if (deferUsagePath === undefined) { deferredFragmentRecords = this._rootDeferredFragments; } else { // A doubly nested Map<Path, Map<DeferUsage, DeferredFragmentRecord>> // could be used, but could leak memory in long running operations. // A WeakMap could be used instead. The below implementation is // WeakMap-Like, saving the Map on the Path object directly. // Alternatively, memory could be reclaimed manually, taking care to // also reclaim memory for nested DeferredFragmentRecords if the parent // is removed secondary to an error. deferredFragmentRecords = deferUsagePath.deferredFragmentRecords; if (deferredFragmentRecords === undefined) { deferredFragmentRecords = new Map(); deferUsagePath.deferredFragmentRecords = deferredFragmentRecords; } } let deferredFragmentRecord = deferredFragmentRecords.get(deferUsage); if (deferredFragmentRecord === undefined) { const { label, parentDeferUsage } = deferUsage; deferredFragmentRecord = new DeferredFragmentRecord(deferUsagePath, label, parentDeferUsage); deferredFragmentRecords.set(deferUsage, deferredFragmentRecord); } return deferredFragmentRecord; } _pathAtDepth(path, depth) { if (depth === 0) { return; } const stack = []; let currentPath = path; while (currentPath !== undefined) { stack.unshift(currentPath); currentPath = currentPath.prev; } return stack[depth - 1]; } }