feat(offline): background-preload dictionaries for offline readiness
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s
An installed PWA (standalone web + confirmed email) warms the dictionaries for the player's enabled variants while online — on lobby entry and on a variant-preference change — using the per-variant version the profile now advertises, so a later switch to offline mode already has the data. - dict/preload.ts: pure preloadDicts (retry + linear backoff, honours the session dictionary miss-breaker); node-tested. - dict/preloadrun.ts: lazy browser orchestration (real getDawg), imported dynamically so the loader and move generator stay out of the main bundle. - offline.svelte.ts: kickDictPreload, gated by the pure, tested offlinePreloadEligible, plus the reactive first-lobby preload warning. - Header shows a poor-connection notice in the ad-banner slot on a first-lobby preload failure (offline.preloadWarning, en/ru). - App-entry bundle budget 112->113 for the irreducible main-side wiring (documented in bundle-size.mjs); the heavy parts remain lazy chunks. Docs: ARCHITECTURE offline-mode + dict-preload mechanism.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { loadOfflinePref, saveOfflinePref, offlineReady, missingDicts } from './offline';
|
||||
import { loadOfflinePref, saveOfflinePref, offlineReady, missingDicts, offlinePreloadEligible } from './offline';
|
||||
import type { Variant } from './model';
|
||||
|
||||
// A minimal in-memory localStorage for the persistence tests (node has none).
|
||||
@@ -35,4 +35,14 @@ describe('offline mode helpers', () => {
|
||||
const has = (v: Variant): boolean => v === 'scrabble_en';
|
||||
expect(missingDicts(['scrabble_en', 'scrabble_ru', 'erudit_ru'], has)).toEqual(['scrabble_ru', 'erudit_ru']);
|
||||
});
|
||||
|
||||
it('offlinePreloadEligible requires a standalone PWA with email, online, outside mini-apps', () => {
|
||||
const base = { hasEmail: true, standalone: true, inTelegram: false, inVK: false, online: true };
|
||||
expect(offlinePreloadEligible(base)).toBe(true);
|
||||
expect(offlinePreloadEligible({ ...base, hasEmail: false })).toBe(false);
|
||||
expect(offlinePreloadEligible({ ...base, standalone: false })).toBe(false);
|
||||
expect(offlinePreloadEligible({ ...base, inTelegram: true })).toBe(false);
|
||||
expect(offlinePreloadEligible({ ...base, inVK: true })).toBe(false);
|
||||
expect(offlinePreloadEligible({ ...base, online: false })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user