logo hsb.horse
← Voltar para o índice de snippets

Snippets

Store de hash de mensagens em tempo de build

Uma função TypeScript que realiza hash e encurta IDs de mensagens e contextos em tempo de build. Útil quando uma plataforma alvo restringe as chaves de tradução permitidas.

Publicado: Atualizado:

Algumas plataformas de tradução restringem o conjunto de caracteres ou o comprimento das chaves de tradução. IDs como user.profile.edit.title podem não ser aceitos diretamente. Realizar hash e encurtar os IDs em tempo de build contorna essas restrições.

Código

function toHex(buffer: ArrayBuffer): string {
return [...new Uint8Array(buffer)]
.map((b) => b.toString(16).padStart(2, '0'))
.join('')
}
export function createHashStore(alg: string = 'SHA-256') {
const contextHash = new Map<string, string>()
const msgIdHash = new Map<string, string>()
async function digestContext(context: string): Promise<string> {
const data = new TextEncoder().encode(context)
const buf = await crypto.subtle.digest(alg, data)
return toHex(buf).slice(0, 7)
}
async function digestMsgId(msgId: string): Promise<string> {
const data = new TextEncoder().encode(msgId)
const buf = await crypto.subtle.digest(alg, data)
return toHex(buf).slice(0, 10)
}
async function saveContext(context: string): Promise<string> {
const cached = contextHash.get(context)
if (cached) return cached
const hash = await digestContext(context)
contextHash.set(context, hash)
return hash
}
async function saveMsgId(msgId: string): Promise<string> {
const cached = msgIdHash.get(msgId)
if (cached) return cached
const hash = await digestMsgId(msgId)
msgIdHash.set(msgId, hash)
return hash
}
return { contextHash, msgIdHash, saveContext, saveMsgId }
}

O uso da Web Crypto API (crypto.subtle.digest) torna a implementação universal — funciona em navegadores, Node.js, Deno e Bun sem modificação. Os valores válidos para alg são 'SHA-1', 'SHA-256', 'SHA-384' e 'SHA-512'.

Como Funciona

saveContext e saveMsgId retornam hashes enquanto armazenam os resultados em cache num Map. Para a mesma entrada, o hash é calculado apenas uma vez. Os contextos (namespaces) são truncados nos primeiros 7 caracteres, os IDs de mensagem nos primeiros 10. Os contextos tendem a ser em menor número e apresentam menor risco de colisão, por isso um prefixo mais curto é suficiente.

Uso na Prática

Integrar num plugin de build (plugin Vite, transformação de código personalizada) para substituir os IDs de mensagem no código-fonte pelos seus hashes. Em runtime, a tabela de tradução é indexada pelo hash, não pela string original.

Para alterar o algoritmo de hash, passar um alg diferente a createHashStore. O comprimento de truncação é ajustável pelo argumento de slice.