chore: fixes for 1st review

This commit is contained in:
Luma 2021-08-24 11:59:40 +09:00 committed by Christian Kaisermann
parent bf4189a862
commit 8235f1e078
10 changed files with 43 additions and 36 deletions

View File

@ -38,7 +38,11 @@ export const defaultFormats: Formats = {
}, },
}; };
export const defaultOptions: ConfigureOptions = { export const defaultOptions: Omit<
ConfigureOptions,
'fallbackLocale' | 'initialLocale'
> &
Record<'fallbackLocale' | 'initialLocale', null> = {
fallbackLocale: null, fallbackLocale: null,
initialLocale: null, initialLocale: null,
loadingDelay: 200, loadingDelay: 200,

View File

@ -1,3 +1,4 @@
import type { Formats } from 'intl-messageformat';
import IntlMessageFormat from 'intl-messageformat'; import IntlMessageFormat from 'intl-messageformat';
import type { import type {
@ -34,8 +35,8 @@ const getIntlFormatterOptions = (
): any => { ): any => {
const { formats } = getOptions(); const { formats } = getOptions();
if (type in formats && name in formats[type]) { if (type in formats && name in (formats as Formats)[type]) {
return formats[type][name]; return (formats as Formats)[type][name];
} }
throw new Error(`[svelte-i18n] Unknown "${name}" ${type} format.`); throw new Error(`[svelte-i18n] Unknown "${name}" ${type} format.`);
@ -105,7 +106,7 @@ export const getTimeFormatter: MemoizedDateTimeFormatterFactoryOptional = ({
} = {}) => createTimeFormatter({ locale, ...args }); } = {}) => createTimeFormatter({ locale, ...args });
export const getMessageFormatter = monadicMemoize( export const getMessageFormatter = monadicMemoize(
(message: string, locale: string = getCurrentLocale()) => (message: string, locale: string = getCurrentLocale()!) =>
new IntlMessageFormat(message, locale, getOptions().formats, { new IntlMessageFormat(message, locale, getOptions().formats, {
ignoreTag: getOptions().ignoreTag, ignoreTag: getOptions().ignoreTag,
}), }),

View File

@ -62,13 +62,13 @@ function loadLocaleQueue(locale: string, localeQueue: MessagesLoader[]) {
const activeFlushes: { [key: string]: Promise<void> } = {}; const activeFlushes: { [key: string]: Promise<void> } = {};
export async function flush(locale: string): Promise<void> { export function flush(locale: string): Promise<void> {
if (!hasLocaleQueue(locale)) { if (!hasLocaleQueue(locale)) {
if (locale in activeFlushes) { if (locale in activeFlushes) {
return activeFlushes[locale]; return activeFlushes[locale];
} }
return; return Promise.resolve();
} }
// get queue of XX-YY and XX locales // get queue of XX-YY and XX locales

View File

@ -35,8 +35,8 @@ export function getMessageFromDictionary(locale: string, id: string) {
} }
export function getClosestAvailableLocale( export function getClosestAvailableLocale(
refLocale: string, refLocale: string | null | undefined,
): string | null | undefined { ): string | undefined {
if (refLocale == null) return undefined; if (refLocale == null) return undefined;
const relatedLocales = getPossibleLocales(refLocale); const relatedLocales = getPossibleLocales(refLocale);

View File

@ -47,7 +47,7 @@ const formatMessage: MessageFormatter = (id, options = {}) => {
`[svelte-i18n] The message "${id}" was not found in "${getPossibleLocales( `[svelte-i18n] The message "${id}" was not found in "${getPossibleLocales(
locale, locale,
).join('", "')}".${ ).join('", "')}".${
hasLocaleQueue(getCurrentLocale()) hasLocaleQueue(getCurrentLocale()!)
? `\n\nNote: there are at least one loader still registered to this locale that wasn't executed.` ? `\n\nNote: there are at least one loader still registered to this locale that wasn't executed.`
: '' : ''
}`, }`,

View File

@ -5,8 +5,8 @@ import { getOptions } from '../configs';
import { getClosestAvailableLocale } from './dictionary'; import { getClosestAvailableLocale } from './dictionary';
import { $isLoading } from './loading'; import { $isLoading } from './loading';
let current: string; let current: string | null | undefined;
const $locale = writable<string | null | undefined>(null); const internalLocale = writable<string | null | undefined>(null);
function getSubLocales(refLocale: string) { function getSubLocales(refLocale: string) {
return refLocale return refLocale
@ -32,18 +32,21 @@ export function getCurrentLocale() {
return current; return current;
} }
$locale.subscribe((newLocale: string) => { internalLocale.subscribe((newLocale: string | null | undefined) => {
current = newLocale; current = newLocale;
if (typeof window !== 'undefined' && newLocale !== null) { if (typeof window !== 'undefined' && newLocale != null) {
document.documentElement.setAttribute('lang', newLocale); document.documentElement.setAttribute('lang', newLocale);
} }
}); });
const localeSet = $locale.set; const set = (newLocale: string | null | undefined): void | Promise<void> => {
if (
$locale.set = (newLocale: string): void | Promise<void> => { ((getClosestAvailableLocale as unknown) as (
if (getClosestAvailableLocale(newLocale) && hasLocaleQueue(newLocale)) { refLocale: string | null | undefined,
) => refLocale is string)(newLocale) &&
hasLocaleQueue(newLocale)
) {
const { loadingDelay } = getOptions(); const { loadingDelay } = getOptions();
let loadingTimer: number; let loadingTimer: number;
@ -65,7 +68,7 @@ $locale.set = (newLocale: string): void | Promise<void> => {
return flush(newLocale) return flush(newLocale)
.then(() => { .then(() => {
localeSet(newLocale); internalLocale.set(newLocale);
}) })
.finally(() => { .finally(() => {
clearTimeout(loadingTimer); clearTimeout(loadingTimer);
@ -73,12 +76,12 @@ $locale.set = (newLocale: string): void | Promise<void> => {
}); });
} }
return localeSet(newLocale); return internalLocale.set(newLocale);
}; };
// istanbul ignore next const $locale = {
$locale.update = ( ...internalLocale,
fn: (value: string | null | undefined) => string | null | undefined, set,
) => localeSet(fn(current)); };
export { $locale }; export { $locale };

View File

@ -1,4 +1,4 @@
import type { FormatXMLElementFn, Formats } from 'intl-messageformat'; import type { Formats, FormatXMLElementFn } from 'intl-messageformat';
export interface LocaleDictionary { export interface LocaleDictionary {
[key: string]: [key: string]:
@ -27,7 +27,7 @@ export type InterpolationValues =
export interface MessageObject { export interface MessageObject {
id?: string; id?: string;
locale?: string; locale?: string | null;
format?: string; format?: string;
default?: string; default?: string;
values?: InterpolationValues; values?: InterpolationValues;
@ -53,11 +53,11 @@ export type NumberFormatter = (
options?: IntlFormatterOptions<Intl.NumberFormatOptions>, options?: IntlFormatterOptions<Intl.NumberFormatOptions>,
) => string; ) => string;
export type JSONGetter = (id: string, locale?: string) => any; export type JSONGetter = (id: string, locale?: string | null) => any;
type IntlFormatterOptions<T> = T & { type IntlFormatterOptions<T> = T & {
format?: string; format?: string;
locale?: string; locale?: string | null;
}; };
export interface MemoizedIntlFormatter<T, U> { export interface MemoizedIntlFormatter<T, U> {
@ -73,14 +73,13 @@ export interface MessagesLoader {
} }
export interface ConfigureOptions { export interface ConfigureOptions {
fallbackLocale: string | null | undefined; fallbackLocale: string;
formats: Formats; formats: Partial<Formats>;
initialLocale: string | null; initialLocale: string;
loadingDelay: number; loadingDelay: number;
warnOnMissingMessages: boolean; warnOnMissingMessages: boolean;
ignoreTag: boolean; ignoreTag: boolean;
} }
export type ConfigureOptionsInit = Pick<ConfigureOptions, 'fallbackLocale'> & export type ConfigureOptionsInit = Pick<ConfigureOptions, 'fallbackLocale'> &
Partial<Record<'formats', Partial<ConfigureOptions['formats']>>> & Partial<Omit<ConfigureOptions, 'fallbackLocale'>>;
Partial<Omit<ConfigureOptions, 'fallbackLocale' | 'formats'>>;

View File

@ -10,7 +10,7 @@ import {
import { $locale } from '../../src/runtime/stores/locale'; import { $locale } from '../../src/runtime/stores/locale';
beforeEach(() => { beforeEach(() => {
init(defaultOptions); init(defaultOptions as any);
}); });
test('inits the fallback locale', () => { test('inits the fallback locale', () => {

View File

@ -10,7 +10,7 @@ import {
const formatsJson = require('../../fixtures/formats.json'); const formatsJson = require('../../fixtures/formats.json');
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: undefined }); init({ fallbackLocale: undefined as any });
}); });
describe('number formatter', () => { describe('number formatter', () => {

View File

@ -11,7 +11,7 @@ import { register, isLoading } from '../../../src/runtime';
import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue'; import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue';
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: undefined }); init({ fallbackLocale: undefined as any });
$locale.set(undefined); $locale.set(undefined);
}); });
@ -90,7 +90,7 @@ test('if no initial locale is set, set the locale to the fallback', () => {
test('if no initial locale was found, set to the fallback locale', () => { test('if no initial locale was found, set to the fallback locale', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
initialLocale: null, initialLocale: null as any,
}); });
expect(get($locale)).toBe('en'); expect(get($locale)).toBe('en');
expect(getOptions().fallbackLocale).toBe('en'); expect(getOptions().fallbackLocale).toBe('en');