summaryrefslogtreecommitdiff
path: root/src/stores/i18n.ts
blob: 740d0b4a36e85656fdb16c5da8439747a54fb230 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { readable } from 'svelte/store';
import I18N from '@amp/web-apps-localization';
import { getContext } from 'svelte';
import type { Readable } from 'svelte/store';
import type { Locale, ILocaleJSON } from '@amp/web-apps-localization';
import type { Logger, LoggerFactory } from '@amp/web-apps-logger';
import { isEnabled } from '@amp/web-apps-featurekit';

export type { Locale } from '@amp/web-apps-localization';

import { __FF_SHOW_LOC_KEYS } from '~/utils/features/consts';

const CONTEXT_NAME = 'i18n';

export async function setup(
    context: Map<string, unknown>,
    loggerFactory: LoggerFactory,
    locale: Locale,
): Promise<I18N> {
    const log = loggerFactory.loggerFor('i18n');

    let alwaysShowScreamers = false;
    if (isEnabled(__FF_SHOW_LOC_KEYS)) {
        alwaysShowScreamers = true;
    }

    const translations = await getTranslations(log, locale);
    const i18n = new I18N(log, locale, translations, alwaysShowScreamers);
    const store = readable(i18n);

    context.set(CONTEXT_NAME, store);

    return i18n;
}

/**
 * Gets the current i18n store from the Svelte context.
 *
 * @return i18n The i18n store
 */
export function getI18n(): Readable<I18N> {
    const i18n = getContext(CONTEXT_NAME) as Readable<I18N> | undefined;

    if (!i18n) {
        throw new Error('getI18n called before setup');
    }

    return i18n;
}

async function getTranslations(
    log: Logger,
    locale: Locale,
): Promise<ILocaleJSON> {
    try {
        // TODO: Shoebox logic here
        const translations = await importLocale(locale);
        return translations.default;
    } catch (err) {
        log.error('failed to load:', err);
        throw new Error('i18n failed to load');
    }
}

interface IDynamicImportJSON {
    default: ILocaleJSON;
}

//TODO: rdar://73157638 (Determine if we can use ES modules based on browser matrix)
// Possibly switch this to fetch instead of dynamic imports?
function importLocale(locale: Locale): Promise<IDynamicImportJSON> {
    return import(`../../tmp/locales/${locale}/translations.json`);
}