Skip to content

Commit

Permalink
refactor(react-t): use new createTranslationsFactory API
Browse files Browse the repository at this point in the history
  • Loading branch information
macarie committed Dec 27, 2023
1 parent c369292 commit e2ae464
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 74 deletions.
105 changes: 48 additions & 57 deletions packages/react-t/source/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { negotiateLanguages } from "@fluent/langneg";
import {
NoLocaleSet,
NoTranslationsSet,
Expand All @@ -12,74 +11,66 @@ const $locale = atom<string | undefined>(undefined);
const defaultStore = getDefaultStore();

export const createTranslations = createTranslationsFactory({
getTranslationsHook: {
factory: ({ cache, lazyLoaders }) => {
const $translations = atom(async (get) => {
const locale = get($locale);
hasSignalLikeInterface: false,
locale: {
hook: {
factory: () => () => useAtomValue($locale)!,
name: "useLocale",
},
setter: (locale) => {
defaultStore.set($locale, locale);
},
},
resources: {
cache: new Map(),
loaders: new Map(),
},
translations: {
hook: {
factory: ({ cache, loaders }) => {
const $translations = atom(async (get) => {
const locale = get($locale);

if (locale === undefined) {
throw new NoLocaleSet();
}
if (locale === undefined) {
throw new NoLocaleSet();
}

let translations = cache.get(locale);
let translations = cache.get(locale);

if (translations !== undefined) {
return translations;
}
if (translations !== undefined) {
return translations;
}

const loader = lazyLoaders.get(locale);
const loader = loaders.get(locale);

if (loader === undefined) {
throw new NoTranslationsSet({
availableLocales: Array.from(lazyLoaders.keys()),
desiredLocale: locale,
});
}
if (loader === undefined) {
throw new NoTranslationsSet({
availableLocales: Array.from(loaders.keys()),
desiredLocale: locale,
});
}

translations = await loader();
translations = await loader();

cache.set(locale, translations);
cache.set(locale, translations);

return translations;
});
return translations;
});

return (prefix) => {
const translations = useAtomValue($translations);
return (prefix) => {
const translations = useAtomValue($translations);

// eslint-disable-next-line ts/no-unsafe-return
return useMemo(
// eslint-disable-next-line ts/no-unsafe-return
() => delve(translations, prefix),
[prefix, translations],
);
};
return useMemo(
// eslint-disable-next-line ts/no-unsafe-return
() => delve(translations, prefix),
[prefix, translations],
);
};
},
name: "useTranslations",
},
name: "useTranslations",
},
locale: {
getter: {
factory: () => () => useAtomValue($locale)!,
name: "useLocale",
},
negotiator: (availableLocales, fallback) =>
negotiateLanguages(navigator.languages, availableLocales, {
defaultLocale: fallback,
strategy: "lookup",
})[0] ?? fallback,
setter: (locale) => {
defaultStore.set($locale, locale);
},
},
resources: {
cache: new Map(),
lazyLoaders: new Map(),
},
});

export {
NoLocaleSet,
NoTranslationsSet,
UnknownDefaultLocale,
UnknownDefaultLocaleStrategy,
lazyTranslations,
} from "@wluwd/t";
export { NoLocaleSet, NoTranslationsSet, lazyTranslations } from "@wluwd/t";
27 changes: 10 additions & 17 deletions packages/react-t/tests/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { renderHook, waitFor } from "@testing-library/react";
import { t as translator } from "@wluwd/t";
import {
NoLocaleSet,
NoTranslationsSet,
Expand Down Expand Up @@ -35,7 +36,10 @@ class ErrorBoundary extends Component<{

describe("throws", () => {
it("`NoLocaleSet` when trying to access translations without a specified locale", async () => {
const { useLocale, useTranslations } = createTranslations(translations);
const { useLocale, useTranslations } = createTranslations(translations, {
localeFrom: [],
translator,
});

const { result: locale } = renderHook(() => useLocale());
expect(locale.current).toBe(undefined);
Expand All @@ -54,8 +58,10 @@ describe("throws", () => {
});

it("`NoTranslationsSet` when trying to load translations that have no loader", async () => {
const { setLocale, useLocale, useTranslations } =
createTranslations(translations);
const { setLocale, useLocale, useTranslations } = createTranslations(
translations,
{ localeFrom: [], translator },
);

const { result: locale } = renderHook(() => useLocale());
expect(locale.current).toBe(undefined);
Expand All @@ -80,7 +86,7 @@ describe("throws", () => {
it("creates a working `createTranslations`", async () => {
const { setLocale, t, useLocale, useTranslations } = createTranslations(
translations,
"en-GB",
{ localeFrom: ["en-GB"], translator },
);

const { rerender: rerenderLocale, result: locale } = renderHook(() =>
Expand Down Expand Up @@ -115,16 +121,3 @@ it("creates a working `createTranslations`", async () => {
expect(t(translation.current.string)).toBe(enGB.default.some.deep.string),
);
});

describe("`defaultLocale` strategies", () => {
it("`auto` picks up the correct locale", async () => {
// @info statically set by happy-dom, should never fail
expect(navigator.languages).toEqual(["en-US", "en"]);

const { useLocale } = createTranslations(translations, ["auto", "en-GB"]);

const { result: locale } = renderHook(() => useLocale());

expect(locale.current).toBe("en-US");
});
});

0 comments on commit e2ae464

Please sign in to comment.