Especificación de I18nId
Resumen
Sección titulada «Resumen»La especificación I18nId v1 define cómo las cadenas se convierten en identificadores deterministas y resistentes a colisiones para internacionalización.
Formato
Sección titulada «Formato»i18n:v1:<hash>Donde:
i18n- Identificador del protocolov1- Versión de la especificación<hash>- Hash BLAKE3 de la cadena normalizada (codificado en hex, 16 caracteres)
Ejemplos
Sección titulada «Ejemplos»| Cadena de origen | I18nId |
|---|---|
| ”Hello” | i18n:v1:a5b9c3d7e8f0 |
| ”Hello, World!” | i18n:v1:b6c8d4e9f1a2 |
| ” Hello “ | i18n:v1:a5b9c3d7e8f0 (igual después de la normalización) |
Normalización
Sección titulada «Normalización»Antes de generar el hash, las cadenas se normalizan:
- Recortar espacios - Eliminar espacios al inicio y al final
- Colapsar espacios internos - Varios espacios → un solo espacio
- Normalización Unicode - Forma NFC
- Minúsculas (opcional, configurable)
fn normalize(input: &str) -> String { input .trim() .split_whitespace() .collect::<Vec<_>>() .join(" ")}Generación del hash
Sección titulada «Generación del hash»use blake3::Hasher;
fn generate_i18n_id(text: &str) -> String { let normalized = normalize(text); let hash = blake3::hash(normalized.as_bytes()); let hex = hex::encode(&hash.as_bytes()[..8]); // First 8 bytes = 16 hex chars format!("i18n:v1:{}", hex)}Propiedades
Sección titulada «Propiedades»Determinista
Sección titulada «Determinista»La misma entrada siempre produce la misma salida:
assert_eq!( generate_i18n_id("Hello"), generate_i18n_id("Hello"));Resistente a colisiones
Sección titulada «Resistente a colisiones»BLAKE3 con 64 bits proporciona una resistencia de cumpleaños de ~2^32, adecuada para la mayoría de las aplicaciones.
Estable
Sección titulada «Estable»Los IDs se mantienen estables entre:
- Diferentes plataformas
- Diferentes lenguajes de programación
- Diferentes versiones (dentro de v1)
Uso en Greentic
Sección titulada «Uso en Greentic»Mensajes de flujo
Sección titulada «Mensajes de flujo»- id: greet type: reply config: message_key: "i18n:v1:a5b9c3d7e8f0"Tarjetas
Sección titulada «Tarjetas»{ "type": "TextBlock", "text": "{{i18n:i18n:v1:a5b9c3d7e8f0}}"}Plantillas
Sección titulada «Plantillas»{{t "i18n:v1:a5b9c3d7e8f0"}}Herramientas CLI
Sección titulada «Herramientas CLI»Generar ID
Sección titulada «Generar ID»greentic-i18n id "Hello, World!"# Output: i18n:v1:b6c8d4e9f1a2Verificar ID
Sección titulada «Verificar ID»greentic-i18n verify "i18n:v1:b6c8d4e9f1a2" "Hello, World!"# Output: ValidMigración desde otros sistemas
Sección titulada «Migración desde otros sistemas»Desde claves
Sección titulada «Desde claves»// Before{ "greeting.hello": "Hello" }
// After (auto-migration){ "i18n:v1:a5b9c3d7e8f0": "Hello" }Script de migración
Sección titulada «Script de migración»greentic-i18n migrate ./old-translations.json --output ./new-translations.jsonBuenas prácticas
Sección titulada «Buenas prácticas»- Usa siempre el CLI para generar IDs
- No modifiques los IDs manualmente - regénéralos si cambia el origen
- Guarda las cadenas fuente junto con las traducciones como referencia
- Versiona tus archivos de traducción - permite hacer rollback
- Prueba con múltiples locales - detecta traducciones faltantes