From e553cf1f10c777a5b13c6b2c7665f6e591a135be Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Fri, 3 Apr 2026 11:03:48 +0300 Subject: [PATCH] feat(appliedFontsStore): create separate getEffectiveConcurrency function with proper tests --- .../appliedFontsStore.svelte.ts | 3 +- .../getEffectiveConcurrency.test.ts | 41 +++++++++++++++++++ .../getEffectiveConcurrency.ts | 26 ++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.test.ts create mode 100644 src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.ts diff --git a/src/entities/Font/model/store/appliedFontsStore/appliedFontsStore.svelte.ts b/src/entities/Font/model/store/appliedFontsStore/appliedFontsStore.svelte.ts index 17e58cf..1758d36 100644 --- a/src/entities/Font/model/store/appliedFontsStore/appliedFontsStore.svelte.ts +++ b/src/entities/Font/model/store/appliedFontsStore/appliedFontsStore.svelte.ts @@ -1,4 +1,5 @@ import { SvelteMap } from 'svelte/reactivity'; +import { getEffectiveConcurrency } from './utils/getEffectiveConcurrency/getEffectiveConcurrency'; /** Loading state of a font. Failed loads may be retried up to MAX_RETRIES. */ export type FontStatus = 'loading' | 'loaded' | 'error'; @@ -200,7 +201,7 @@ export class AppliedFontsManager { } // Phase 1: Concurrent fetching (I/O bound, non-blocking) - const concurrency = this.#getEffectiveConcurrency(); + const concurrency = getEffectiveConcurrency(); const buffers = new Map(); for (let i = 0; i < entries.length; i += concurrency) { diff --git a/src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.test.ts b/src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.test.ts new file mode 100644 index 0000000..3bc23b4 --- /dev/null +++ b/src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.test.ts @@ -0,0 +1,41 @@ +import { + beforeEach, + describe, + expect, + it, +} from 'vitest'; +import { + Concurrency, + getEffectiveConcurrency, +} from './getEffectiveConcurrency'; + +describe('getEffectiveConcurrency', () => { + beforeEach(() => { + const nav = navigator as any; + nav.connection = null; + }); + + it('should return MAX when connection is not available', () => { + const nav = navigator as any; + nav.connection = null; + expect(getEffectiveConcurrency()).toBe(Concurrency.MAX); + }); + + it('should return MIN for slow-2g or 2g connection', () => { + const nav = navigator as any; + nav.connection = { effectiveType: 'slow-2g' }; + expect(getEffectiveConcurrency()).toBe(Concurrency.MIN); + }); + + it('should return AVERAGE for 3g connection', () => { + const nav = navigator as any; + nav.connection = { effectiveType: '3g' }; + expect(getEffectiveConcurrency()).toBe(Concurrency.AVERAGE); + }); + + it('should return MAX for other connection types', () => { + const nav = navigator as any; + nav.connection = { effectiveType: '4g' }; + expect(getEffectiveConcurrency()).toBe(Concurrency.MAX); + }); +}); diff --git a/src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.ts b/src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.ts new file mode 100644 index 0000000..f98bcbb --- /dev/null +++ b/src/entities/Font/model/store/appliedFontsStore/utils/getEffectiveConcurrency/getEffectiveConcurrency.ts @@ -0,0 +1,26 @@ +export enum Concurrency { + MIN = 1, + AVERAGE = 2, + MAX = 4, +} + +/** + * Calculates the amount of fonts for concurrent download based on the user internet connection + */ +export function getEffectiveConcurrency(): number { + const nav = navigator as any; + const connection = nav.connection; + if (!connection) { + return Concurrency.MAX; + } + + switch (connection.effectiveType) { + case 'slow-2g': + case '2g': + return Concurrency.MIN; + case '3g': + return Concurrency.AVERAGE; + default: + return Concurrency.MAX; + } +}