Skip to content

Commit

Permalink
Explicitly specify locales in the config
Browse files Browse the repository at this point in the history
  • Loading branch information
LorisSigrist committed Oct 19, 2023
1 parent 2ab31cb commit b925c22
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 100 deletions.
2 changes: 0 additions & 2 deletions src/core/HMR.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
* "t18s:addDictionary": { locale: string, domain: string }
* "t18s:removeDictionary": { locale: string, domain: string }
* "t18s:reloadDictionary": { locale: string, domain: string }
* "t18s:addLocale": { locale: string }
* "t18s:removeLocale": { locale: string }
* }} HMREventMap
*/

Expand Down
18 changes: 7 additions & 11 deletions src/core/codegen/dts.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { MessageCatalogue } from "../MessageCatalogue.js";
* @param {MessageCatalogue} Catalogue
*/
export function generateDTS(config, Catalogue) {
const locales = Catalogue.getLocales();
const locales = config.locales;
const messagesTypeMap = generateMessagesTypeMap(config, Catalogue);

const dts = new DTSBuilder();
Expand All @@ -29,7 +29,12 @@ export function generateDTS(config, Catalogue) {
s.setDescription("The known locales"),
);

module.addStatement(`export const locales : Readable<Locales>;`, (s) =>

module.addStatement(`export const fallbackLocale: Locale | undefined;`, (s) =>
s.setDescription("The fallback locale that's currently in use.")
);

module.addStatement(`export const locales : Locales;`, (s) =>
s.setDescription(
"A store containing the available locales.\n\nThis store will only ever change during development, it is constant in production.",
),
Expand Down Expand Up @@ -106,15 +111,6 @@ export function generateDTS(config, Catalogue) {
].join("\n"),
),
);

// T Component
module.addImport("import type { SvelteComponentTyped } from 'svelte';");
module.addStatement(
"export class T<Key extends keyof Messages> extends SvelteComponentTyped<Messages[Key] extends undefined ? { key: Key } : { key: Key, values: Messages[Key] }, {}, {}> { };",
(s) => {
s.setDescription("The t18s translation component.");
},
);
});

return dts.build();
Expand Down
17 changes: 0 additions & 17 deletions src/core/codegen/locale.js

This file was deleted.

