graphql
Version:
A Query Language and Runtime which can target any service.
1 lines • 16.6 kB
Source Map (JSON)
{"version":3,"file":"BranchingIncrementalExecutor.js","sourceRoot":"","sources":["../../../src/execution/legacyIncremental/BranchingIncrementalExecutor.ts"],"names":[],"mappings":"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","sourcesContent":["/** @category Legacy Incremental Execution */\n\nimport { AccumulatorMap } from '../../jsutils/AccumulatorMap.ts';\nimport { getBySet } from '../../jsutils/getBySet.ts';\nimport { invariant } from '../../jsutils/invariant.ts';\nimport { isSameSet } from '../../jsutils/isSameSet.ts';\nimport { memoize1 } from '../../jsutils/memoize1.ts';\nimport { memoize2 } from '../../jsutils/memoize2.ts';\nimport type { ObjMap } from '../../jsutils/ObjMap.ts';\n\nimport type {\n GraphQLError,\n GraphQLFormattedError,\n} from '../../error/GraphQLError.ts';\n\nimport type {\n DeferUsage,\n FieldDetails,\n GroupedFieldSet,\n} from '../collectFields.ts';\nimport type { ExecutionResult, FormattedExecutionResult } from '../Executor.ts';\nimport type {\n DeferUsageSet,\n ExecutionPlan,\n} from '../incremental/buildExecutionPlan.ts';\nimport { IncrementalExecutor } from '../incremental/IncrementalExecutor.ts';\n\nimport { BranchingIncrementalPublisher } from './BranchingIncrementalPublisher.ts';\n\n/**\n * Results for an operation that produced legacy incremental payloads.\n * @typeParam TInitialData - Shape of the initial result data payload.\n * @typeParam TDeferredData - Shape of deferred fragment data payloads.\n * @typeParam TStreamItem - Shape of streamed list items.\n * @typeParam TExtensions - Shape of extensions payloads.\n */\nexport interface LegacyExperimentalIncrementalExecutionResults<\n TInitialData = ObjMap<unknown>,\n TDeferredData = ObjMap<unknown>,\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> {\n /** Initial execution result delivered before subsequent legacy incremental payloads. */\n initialResult: LegacyInitialIncrementalExecutionResult<\n TInitialData,\n TExtensions\n >;\n /** Async stream of legacy incremental payloads delivered after the initial result. */\n subsequentResults: AsyncGenerator<\n LegacySubsequentIncrementalExecutionResult<\n TDeferredData,\n TStreamItem,\n TExtensions\n >,\n void,\n void\n >;\n}\n\n/**\n * Initial execution result for an operation that produced legacy incremental payloads.\n *\n * Unlike `InitialIncrementalExecutionResult`, the legacy initial result does\n * not include a `pending` list. Subsequent payloads identify their location\n * directly with `path` and optional `label` fields.\n * @typeParam TInitialData - Shape of the initial data payload.\n * @typeParam TExtensions - Shape of the extensions payload.\n */\nexport interface LegacyInitialIncrementalExecutionResult<\n TInitialData = ObjMap<unknown>,\n TExtensions = ObjMap<unknown>,\n> extends ExecutionResult<TInitialData, TExtensions> {\n /** Data produced by the initial execution payload. */\n data: TInitialData;\n /** Indicates that subsequent legacy incremental payloads will follow. */\n hasNext: true;\n /** Additional non-standard metadata included in the initial result. */\n extensions?: TExtensions;\n}\n\n/**\n * Subsequent payload produced by legacy incremental execution.\n *\n * Legacy subsequent payloads may contain deferred fragment data, streamed list\n * items, or only `hasNext: false` to complete the response stream.\n * @typeParam TDeferredData - Shape of deferred fragment data payloads.\n * @typeParam TStreamItem - Shape of streamed list items.\n * @typeParam TExtensions - Shape of the extensions payload.\n */\nexport interface LegacySubsequentIncrementalExecutionResult<\n TDeferredData = ObjMap<unknown>,\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> {\n /** Deferred or streamed payloads delivered by this response. */\n incremental?: ReadonlyArray<\n LegacyIncrementalResult<TDeferredData, TStreamItem, TExtensions>\n >;\n /** Indicates whether more legacy incremental payloads will follow. */\n hasNext: boolean;\n /** Additional non-standard metadata included in this payload. */\n extensions?: TExtensions;\n}\n\n/**\n * Deferred fragment or streamed list payload produced by legacy incremental execution.\n * @typeParam TDeferredData - Shape of deferred fragment data.\n * @typeParam TStreamItem - Shape of streamed list items.\n * @typeParam TExtensions - Shape of extensions payloads.\n */\nexport type LegacyIncrementalResult<\n TDeferredData = ObjMap<unknown>,\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> =\n | LegacyIncrementalDeferResult<TDeferredData, TExtensions>\n | LegacyIncrementalStreamResult<TStreamItem, TExtensions>;\n\n/**\n * Legacy incremental payload produced by a deferred fragment.\n *\n * The payload location is identified directly by `path` and optional `label`\n * instead of by an `id` from a pending entry.\n * @typeParam TDeferredData - Shape of deferred fragment data.\n * @typeParam TExtensions - Shape of extensions payloads.\n */\nexport interface LegacyIncrementalDeferResult<\n TDeferredData = ObjMap<unknown>,\n TExtensions = ObjMap<unknown>,\n> extends ExecutionResult<TDeferredData, TExtensions> {\n /** Response path to the deferred fragment payload. */\n path: ReadonlyArray<string | number>;\n /** Label from the `@defer` directive. */\n label?: string;\n}\n\n/**\n * Legacy incremental payload produced by a streamed list field.\n * @typeParam TStreamItem - Shape of streamed list items.\n * @typeParam TExtensions - Shape of extensions payloads.\n */\nexport interface LegacyIncrementalStreamResult<\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> {\n /** Errors raised while producing streamed items. */\n errors?: ReadonlyArray<GraphQLError>;\n /** Streamed list items delivered by this payload. */\n items: ReadonlyArray<TStreamItem> | null;\n /** Response path to the first streamed list item in this payload. */\n path: ReadonlyArray<string | number>;\n /** Label from the `@stream` directive. */\n label?: string;\n /** Additional non-standard metadata included in this payload. */\n extensions?: TExtensions;\n}\n\nconst buildBranchingExecutionPlanFromInitial = memoize1(\n (groupedFieldSet: GroupedFieldSet) =>\n buildBranchingExecutionPlan(groupedFieldSet),\n);\n\nconst buildBranchingExecutionPlanFromDeferred = memoize2(\n (groupedFieldSet: GroupedFieldSet, deferUsageSet: DeferUsageSet) =>\n buildBranchingExecutionPlan(groupedFieldSet, deferUsageSet),\n);\n\n/**\n * JSON-serializable form of legacy incremental execution results.\n * @typeParam TInitialData - Shape of the formatted initial result data payload.\n * @typeParam TDeferredData - Shape of formatted deferred fragment data payloads.\n * @typeParam TStreamItem - Shape of formatted streamed list items.\n * @typeParam TExtensions - Shape of formatted extensions payloads.\n */\nexport interface FormattedLegacyExperimentalIncrementalExecutionResults<\n TInitialData = ObjMap<unknown>,\n TDeferredData = ObjMap<unknown>,\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> {\n /** Formatted initial execution result. */\n initialResult: FormattedLegacyInitialIncrementalExecutionResult<\n TInitialData,\n TExtensions\n >;\n /** Async stream of formatted legacy incremental payloads. */\n subsequentResults: AsyncGenerator<\n FormattedLegacySubsequentIncrementalExecutionResult<\n TDeferredData,\n TStreamItem,\n TExtensions\n >,\n void,\n void\n >;\n}\n\n/**\n * JSON-serializable form of a legacy initial incremental execution result.\n * @typeParam TInitialData - Shape of the formatted initial data payload.\n * @typeParam TExtensions - Shape of the formatted extensions payload.\n */\nexport interface FormattedLegacyInitialIncrementalExecutionResult<\n TInitialData = ObjMap<unknown>,\n TExtensions = ObjMap<unknown>,\n> extends FormattedExecutionResult<TInitialData, TExtensions> {\n /** Formatted data produced by the initial execution payload. */\n data: TInitialData;\n /** Indicates that subsequent legacy incremental payloads will follow. */\n hasNext: true;\n /** Additional non-standard metadata included in the formatted initial result. */\n extensions?: TExtensions;\n}\n\n/**\n * JSON-serializable form of a legacy subsequent incremental execution payload.\n * @typeParam TDeferredData - Shape of formatted deferred fragment data payloads.\n * @typeParam TStreamItem - Shape of formatted streamed list items.\n * @typeParam TExtensions - Shape of formatted extensions payloads.\n */\nexport interface FormattedLegacySubsequentIncrementalExecutionResult<\n TDeferredData = ObjMap<unknown>,\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> {\n /** Formatted deferred or streamed payloads delivered by this response. */\n incremental?: ReadonlyArray<\n FormattedLegacyIncrementalResult<TDeferredData, TStreamItem, TExtensions>\n >;\n /** Indicates whether more legacy incremental payloads will follow. */\n hasNext: boolean;\n /** Additional non-standard metadata included in this formatted payload. */\n extensions?: TExtensions;\n}\n\n/**\n * JSON-serializable deferred fragment or streamed list payload produced by\n * legacy incremental execution.\n * @typeParam TDeferredData - Shape of formatted deferred fragment data.\n * @typeParam TStreamItem - Shape of formatted streamed list items.\n * @typeParam TExtensions - Shape of formatted extensions payloads.\n */\nexport type FormattedLegacyIncrementalResult<\n TDeferredData = ObjMap<unknown>,\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> =\n | FormattedLegacyIncrementalDeferResult<TDeferredData, TExtensions>\n | FormattedLegacyIncrementalStreamResult<TStreamItem, TExtensions>;\n\n/**\n * JSON-serializable form of a legacy deferred fragment payload.\n * @typeParam TDeferredData - Shape of formatted deferred fragment data.\n * @typeParam TExtensions - Shape of formatted extensions payloads.\n */\nexport interface FormattedLegacyIncrementalDeferResult<\n TDeferredData = ObjMap<unknown>,\n TExtensions = ObjMap<unknown>,\n> extends FormattedExecutionResult<TDeferredData, TExtensions> {\n /** Response path to the formatted deferred fragment payload. */\n path: ReadonlyArray<string | number>;\n /** Label from the `@defer` directive. */\n label?: string;\n}\n\n/**\n * JSON-serializable form of a legacy streamed list payload.\n * @typeParam TStreamItem - Shape of formatted streamed list items.\n * @typeParam TExtensions - Shape of formatted extensions payloads.\n */\nexport interface FormattedLegacyIncrementalStreamResult<\n TStreamItem = unknown,\n TExtensions = ObjMap<unknown>,\n> {\n /** Formatted errors raised while producing streamed items. */\n errors?: ReadonlyArray<GraphQLFormattedError>;\n /** Formatted streamed list items delivered by this payload. */\n items: ReadonlyArray<TStreamItem> | null;\n /** Response path to the first streamed list item in this formatted payload. */\n path: ReadonlyArray<string | number>;\n /** Label from the `@stream` directive. */\n label?: string;\n /** Additional non-standard metadata included in this formatted payload. */\n extensions?: TExtensions;\n}\n/** @internal */\nexport class BranchingIncrementalExecutor extends IncrementalExecutor<LegacyExperimentalIncrementalExecutionResults> {\n override getCreateSubExecutor(): (\n deferUsageSet?: DeferUsageSet,\n ) => BranchingIncrementalExecutor {\n const validatedExecutionArgs = this.validatedExecutionArgs;\n const sharedExecutionContext = this.sharedExecutionContext;\n\n return (deferUsageSet?: DeferUsageSet) =>\n new BranchingIncrementalExecutor(\n validatedExecutionArgs,\n sharedExecutionContext,\n deferUsageSet,\n );\n }\n\n override buildResponse(\n data: ObjMap<unknown> | null,\n ): ExecutionResult | LegacyExperimentalIncrementalExecutionResults {\n const work = this.getIncrementalWork();\n const { tasks, streams } = work;\n if (tasks?.length === 0 && streams?.length === 0) {\n return super.buildResponse(data);\n }\n\n const errors = this.collectedErrors.errors;\n invariant(data !== null);\n const incrementalPublisher = new BranchingIncrementalPublisher();\n return incrementalPublisher.buildResponse(\n data,\n errors,\n work,\n this.validatedExecutionArgs.externalAbortSignal,\n this.getFinishSharedExecution(),\n );\n }\n\n override buildRootExecutionPlan(\n originalGroupedFieldSet: GroupedFieldSet,\n ): ExecutionPlan {\n return buildBranchingExecutionPlanFromInitial(originalGroupedFieldSet);\n }\n\n override buildSubExecutionPlan(\n originalGroupedFieldSet: GroupedFieldSet,\n ): ExecutionPlan {\n return this.deferUsageSet === undefined\n ? buildBranchingExecutionPlanFromInitial(originalGroupedFieldSet)\n : buildBranchingExecutionPlanFromDeferred(\n originalGroupedFieldSet,\n this.deferUsageSet,\n );\n }\n}\n\nfunction buildBranchingExecutionPlan(\n originalGroupedFieldSet: GroupedFieldSet,\n parentDeferUsages: DeferUsageSet = new Set<DeferUsage>(),\n): ExecutionPlan {\n const groupedFieldSet = new AccumulatorMap<string, FieldDetails>();\n\n const newGroupedFieldSets = new Map<\n DeferUsageSet,\n AccumulatorMap<string, FieldDetails>\n >();\n\n for (const [responseKey, fieldGroup] of originalGroupedFieldSet) {\n for (const fieldDetails of fieldGroup) {\n const deferUsage = fieldDetails.deferUsage;\n const deferUsageSet =\n deferUsage === undefined\n ? new Set<DeferUsage>()\n : new Set([deferUsage]);\n if (isSameSet(parentDeferUsages, deferUsageSet)) {\n groupedFieldSet.add(responseKey, fieldDetails);\n } else {\n let newGroupedFieldSet = getBySet(newGroupedFieldSets, deferUsageSet);\n if (newGroupedFieldSet === undefined) {\n newGroupedFieldSet = new AccumulatorMap();\n newGroupedFieldSets.set(deferUsageSet, newGroupedFieldSet);\n }\n newGroupedFieldSet.add(responseKey, fieldDetails);\n }\n }\n }\n\n return {\n groupedFieldSet,\n newGroupedFieldSets,\n };\n}\n"]}