mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 13:25:12 +00:00
feat(infra): framework
This commit is contained in:
@@ -1,18 +1,9 @@
|
||||
import type { ExecutionResult } from 'graphql';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import { isNil, isObject, merge } from 'lodash-es';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import type { GraphQLQuery } from './graphql';
|
||||
import type { Mutations, Queries } from './schema';
|
||||
import {
|
||||
generateRandUTF16Chars,
|
||||
SPAN_ID_BYTES,
|
||||
TRACE_FLAG,
|
||||
TRACE_ID_BYTES,
|
||||
TRACE_VERSION,
|
||||
traceReporter,
|
||||
} from './utils';
|
||||
|
||||
export type NotArray<T> = T extends Array<unknown> ? never : T;
|
||||
|
||||
@@ -166,7 +157,10 @@ function formatRequestBody<Q extends GraphQLQuery>({
|
||||
return body;
|
||||
}
|
||||
|
||||
export const gqlFetcherFactory = (endpoint: string) => {
|
||||
export const gqlFetcherFactory = (
|
||||
endpoint: string,
|
||||
fetcher: (input: string, init?: RequestInit) => Promise<Response> = fetch
|
||||
) => {
|
||||
const gqlFetch = async <Query extends GraphQLQuery>(
|
||||
options: QueryOptions<Query>
|
||||
): Promise<QueryResponse<Query>> => {
|
||||
@@ -180,14 +174,13 @@ export const gqlFetcherFactory = (endpoint: string) => {
|
||||
if (!isFormData) {
|
||||
headers['content-type'] = 'application/json';
|
||||
}
|
||||
const ret = fetchWithTraceReport(
|
||||
const ret = fetcher(
|
||||
endpoint,
|
||||
merge(options.context, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: isFormData ? body : JSON.stringify(body),
|
||||
}),
|
||||
{ event: 'GraphQLRequest' }
|
||||
})
|
||||
).then(async res => {
|
||||
if (res.headers.get('content-type')?.startsWith('application/json')) {
|
||||
const result = (await res.json()) as ExecutionResult;
|
||||
@@ -205,7 +198,10 @@ export const gqlFetcherFactory = (endpoint: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
throw new GraphQLError('GraphQL query responds unexpected result');
|
||||
throw new GraphQLError(
|
||||
'GraphQL query responds unexpected result, query ' +
|
||||
options.query.operationName
|
||||
);
|
||||
});
|
||||
|
||||
return ret;
|
||||
@@ -213,47 +209,3 @@ export const gqlFetcherFactory = (endpoint: string) => {
|
||||
|
||||
return gqlFetch;
|
||||
};
|
||||
|
||||
export const fetchWithTraceReport = async (
|
||||
input: RequestInfo | URL,
|
||||
init?: RequestInit & { priority?: 'auto' | 'low' | 'high' }, // https://github.com/microsoft/TypeScript/issues/54472
|
||||
traceOptions?: { event: string }
|
||||
): Promise<Response> => {
|
||||
const startTime = new Date().toISOString();
|
||||
const spanId = generateRandUTF16Chars(SPAN_ID_BYTES);
|
||||
const traceId = generateRandUTF16Chars(TRACE_ID_BYTES);
|
||||
const traceparent = `${TRACE_VERSION}-${traceId}-${spanId}-${TRACE_FLAG}`;
|
||||
init = init || {};
|
||||
init.headers = init.headers || new Headers();
|
||||
const requestId = nanoid();
|
||||
const event = traceOptions?.event;
|
||||
if (init.headers instanceof Headers) {
|
||||
init.headers.append('x-request-id', requestId);
|
||||
init.headers.append('traceparent', traceparent);
|
||||
} else {
|
||||
const headers = init.headers as Record<string, string>;
|
||||
headers['x-request-id'] = requestId;
|
||||
headers['traceparent'] = traceparent;
|
||||
}
|
||||
|
||||
if (!traceReporter) {
|
||||
return fetch(input, init);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(input, init);
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
traceReporter!.cacheTrace(traceId, spanId, startTime, {
|
||||
requestId,
|
||||
...(event ? { event } : {}),
|
||||
});
|
||||
return response;
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
traceReporter!.uploadTrace(traceId, spanId, startTime, {
|
||||
requestId,
|
||||
...(event ? { event } : {}),
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user