33 changes: 7 additions & 26 deletions src/core/codegen/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ import { MessageCatalogue } from "../MessageCatalogue.js";
* @returns {string}
*/
export function generateMainModuleCode(config, Catalogue) {
const locales = [...Catalogue.getLocales()];

const code = `
import { writable, get } from 'svelte/store';
import { locales } from 't18s-internal:locales'
import config from 't18s-internal:config';
export { locales };
export const locales = config.locales;
//Keeps track of the current catalogue of dictionaries. Double-Keyed by locale and domain
const Catalogue = {}
Expand All @@ -28,7 +24,7 @@ export function generateMainModuleCode(config, Catalogue) {
//We need to explicitly list each import here to make sure none of
//the dictionaries are accidentally removed by tree-shaking
const loaders = {
${locales.map((loc) => {
${config.locales.map((loc) => {
const domains = Catalogue.getDomains(loc);
let code = `"${loc}" : {\n`;
Expand All @@ -43,7 +39,7 @@ export function generateMainModuleCode(config, Catalogue) {
//List of domains that should be loaded eagerly when a new locale is loaded
const eagerlyLoadedDomains = new Set(["${config.defaultDomain}"]);
let fallbackLocale = undefined;
export let fallbackLocale = undefined;
let loadingDelay = 200;
export async function init(options) {
Expand Down Expand Up @@ -96,7 +92,7 @@ export function generateMainModuleCode(config, Catalogue) {
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
export function isLocale(maybeLocale) {
return get(locales).includes(maybeLocale);
return locales.includes(maybeLocale);
}
async function loadLocale(newLocale) {
Expand All @@ -116,7 +112,7 @@ export function generateMainModuleCode(config, Catalogue) {
function parseKey(key) {
const [first, second] = key.split(":");
if(!first) throw new Error("[t18s] Invalid key: " + key);
if(!second) return {domain: "${config.defaultDomain}", key: first};
if(!second) return {domain: config.defaultDomain, key: first};
else return {domain: first, key: second};
}
Expand Down Expand Up @@ -211,23 +207,8 @@ export function generateMainModuleCode(config, Catalogue) {
t.set(getMessage); //update the store
});
import.meta.hot.on("t18s:addLocale", async (data) => {
locales.update((locales) => [...locales, data.locale]);
});
import.meta.hot.on("t18s:removeLocale", async (data) => {
locales.update((locales) => locales.filter((l) => l !== data.locale));
console.log("REMOVING LOCALE", data.locale, get(locale), get(locales));
//Switch locale if the current locale was removed
if(data.locale === get(locale)) {
locale.set(get(locales)[0]);
t.set(getMessage); //rerender the component
}
});
}
`;

return code;
}
59 changes: 17 additions & 42 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import { cleanUrl } from "./utils/id.js";
import { existsSync } from "node:fs";
import { createHMRDispatcher } from "./HMR.js";
import { generateConfigModule } from "./codegen/config.js";
import { generateLocaleModule } from "./codegen/locale.js";
import { $ } from "kleur/colors";

/**
* TypeSafe translations for Svelte & SvelteKit.
Expand Down Expand Up @@ -55,15 +53,6 @@ export function t18sCore(pluginConfig) {

/** Keeps track of the messages that exist & where to find them */
const Catalogue = new MessageCatalogue();

Catalogue.addEventListener("locale_removed", e => {
dispatch("t18s:removeLocale", { locale: e.detail.locale });
})

Catalogue.addEventListener("locale_added", e => {
dispatch("t18s:addLocale", { locale: e.detail.locale });
});

Catalogue.addEventListener(
"messages_changed",
async () => await regenerateDTS()
Expand Down Expand Up @@ -170,19 +159,28 @@ export function t18sCore(pluginConfig) {
}

/**
* Reads the initial translation files and generates the initial code.
* @param { import("./types.js").ResolvedPluginConfig} config
* Safely list the files that are in the given directory. If the reading fails, an empty array is returned & a warning is logged.
* @example ["file1.txt", "file2.txt"]
*
* @param {string} dir
* @returns {Promise<string[]>}
*/
async function loadInitialLocales(config) {
const readdirResult = await buffer(readdir(config.translationsDir));

const files = new ResultMatcher(readdirResult)
async function getFilesInDir(dir) {
const readdirResult = await buffer(readdir(dir));
return new ResultMatcher(readdirResult)
.catchAll((e) => {
logger.warn("Could not read translation directory\n" + e);
logger.warn("Could not read directory " + dir);
return [];
})
.run();
}

/**
* Reads the initial translation files and generates the initial code.
* @param { import("./types.js").ResolvedPluginConfig} config
*/
async function loadInitialLocales(config) {
const files = await getFilesInDir(config.translationsDir);
const paths = files.map((file) => resolve(config.translationsDir, file));

/** @param {string} path */
Expand Down Expand Up @@ -238,6 +236,7 @@ export function t18sCore(pluginConfig) {
),
verbose: pluginConfig.verbose,
defaultDomain: pluginConfig.defaultDomain,
locales: pluginConfig.locales,
};

logger = new Logger(resolvedConfig, config.verbose);
Expand All @@ -254,7 +253,6 @@ export function t18sCore(pluginConfig) {
resolveMainModuleId,
resolveRuntimeId,
resolveConfigModuleId,
resolveLocaleModuleId,
];

for (const resolver of resolvers) {
Expand All @@ -273,7 +271,6 @@ export function t18sCore(pluginConfig) {
loadDictionaryModule,
loadRuntimeModule,
loadConfigModule,
loadLocaleModule
];

//Attempt to load the module from all loaders
Expand Down Expand Up @@ -401,18 +398,6 @@ async function loadConfigModule(resolved_id, config, Catalogue) {
return generateConfigModule(config);
}

/**
* @param {string} resolved_id
* @param {import("./types.js").ResolvedPluginConfig} config
*
* @param {MessageCatalogue} Catalogue
* @returns {Promise<string | null>}
*/
async function loadLocaleModule(resolved_id, config, Catalogue) {
if (resolved_id !== "\0t18s-internal:locales") return null;
return generateLocaleModule(Catalogue);
}

/**
* If the unresolved_id is for the t18s-runtime, this function will resolve it.
* @param {string} unresolved_id
Expand Down Expand Up @@ -459,13 +444,3 @@ function resolveConfigModuleId(unresolved_id) {
if (unresolved_id !== "t18s-internal:config") return null;
return "\0t18s-internal:config";
}

/**
* If the unresolved_id is for the t18s locales, this function will resolve it.
* @param {string} unresolved_id
* @returns {string | null}
*/
function resolveLocaleModuleId(unresolved_id) {
if (unresolved_id !== "t18s-internal:locales") return null;
return "\0t18s-internal:locales";
}
1 change: 1 addition & 0 deletions src/core/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ export interface ResolvedPluginConfig {
translationsDir: string;
verbose: boolean;
defaultDomain: string;
locales: [string, ...string[]];
}
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { t18sCore } from "./core/index.js";
import { t18sToolkit } from "./toolkit/index.js";

/** @type {import("./types.js").t18sFullConfig} */
/** @type {import("./types.js").t18sDefaultConfig} */
const DEFAULT_CONFIG = {
translationsDir: "src/translations",
dts: "src/$t18s.d.ts",
Expand All @@ -14,7 +14,7 @@ const DEFAULT_CONFIG = {
* @param {import("./types.js").t18sUserConfig} userConfig
* @returns {import("vite").Plugin[]}
*/
export function t18s(userConfig = {}) {
export function t18s(userConfig) {
/** @type {import("./types.js").t18sFullConfig} */
const pluginConfig = { ...DEFAULT_CONFIG, ...userConfig };

Expand Down
16 changes: 16 additions & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ export type t18sUserConfig = {
* @default "messages"
*/
defaultDomain?: string;

/**
* The locales that should be made available.
*/
locales: [string, ...string[]],
};

export type t18sDefaultConfig = FlipOptional<t18sUserConfig>;
export type t18sFullConfig = Required<t18sUserConfig>;


type OptionalKeys<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? K : never
}[keyof T];

type FlipOptional<T> = (Required<Pick<T, OptionalKeys<T>>> &
Partial<Omit<T, OptionalKeys<T>>>) extends infer O
? { [K in keyof O]: O[K] }
: never;

0 comments on commit b925c22

Please sign in to comment.