Skip to content

Commit b2b9bf5

Browse files
committed
feat: update docs
1 parent af2bfbd commit b2b9bf5

File tree

2 files changed

+103
-211
lines changed

2 files changed

+103
-211
lines changed

cmp/README.md

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,90 @@
11
# Lingo.dev compiler
22

3-
### Development
3+
## Getting started
4+
5+
Install the package - `pnpm install @lingo.dev/compile`
6+
7+
### Vite
8+
9+
- Configure the plugin in your vite config.
10+
11+
```ts
12+
import { defineConfig } from "vite";
13+
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";
14+
15+
export default defineConfig({
16+
plugins: [
17+
lingoCompilerPlugin({
18+
sourceRoot: "src",
19+
sourceLocale: "en",
20+
targetLocales: ["es", "de", "fr"],
21+
models: "lingo.dev",
22+
dev: {
23+
usePseudotranslator: true,
24+
},
25+
}), // ...other plugins
26+
],
27+
});
28+
```
29+
30+
- Wrap your app with `LingoProvider`. It should be used as early as possible in your app.
31+
e.g. in vite example with tanstack-router `LingoProvider` should be above `RouterProvider`, otherwise code-splitting breaks contexts.
32+
```tsx
33+
// Imports and other tanstack router setup
34+
if (rootElement && !rootElement.innerHTML) {
35+
const root = ReactDOM.createRoot(rootElement);
36+
root.render(
37+
<StrictMode>
38+
<LingoProvider>
39+
<RouterProvider router={router} />
40+
</LingoProvider>
41+
</StrictMode>,
42+
);
43+
}
44+
```
45+
46+
See `demo/vite-react-spa` for the working example
47+
48+
### Next.js
49+
50+
- Use `withLingo` function to wrap your existing next config. You will have to make your config async.
51+
52+
```ts
53+
import type { NextConfig } from "next";
54+
import { withLingo } from "@lingo.dev/compiler/next";
55+
56+
const nextConfig: NextConfig = {};
57+
58+
export default async function (): Promise<NextConfig> {
59+
return await withLingo(nextConfig, {
60+
sourceRoot: "./app",
61+
sourceLocale: "en",
62+
targetLocales: ["es", "de", "ru"],
63+
models: "lingo.dev",
64+
dev: {
65+
usePseudotranslator: true,
66+
},
67+
buildMode: "cache-only",
68+
});
69+
}
70+
```
71+
72+
- Wrap your app with `LingoProvider`. It should be used as early as possible in your app, root `Layout` is a good place.
73+
```tsx
74+
export default function RootLayout({
75+
children,
76+
}: Readonly<{ children: React.ReactNode }>) {
77+
return (
78+
<LingoProvider>
79+
<html>
80+
<body className="antialiased">{children}</body>
81+
</html>
82+
</LingoProvider>
83+
);
84+
}
85+
```
86+
87+
## Development
488

589
`pnpm install` from project root
690
`pnpm turbo dev --filter=@lingo.dev/compile` to compile and watch for compiler changes

cmp/docs/TRANSLATION_ARCHITECTURE.md

Lines changed: 18 additions & 210 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
## Overview
44

5-
This document describes the refactored translation architecture that provides clear separation of concerns between metadata management, translation execution, and caching.
5+
This document describes the refactored translation architecture that provides clear separation of concerns between
6+
metadata management, translation execution, and caching.
67

78
## Architectural Principles
89

@@ -18,7 +19,6 @@ This document describes the refactored translation architecture that provides cl
1819
3. **Caching is handled at the service layer**
1920
- Translation Service owns cache strategy
2021
- Cache implementations can be swapped (local disk, remote, memory, etc.)
21-
- Translators remain pure and simple
2222

2323
4. **Partial failures are handled gracefully**
2424
- Service returns both successful translations and errors
@@ -29,18 +29,18 @@ This document describes the refactored translation architecture that provides cl
2929

