@graphql-tools/executor-http
Advanced tools
Comparing version 1.1.10-alpha-9742b09ab47742f704b76ce4c8a5e50923a1676b to 1.1.10-alpha-97436b39d21a5836caeb8a0218ec9258b356a35d
# @graphql-tools/executor-http | ||
## 1.1.10-alpha-9742b09ab47742f704b76ce4c8a5e50923a1676b | ||
## 1.1.10-alpha-97436b39d21a5836caeb8a0218ec9258b356a35d | ||
@@ -11,2 +11,10 @@ ### Patch Changes | ||
- [#180](https://github.com/graphql-hive/gateway/pull/180) [`9438e21`](https://github.com/graphql-hive/gateway/commit/9438e21982ed5c6fb18cb678b275046595ae00f5) Thanks [@ardatan](https://github.com/ardatan)! - dependencies updates: | ||
- Added dependency [`@whatwg-node/disposablestack@^0.0.5` ↗︎](https://www.npmjs.com/package/@whatwg-node/disposablestack/v/0.0.5) (to `dependencies`) | ||
- [#180](https://github.com/graphql-hive/gateway/pull/180) [`9438e21`](https://github.com/graphql-hive/gateway/commit/9438e21982ed5c6fb18cb678b275046595ae00f5) Thanks [@ardatan](https://github.com/ardatan)! - Use new explicit resource management internally | ||
- [#199](https://github.com/graphql-hive/gateway/pull/199) [`b534288`](https://github.com/graphql-hive/gateway/commit/b5342885f8ac1197d70cbf45266c83b720b4f85a) Thanks [@ardatan](https://github.com/ardatan)! - Logs are now easier to read, bigger results not do not create bigger outputs but instead they are all logged in a single line | ||
- [#98](https://github.com/graphql-hive/gateway/pull/98) [`697308d`](https://github.com/graphql-hive/gateway/commit/697308df3b2dd96f28dc65a5f5361a911077e022) Thanks [@ardatan](https://github.com/ardatan)! - Bun support by using native Bun API whenever possible | ||
@@ -13,0 +21,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { ExecutionRequest, DisposableSyncExecutor, SyncExecutor, DisposableAsyncExecutor, AsyncExecutor } from '@graphql-tools/utils'; | ||
import { ExecutionRequest, DisposableSyncExecutor, DisposableAsyncExecutor } from '@graphql-tools/utils'; | ||
import { OperationDefinitionNode, GraphQLResolveInfo, DocumentNode } from 'graphql'; | ||
@@ -60,3 +60,3 @@ | ||
* Enable [Explicit Resource Management](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management) | ||
* @default false | ||
* @deprecated The executors are always disposable, and this option will be removed in the next major version, there is no need to have a flag for this. | ||
*/ | ||
@@ -66,43 +66,13 @@ disposable?: boolean; | ||
type HeadersConfig = Record<string, string>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: SyncFetchFn; | ||
disposable: true; | ||
}): DisposableSyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: SyncFetchFn; | ||
disposable: false; | ||
}): SyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: SyncFetchFn; | ||
}): SyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: AsyncFetchFn; | ||
disposable: true; | ||
}): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: AsyncFetchFn; | ||
disposable: false; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: AsyncFetchFn; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: RegularFetchFn; | ||
disposable: true; | ||
}): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: RegularFetchFn; | ||
disposable: false; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: RegularFetchFn; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
disposable: true; | ||
}): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
disposable: false; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'>): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'>): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
export { type AsyncFetchFn, type AsyncImportFn, type FetchFn, type HTTPExecutorOptions, type HeadersConfig, type RegularFetchFn, type SyncFetchFn, type SyncImportFn, type SyncResponse, buildHTTPExecutor, isLiveQueryOperationDefinitionNode }; |
@@ -1,2 +0,3 @@ | ||
import { isAsyncIterable, isPromise, fakePromise, inspect, mapAsyncIterator, mergeIncrementalResult, memoize1, getOperationASTFromRequest, mapMaybePromise, createGraphQLError } from '@graphql-tools/utils'; | ||
import { isAsyncIterable, isPromise, fakePromise, createGraphQLError, inspect, mapAsyncIterator, mergeIncrementalResult, memoize1, getOperationASTFromRequest, mapMaybePromise } from '@graphql-tools/utils'; | ||
import { DisposableSymbols } from '@whatwg-node/disposablestack'; | ||
import { File, FormData, TextDecoder, fetch } from '@whatwg-node/fetch'; | ||
@@ -59,3 +60,3 @@ import { ValueOrPromise } from 'value-or-promise'; | ||
); | ||
form.append("map", JSON.stringify(map, null, 2)); | ||
form.append("map", JSON.stringify(map)); | ||
function handleUpload(upload, i) { | ||
@@ -119,2 +120,16 @@ const indexStr = i.toString(); | ||
function createAbortErrorReason() { | ||
return new Error("Executor was disposed."); | ||
} | ||
function createGraphQLErrorForAbort(reason, extensions) { | ||
return createGraphQLError("The operation was aborted. reason: " + reason, { | ||
extensions | ||
}); | ||
} | ||
function createResultForAbort(reason, extensions) { | ||
return { | ||
errors: [createGraphQLErrorForAbort(reason, extensions)] | ||
}; | ||
} | ||
const DELIM = "\n\n"; | ||
@@ -124,3 +139,3 @@ function isReadableStream(value) { | ||
} | ||
function handleEventStreamResponse(response) { | ||
function handleEventStreamResponse(signal, response) { | ||
const body = response.body; | ||
@@ -141,2 +156,6 @@ if (!isReadableStream(body)) { | ||
async function pump() { | ||
if (signal.aborted) { | ||
await push(createResultForAbort(signal)); | ||
return stop(); | ||
} | ||
if (!body?.locked) { | ||
@@ -241,8 +260,25 @@ return stop(); | ||
function createSignalWrapper(signal) { | ||
const listeners = /* @__PURE__ */ new Set(); | ||
signal.onabort = (event) => { | ||
for (const listener of listeners) { | ||
listener(event); | ||
} | ||
}; | ||
return Object.assign(signal, { | ||
addEventListener(_type, listener) { | ||
listeners.add(listener); | ||
}, | ||
removeEventListener(_type, listener) { | ||
listeners.delete(listener); | ||
} | ||
}); | ||
} | ||
function buildHTTPExecutor(options) { | ||
const printFn = options?.print ?? defaultPrintFn; | ||
let disposeCtrl; | ||
const disposeCtrl = new AbortController(); | ||
const sharedSignal = createSignalWrapper(disposeCtrl.signal); | ||
const baseExecutor = (request) => { | ||
if (disposeCtrl?.signal.aborted) { | ||
return createResultForAbort(disposeCtrl.signal); | ||
if (sharedSignal.aborted) { | ||
return createResultForAbort(sharedSignal.reason); | ||
} | ||
@@ -277,18 +313,8 @@ const fetchFn = request.extensions?.fetch ?? options?.fetch ?? fetch; | ||
const query = printFn(request.document); | ||
let signal = disposeCtrl?.signal; | ||
let clearTimeoutFn = () => { | ||
}; | ||
let signal = sharedSignal; | ||
if (options?.timeout) { | ||
const timeoutCtrl = new AbortController(); | ||
signal = timeoutCtrl.signal; | ||
disposeCtrl?.signal.addEventListener("abort", clearTimeoutFn); | ||
const timeoutId = setTimeout(() => { | ||
if (!timeoutCtrl.signal.aborted) { | ||
timeoutCtrl.abort("timeout"); | ||
} | ||
disposeCtrl?.signal.removeEventListener("abort", clearTimeoutFn); | ||
}, options.timeout); | ||
clearTimeoutFn = () => { | ||
clearTimeout(timeoutId); | ||
}; | ||
signal = AbortSignal.any([ | ||
sharedSignal, | ||
AbortSignal.timeout(options.timeout) | ||
]); | ||
} | ||
@@ -367,3 +393,2 @@ const upstreamErrorExtensions = { | ||
}); | ||
clearTimeoutFn(); | ||
if (options?.retry != null && !fetchResult.status.toString().startsWith("2")) { | ||
@@ -376,3 +401,3 @@ throw new Error( | ||
if (contentType?.includes("text/event-stream")) { | ||
return handleEventStreamResponse(fetchResult); | ||
return handleEventStreamResponse(signal, fetchResult); | ||
} else if (contentType?.includes("multipart/mixed")) { | ||
@@ -465,4 +490,4 @@ return handleMultipartMixedResponse(fetchResult); | ||
function retryAttempt() { | ||
if (disposeCtrl?.signal.aborted) { | ||
return createResultForAbort(disposeCtrl.signal); | ||
if (sharedSignal.aborted) { | ||
return createResultForAbort(sharedSignal.reason); | ||
} | ||
@@ -489,9 +514,4 @@ attempt++; | ||
} | ||
if (!options?.disposable) { | ||
disposeCtrl = void 0; | ||
return executor; | ||
} | ||
disposeCtrl = new AbortController(); | ||
Object.defineProperties(executor, { | ||
[Symbol.dispose]: { | ||
[DisposableSymbols.dispose]: { | ||
get() { | ||
@@ -503,3 +523,3 @@ return function dispose() { | ||
}, | ||
[Symbol.asyncDispose]: { | ||
[DisposableSymbols.asyncDispose]: { | ||
get() { | ||
@@ -530,4 +550,4 @@ return function asyncDispose() { | ||
}); | ||
} else if (e.name === "AbortError" && signal?.reason) { | ||
return createGraphQLErrorForAbort(signal, { | ||
} else if (e.name === "AbortError" && signal.reason) { | ||
return createGraphQLErrorForAbort(signal.reason, { | ||
extensions: upstreamErrorExtensions | ||
@@ -547,19 +567,3 @@ }); | ||
} | ||
function createAbortErrorReason() { | ||
return new Error("Executor was disposed."); | ||
} | ||
function createGraphQLErrorForAbort(signal, extensions) { | ||
return createGraphQLError( | ||
"The operation was aborted. reason: " + signal.reason, | ||
{ | ||
extensions | ||
} | ||
); | ||
} | ||
function createResultForAbort(signal, extensions) { | ||
return { | ||
errors: [createGraphQLErrorForAbort(signal, extensions)] | ||
}; | ||
} | ||
export { buildHTTPExecutor, isLiveQueryOperationDefinitionNode }; |
{ | ||
"name": "@graphql-tools/executor-http", | ||
"version": "1.1.10-alpha-9742b09ab47742f704b76ce4c8a5e50923a1676b", | ||
"version": "1.1.10-alpha-97436b39d21a5836caeb8a0218ec9258b356a35d", | ||
"type": "module", | ||
@@ -44,2 +44,3 @@ "description": "A set of utils for faster development of GraphQL tools", | ||
"@repeaterjs/repeater": "^3.0.4", | ||
"@whatwg-node/disposablestack": "^0.0.5", | ||
"@whatwg-node/fetch": "^0.10.0", | ||
@@ -46,0 +47,0 @@ "extract-files": "^11.0.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
61361
9
1167
+ Added@graphql-tools/utils@10.6.2(transitive)
- Removed@graphql-tools/utils@10.6.1(transitive)