Skip to content

Commit efa1db7

Browse files
committed
chore: deduplicated cache stuff
1 parent 9d9ab43 commit efa1db7

10 files changed

Lines changed: 87 additions & 112 deletions

File tree

cmp/compiler/src/plugin/build-translator.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
type TranslationServer,
1717
} from "../translation-server";
1818
import { loadMetadata } from "../metadata/manager";
19-
import { LocalTranslationCache, type TranslationCache } from "../translators";
19+
import { createCache, type TranslationCache } from "../translators";
2020

2121
export interface BuildTranslationOptions {
2222
config: LingoConfig;
@@ -82,10 +82,7 @@ export async function processBuildTranslations(
8282
const totalEntries = Object.keys(metadata.entries).length;
8383
logger.info(`📊 Found ${totalEntries} translatable entries`);
8484

85-
const cache = new LocalTranslationCache(
86-
{ cacheDir: config.lingoDir },
87-
logger,
88-
);
85+
const cache = createCache(config);
8986

9087
// Handle cache-only mode
9188
if (buildMode === "cache-only") {
@@ -298,6 +295,7 @@ async function copyStaticFiles(
298295
const publicFilePath = path.join(publicOutputPath, `${locale}.json`);
299296

300297
try {
298+
// TODO (AleksandrSl 14/12/2025): Probably make it required?
301299
// Use getDictionary if available (for LocalTranslationCache), otherwise use get
302300
const dictionary = cache.getDictionary
303301
? await cache.getDictionary(locale)

cmp/compiler/src/translation-server/translation-server.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import { WebSocket, WebSocketServer } from "ws";
1818
import type { MetadataSchema, TranslationMiddlewareConfig } from "../types";
1919
import { getLogger } from "./logger";
2020
import {
21+
createCache,
2122
createTranslator,
22-
LocalTranslationCache,
2323
TranslationService,
2424
} from "../translators";
2525
import {
@@ -92,12 +92,9 @@ export class TranslationServer {
9292
this.logger.info(`🔧 Initializing translator...`);
9393

9494
const translator = createTranslator(this.config, this.logger);
95+
// TODO (AleksandrSl 14/12/2025): I think this should be taken from the translator directly
9596
const isPseudo = translator.constructor.name === "PseudoTranslator";
96-
97-
const cache = new LocalTranslationCache(
98-
{ cacheDir: this.config.lingoDir },
99-
this.logger,
100-
);
97+
const cache = createCache(this.config);
10198

10299
this.translationService = new TranslationService(
103100
translator,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Cache factory for creating cache instances from config
3+
*/
4+
5+
import type { LingoConfig, PathConfig } from "../types";
6+
import type { TranslationCache } from "./cache";
7+
import { LocalTranslationCache } from "./local-cache";
8+
import { logger } from "../utils/logger";
9+
import { getCacheDir } from "../utils/path-helpers";
10+
11+
/**
12+
* Create a cache instance based on the config
13+
*
14+
* @param config - LingoConfig with cacheType and lingoDir
15+
* @returns TranslationCache instance
16+
*
17+
* @example
18+
* ```typescript
19+
* const cache = createCache(config);
20+
* const translations = await cache.get("de");
21+
* ```
22+
*/
23+
export function createCache(
24+
config: Pick<LingoConfig, "cacheType"> & PathConfig,
25+
): TranslationCache {
26+
switch (config.cacheType) {
27+
case "local":
28+
return new LocalTranslationCache(
29+
{
30+
cacheDir: getCacheDir(config),
31+
},
32+
logger,
33+
);
34+
35+
default:
36+
// This should never happen due to TypeScript types, but provides a safeguard
37+
throw new Error(
38+
`Unknown cache type: ${config.cacheType}. Only "local" is currently supported.`,
39+
);
40+
}
41+
}

cmp/compiler/src/translators/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ export type { DictionarySchema } from "./api";
2626

2727
// Cache abstractions
2828
export type { TranslationCache, LocalCacheConfig } from "./cache";
29-
export { LocalTranslationCache } from "./local-cache";
29+
export { createCache } from "./cache-factory";

cmp/compiler/src/translators/pluralization/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
*/
1010
export type {
1111
PluralizationConfig,
12-
PartialPluralizationConfig,
13-
DefaultPluralizationConfig,
1412
PluralizationStats,
1513
PluralCandidate,
1614
ICUGenerationResult,

cmp/compiler/src/translators/pluralization/types.ts

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,13 @@
1-
/**
2-
* Types for pluralization system
3-
*/
1+
import type { LocaleCode } from "lingo.dev/spec";
42

5-
import type { LingoConfig } from "../../types";
6-
7-
/**
8-
* Plural candidate detected by pattern matching
9-
*/
103
export interface PluralCandidate {
11-
/**
12-
* Hash of the entry
13-
*/
144
hash: string;
15-
16-
/**
17-
* Original source text
18-
*/
195
sourceText: string;
206
}
217

22-
/**
23-
* Result of ICU format generation
24-
*/
258
export interface ICUGenerationResult {
26-
/**
27-
* Whether ICU format was generated successfully
28-
*/
299
success: boolean;
30-
31-
/**
32-
* Generated ICU format text (if successful)
33-
*/
3410
icuText?: string;
35-
36-
/**
37-
* Error message (if failed)
38-
*/
3911
error?: string;
4012

4113
/**
@@ -44,25 +16,8 @@ export interface ICUGenerationResult {
4416
reasoning?: string;
4517
}
4618

47-
type RequiredPluralizationConfigFields = "sourceLocale";
48-
49-
export type DefaultPluralizationConfig = Required<
50-
Omit<PluralizationConfig, RequiredPluralizationConfigFields>
51-
>;
52-
53-
export type PartialPluralizationConfig = Partial<
54-
Omit<PluralizationConfig, RequiredPluralizationConfigFields>
55-
> &
56-
Pick<PluralizationConfig, RequiredPluralizationConfigFields>;
57-
58-
/**
59-
* Configuration for pluralization system
60-
*/
6119
export type PluralizationConfig = {
62-
/**
63-
* Whether pluralization is enabled
64-
* @default true
65-
*/
20+
sourceLocale: LocaleCode;
6621
enabled: boolean;
6722

6823
/**
@@ -71,7 +26,7 @@ export type PluralizationConfig = {
7126
* @default "groq:llama3-8b-8192"
7227
*/
7328
model: string;
74-
} & Pick<LingoConfig, "sourceLocale">;
29+
};
7530

7631
/**
7732
* Statistics about pluralization processing

cmp/compiler/src/translators/translation-service.ts

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,17 @@
1111
import type { TranslationCache } from "./cache";
1212
import type { TranslatableEntry, Translator } from "./api";
1313
import type { MetadataSchema } from "../types";
14-
import { PluralizationService } from "./pluralization";
14+
import {
15+
type PluralizationConfig,
16+
PluralizationService,
17+
} from "./pluralization";
1518
import type { Logger } from "../utils/logger";
16-
import type { PartialPluralizationConfig } from "./pluralization";
1719
import type { LocaleCode } from "lingo.dev/spec";
1820

19-
/**
20-
* Configuration for translation service
21-
*/
2221
export interface TranslationServiceConfig {
2322
/**
2423
* Source locale (e.g., "en")
2524
*/
26-
// TODO (AleksandrSl 05/12/2025): Sort out these fields, they should most likely pick from the global config
2725
sourceLocale: LocaleCode;
2826

2927
/**
@@ -36,26 +34,17 @@ export interface TranslationServiceConfig {
3634
* Pluralization configuration
3735
* If provided, enables automatic pluralization of source messages
3836
*/
39-
pluralization?: Omit<PartialPluralizationConfig, "sourceLocale">;
37+
pluralization: Omit<PluralizationConfig, "sourceLocale">;
4038
}
4139

42-
/**
43-
* Result of a translation request
44-
*/
4540
export interface TranslationResult {
4641
/**
4742
* Successfully translated entries (hash -> translated text)
4843
*/
4944
translations: Record<string, string>;
5045

51-
/**
52-
* Errors that occurred during translation
53-
*/
5446
errors: TranslationError[];
5547

56-
/**
57-
* Statistics about the operation
58-
*/
5948
stats: {
6049
total: number;
6150
cached: number;
@@ -64,18 +53,12 @@ export interface TranslationResult {
6453
};
6554
}
6655

67-
/**
68-
* Translation error details
69-
*/
7056
export interface TranslationError {
7157
hash: string;
7258
sourceText: string;
7359
error: string;
7460
}
7561

76-
/**
77-
* Translation service orchestrator
78-
*/
7962
export class TranslationService {
8063
private useCache = true;
8164
private pluralizationService?: PluralizationService;
@@ -94,9 +77,7 @@ export class TranslationService {
9477
this.logger.info("Initializing pluralization service...");
9578
this.pluralizationService = new PluralizationService(
9679
{
97-
enabled: true,
98-
model:
99-
this.config.pluralization?.model || "groq:llama-3.1-8b-instant",
80+
...this.config.pluralization,
10081
sourceLocale: this.config.sourceLocale,
10182
},
10283
this.logger,
@@ -379,6 +360,7 @@ export class TranslationService {
379360
/**
380361
* Pick only requested translations from the full set
381362
*/
363+
// TODO (AleksandrSl 14/12/2025): SHould I use this in the build somehow?
382364
private pickTranslations(
383365
allTranslations: Record<string, string>,
384366
requestedHashes: string[],

cmp/compiler/src/types.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import type { LocaleCode } from "lingo.dev/spec";
6+
import type { PluralizationConfig } from "./translators/pluralization";
67

78
/**
89
* Cookie configuration for locale persistence
@@ -32,7 +33,7 @@ export type LocalePersistenceConfig = { type: "cookie"; cookieName?: string };
3233
*/
3334
export type LingoConfigRequiredFields = "sourceLocale" | "targetLocales";
3435

35-
export type LingoInternalFields = "environment";
36+
export type LingoInternalFields = "environment" | "cacheType";
3637

3738
/**
3839
* Configuration for the Lingo compiler
@@ -47,24 +48,6 @@ export type PartialLingoConfig = Pick<LingoConfig, LingoConfigRequiredFields> &
4748
}
4849
>;
4950

50-
/**
51-
* Pluralization configuration
52-
*/
53-
export interface PluralizationConfig {
54-
/**
55-
* Whether pluralization is enabled
56-
* @default true
57-
*/
58-
enabled: boolean;
59-
60-
/**
61-
* LLM provider for pluralization detection
62-
* Format: "provider:model" (e.g., "groq:llama3-8b-8192")
63-
* @default "groq:llama3-8b-8192"
64-
*/
65-
model?: string;
66-
}
67-
6851
export type LingoEnvironment = "development" | "production";
6952

7053
/**
@@ -86,9 +69,20 @@ export type LingoConfig = {
8669
* Determines metadata file naming and translator behavior
8770
*
8871
* @default "production"
72+
* @internal
8973
*/
9074
environment: LingoEnvironment;
9175

76+
/**
77+
* Cache implementation type
78+
* - "local": Local file system cache (default)
79+
* - "remote": Remote cache (future)
80+
*
81+
* @default "local"
82+
* @internal Since we do not support more types, there is no need to make it public, but it allows keeping the config in the single place
83+
*/
84+
cacheType: "local";
85+
9286
/**
9387
* The locale to translate from.
9488
*
@@ -140,10 +134,8 @@ export type LingoConfig = {
140134
/**
141135
* Pluralization configuration
142136
* Automatically detects and converts messages to ICU MessageFormat
143-
*
144-
* @default { enabled: true, model: "groq:llama3-8b-8192" }
145137
*/
146-
pluralization: PluralizationConfig;
138+
pluralization: Omit<PluralizationConfig, "sourceLocale">;
147139

148140
/**
149141
* Development-specific settings
@@ -227,6 +219,7 @@ export type TranslationMiddlewareConfig = Pick<
227219
| "dev"
228220
| "pluralization"
229221
| "environment"
222+
| "cacheType"
230223
>;
231224

232225
/**

0 commit comments

Comments
 (0)