3030
```
3131
┌─────────────────────────────────────────────────┐
32-
│ AST Transformer
32+
│ AST Transformer │
3333
│ - Extracts text from JSX │
3434
│ - Knows ComponentType, context │
3535
└────────────────┬────────────────────────────────┘
3636
│ writes
3737
38-
┌─────────────────────────────────────────────────┐
38+
┌─────────────────────────────────────────────────
3939
│ MetadataManager │
4040
│ - ONLY component that reads/writes metadata.json│
4141
│ - Provides metadata loading/saving │
42-
│ - Returns TranslationEntry[] │
43-
└────────────────┬────────────────────────────────┘
42+
│ - Returns TranslationEntry[]
43+
└────────────────┬────────────────────────────────
4444
│ reads from
4545
4646
┌─────────────────────────────────────────────────┐
@@ -66,175 +66,10 @@ This document describes the refactored translation architecture that provides cl
6666

6767
## Core Components
6868

69-
### 1. TranslationCache Interface
70-
71-
**Location:** `compiler/src/translate/cache.ts`
72-
73-
Abstract interface for cache implementations:
74-
75-
```typescript
76-
interface TranslationCache {
77-
get(locale: string): Promise<Record<string, string>>;
78-
update(locale: string, translations: Record<string, string>): Promise<void>;
79-
set(locale: string, translations: Record<string, string>): Promise<void>;
80-
has(locale: string): Promise<boolean>;
81-
clear(locale: string): Promise<void>;
82-
clearAll(): Promise<void>;
83-
}
84-
```
85-
86-
**Key principle:** Cache stores simple `hash -> translation` mappings. It doesn't need to know about metadata context.
87-
88-
### 2. LocalTranslationCache
89-
90-
**Location:** `compiler/src/translate/local-cache.ts`
91-
92-
Disk-based cache implementation that stores translations in `.lingo/cache/{locale}.json`:
93-
94-
```typescript
95-
const cache = new LocalTranslationCache({
96-
cacheDir: ".lingo",
97-
sourceRoot: ".",
98-
});
99-
```
100-
101-
**Future:** Can easily add `RemoteTranslationCache`, `MemoryTranslationCache`, etc.
102-
103-
### 3. TranslationService
104-
105-
**Location:** `compiler/src/translate/translation-service.ts`
106-
107-
Main orchestrator that coordinates the translation workflow:
108-
109-
```typescript
110-
const service = new TranslationService(translator, cache, {
111-
sourceLocale: "en",
112-
useCache: true,
113-
});
114-
115-
const result = await service.translate(locale, metadata, requestedHashes);
116-
// Returns: { translations, errors, stats }
117-
```
118-
119-
**Responsibilities:**
120-
121-
- Load metadata from MetadataManager
122-
- Check cache for existing translations
123-
- Determine what needs translation (missing hashes)
124-
- Call translator for missing translations only
125-
- Handle partial failures gracefully
126-
- Update cache with new translations
127-
- Return results with errors for debugging
128-
129-
**Result format:**
130-
131-
```typescript
132-
interface TranslationResult {
133-
translations: Record<string, string>; // hash -> translated text
134-
errors: TranslationError[]; // Any failures that occurred
135-
stats: {
136-
total: number; // Total hashes requested
137-
cached: number; // How many came from cache
138-
translated: number; // How many were newly translated
139-
failed: number; // How many failed
140-
};
141-
}
142-
```
143-
144-
### 4. Translator Interface (unchanged)
145-
146-
**Location:** `compiler/src/translate/api.ts`
147-
148-
```typescript
149-
interface Translator<Config> {
150-
translate(locale: string, entry: TranslatableEntry): Promise<string>;
151-
batchTranslate(
152-
locale: string,
153-
entriesMap: Record<string, TranslatableEntry>,
154-
): Promise<Record<string, string>>;
155-
}
156-
157-
type TranslatableEntry = {
158-
text: string;
159-
context: Record<string, any>;
160-
};
161-
```
162-
163-
**Key principle:** Translators are stateless and only know about abstract entries. No file I/O, no caching logic.
164-
165-
## Migration Guide
166-
167-
### Old Approach (deprecated)
168-
169-
```typescript
170-
// ❌ Old: Wrapping translator with caching
171-
const translator = createCachedTranslatorFromConfig(config.translator, {
172-
cacheDir: ".lingo",
173-
useCache: true,
174-
});
175-
```
176-
177-
### New Approach
178-
179-
```typescript
180-
// ✅ New: Service handles caching
181-
const translator = createTranslator(config.translator);
182-
const cache = new LocalTranslationCache({ cacheDir: ".lingo" });
183-
const service = new TranslationService(translator, cache, {
184-
sourceLocale: "en",
185-
useCache: true,
186-
});
187-
188-
const result = await service.translate(locale, metadata);
189-
```
190-
191-
## Benefits of New Architecture
192-
193-
1. **Clear Separation of Concerns**
194-
- Metadata knows file structure
195-
- Translators know translation logic
196-
- Cache knows storage
197-
- Service coordinates everything
198-
199-
2. **Easier Testing**
200-
- Can mock cache separately from translator
201-
- Can test translators without file system
202-
- Can test service with mock dependencies
203-
204-
3. **Better Error Handling**
205-
- Partial failures don't break everything
206-
- Errors include context for debugging
207-
- Can continue with cached translations
208-
209-
4. **Flexible Caching**
210-
- Easy to add remote cache
211-
- Easy to add memory cache for tests
212-
- Easy to implement different cache strategies
213-
214-
5. **Type Safety**
215-
- Clear interfaces for each layer
216-
- Compiler catches misuse
217-
- Self-documenting code
218-
219-
## Files Changed
220-
221-
### New Files
222-
223-
- `compiler/src/translate/cache.ts` - Cache interface
224-
- `compiler/src/translate/local-cache.ts` - Local disk cache implementation
225-
- `compiler/src/translate/translation-service.ts` - Orchestrator service
226-
227-
### Modified Files
228-
229-
- `compiler/src/plugin/shared-middleware.ts` - Simplified to use service (345 → 224 lines)
230-
- `compiler/src/translate/translator-factory.ts` - Removed caching wrapper
231-
- `compiler/src/translate/index.ts` - Updated exports
232-
- `compiler/src/types.ts` - Added `useCache` to config types
233-
234-
### Deprecated Files (kept for backward compatibility)
235-
236-
- `compiler/src/translate/cached-translator.ts` - Use TranslationService instead
237-
- `compiler/src/translate/cache-server.ts` - Use LocalTranslationCache instead
69+
Cache api - `compiler/src/translate/cache.ts`
70+
Local cache implementation - `compiler/src/translate/local-cache.ts`
71+
Orchestrator translation service - `compiler/src/translate/translation-service.ts`
72+
Translator and dictionary api - `compiler/src/translate/api.ts`
23873

23974
## Future Enhancements
24075

@@ -253,47 +88,20 @@ class RemoteTranslationCache implements TranslationCache {
25388
}
25489
```
25590

