refactor: decouple core-storage services from static keys and update i18n setup to use configurable storage adapters

This commit is contained in:
Firman Ramdhani
2026-05-28 13:27:13 +07:00
parent b4af762baa
commit d0ebceb1bb
20 changed files with 377 additions and 375 deletions
+17 -6
View File
@@ -2,13 +2,13 @@
[← Back to Root](../../README.md)
A highly decoupled, type-safe internationalization engine for the Eigen Monorepo.
A highly decoupled, type-safe internationalization engine for the monorepo.
It uses a **Hybrid Namespace Strategy**:
1. **Centralized Engine**: Setup, local persistence (`@repo/core-storage`), and global words (`common`).
1. **Centralized Engine**: Setup, local persistence orchestration, and global words (`common`).
2. **Decentralized Dictionaries**: Feature-specific translations (`booking`, `billing`) live inside the application modules and are lazy-loaded.
This architecture strictly adheres to **Inversion of Control (IoC)**. The core engine handles local state and performance, but leaves API and networking decisions entirely to the consuming applications.
This architecture strictly adheres to **Inversion of Control (IoC)**. The core engine handles local state and performance, but leaves API, networking, and storage implementation decisions entirely to the consuming applications.
---
@@ -65,18 +65,29 @@ graph TD
## 1. App-Level Setup (Bootstrap)
Initialize the engine *before* your React application mounts to prevent UI flashing.
Initialize the engine *before* your React application mounts to prevent UI flashing. Provide an `I18nStorageAdapter` using Dependency Injection so the core engine can persist the user's language without being tightly coupled to a specific storage implementation.
```tsx
// apps/web/src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { setupI18n } from '@repo/core-i18n';
import { secureStorage, AppStorageKey } from './core/storage';
import App from './app';
async function bootstrap() {
// Synchronously reads preferred language from storage & inits i18next
await setupI18n();
// Synchronously reads preferred language from injected storage & inits i18next
await setupI18n({
storageAdapter: {
getLanguage: async () => {
const stored = await secureStorage.getItem(AppStorageKey.LOCALE);
return typeof stored === 'string' ? stored : null;
},
setLanguage: async (lng: string) => {
await secureStorage.setItem(AppStorageKey.LOCALE, lng);
},
},
});
createRoot(document.getElementById('app')!).render(
<StrictMode><App /></StrictMode>,