Allow overriding fetch implementation

This commit is contained in:
Andras Schmelczer 2025-02-25 22:52:47 +00:00
commit 9cebf53707
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
3 changed files with 17 additions and 6 deletions

View file

@ -17,12 +17,13 @@ export interface CheckConnectionResult {
export class SyncService { export class SyncService {
private client!: Client<paths>; private client!: Client<paths>;
private clientWithoutRetries!: Client<paths>; private clientWithoutRetries!: Client<paths>;
private _fetchImplementation: typeof globalThis.fetch = globalThis.fetch;
public constructor( public constructor(
private readonly settings: Settings, private readonly settings: Settings,
private readonly logger: Logger private readonly logger: Logger
) { ) {
this.createClient(settings.getSettings().remoteUri); this.createClient(this.settings.getSettings().remoteUri);
settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => { settings.addOnSettingsChangeHandlers((newSettings, oldSettings) => {
if (newSettings.remoteUri === oldSettings.remoteUri) { if (newSettings.remoteUri === oldSettings.remoteUri) {
@ -33,6 +34,11 @@ export class SyncService {
}); });
} }
public set fetchImplementation(fetch: typeof globalThis.fetch) {
this._fetchImplementation = fetch;
this.createClient(this.settings.getSettings().remoteUri);
}
private static formatError( private static formatError(
error: components["schemas"]["SerializedError"] error: components["schemas"]["SerializedError"]
): string { ): string {
@ -289,7 +295,7 @@ export class SyncService {
private createClient(remoteUri: string): void { private createClient(remoteUri: string): void {
this.client = createClient<paths>({ this.client = createClient<paths>({
baseUrl: remoteUri, baseUrl: remoteUri,
fetch: retriedFetchFactory(this.logger) fetch: retriedFetchFactory(this.logger, this._fetchImplementation)
}); });
this.clientWithoutRetries = createClient<paths>({ this.clientWithoutRetries = createClient<paths>({

View file

@ -45,6 +45,10 @@ export class SyncClient {
return this._database.getDocuments().size; return this._database.getDocuments().size;
} }
public set fetchImplementation(fetch: typeof globalThis.fetch) {
this._syncService.fetchImplementation = fetch;
}
public static async create( public static async create(
fs: FileSystemOperations, fs: FileSystemOperations,
persistence: PersistenceProvider< persistence: PersistenceProvider<

View file

@ -2,8 +2,6 @@ import * as fetchRetryFactory from "fetch-retry";
import type { RequestInitRetryParams } from "fetch-retry"; import type { RequestInitRetryParams } from "fetch-retry";
import type { Logger } from "src/tracing/logger"; import type { Logger } from "src/tracing/logger";
const fetchWithRetry = fetchRetryFactory.default(fetch);
function getUrlFromInput(input: RequestInfo | URL): string { function getUrlFromInput(input: RequestInfo | URL): string {
if (input instanceof URL) { if (input instanceof URL) {
return input.href; return input.href;
@ -14,12 +12,15 @@ function getUrlFromInput(input: RequestInfo | URL): string {
return input.url; return input.url;
} }
export function retriedFetchFactory(logger: Logger) { export function retriedFetchFactory(
logger: Logger,
fetch: typeof globalThis.fetch = globalThis.fetch
) {
return async ( return async (
input: RequestInfo | URL, input: RequestInfo | URL,
init: RequestInitRetryParams<typeof fetch> = {} init: RequestInitRetryParams<typeof fetch> = {}
): Promise<Response> => { ): Promise<Response> => {
return fetchWithRetry(input, { return fetchRetryFactory.default(fetch)(input, {
retryOn: function (attempt, error, response) { retryOn: function (attempt, error, response) {
if (error !== null || !response || response.status >= 500) { if (error !== null || !response || response.status >= 500) {
logger.warn( logger.warn(