256-
### Metrics & Observability
257-
258-
The service already provides stats - easy to add metrics:
259-
260-
```typescript
261-
const result = await service.translate(locale, metadata);
262-
metrics.recordCacheHitRate(result.stats.cached / result.stats.total);
263-
metrics.recordTranslationErrors(result.errors.length);
264-
```
265-
266-
### Cache Warming
267-
268-
```typescript
269-
async function warmCache(locales: string[]) {
270-
const metadata = await loadMetadata(config);
271-
const service = createTranslationService(config);
272-
273-
for (const locale of locales) {
274-
await service.translate(locale, metadata);
275-
}
276-
}
277-
```
278-
27991
## Questions & Answers
28092

28193
**Q: Why not cache inside translators?**
282-
A: Caching is an infrastructure concern, not a translation concern. Different deployments might need different cache strategies (local dev vs production, single server vs distributed).
94+
A: Caching is an infrastructure concern, not a translation concern. Different deployments might need different cache
95+
strategies (local dev vs production, single server vs distributed).
28396

28497
**Q: What if I need context in the cache?**
285-
A: The service already has access to metadata context. If you need it in the cache, extend the cache interface to store `TranslationEntry` instead of just strings.
286-
287-
**Q: Can I still use the old cached translator?**
288-
A: Yes, it's deprecated but kept for backward compatibility. However, it won't receive new features and will be removed in a future major version.
98+
A: The service already has access to metadata context. If you need it in the cache, extend the cache interface to store
99+
`TranslationEntry` instead of just strings.
289100

290101
**Q: How do I add a new translator?**
291-
A: Implement the `Translator` interface, add a case to `translator-factory.ts`, and you're done. No need to worry about caching.
102+
A: Implement the `Translator` interface, add a case to `translator-factory.ts`, and you're done. No need to worry about
103+
caching.
292104

293105
**Q: What happens if translation fails?**
294-
A: The service returns partial results with errors. The cached translations are still returned, and errors include details for debugging.
295-
296-
---
297-
298-
**Last Updated:** November 2025
299-
**Version:** 0.1.0 (Beta)
106+
A: The service returns partial results with errors. The cached translations are still returned, and errors include
107+
details for debugging.

0 commit comments

Comments
 (0)