Durvald

Player de música local-first com núcleo Rust compartilhado e interfaces nativas

2025

Produto e estágio atual

Desenvolvo o Durvald como um player de música local-first em evolução de uma interface SolidJS/Tauri para aplicações nativas com núcleo compartilhado em Rust. Meu objetivo é organizar e reproduzir a coleção do usuário no próprio dispositivo.

Avancei mais na implementação macOS. Windows faz parte da migração para interfaces nativas e Linux tem uma implementação GTK4 iniciada. Essas frentes estão em estágios diferentes; ainda não ofereço paridade de funcionalidades entre as plataformas.

Interface nativa do Durvald no macOS, com navegação da biblioteca, álbum Switched-On Bach e controles de reprodução.Versão nativa macOS: detalhe de álbum, lista de faixas e player persistente.

Autoria e aprendizado

Desenvolvi todo o projeto, do logotipo e da identidade visual às interfaces e ao núcleo Rust, com auxílio de diferentes modelos de inteligência artificial. Durvald é um projeto pessoal de desenvolvimento e aprendizado.

Da versão Tauri às interfaces nativas

A versão Tauri ainda estava incompleta, aproximadamente na metade do desenvolvimento, quando decidi privilegiar interfaces nativas como oportunidade de aprender SwiftUI e GTK4. Boa parte do núcleo Rust já era utilizada no Tauri; esse reaproveitamento limitou o impacto da mudança. A migração aconteceu durante a construção do produto, sem representar a substituição de um sistema consolidado em produção.

Na primeira implementação, combinei SolidJS na apresentação, comandos e eventos Tauri na comunicação e Rust no processamento. Mantenho seu código público em durvald-tauri, como referência da etapa anterior do mesmo produto.

Na arquitetura atual, concentro as responsabilidades compartilhadas em durvald-core, independente de interface. A mudança preserva o objetivo do produto, mas substitui a camada de apresentação compartilhada por clientes nativos. Essa escolha exige manter integrações e comportamentos de interface por plataforma. A seção de memória registra uma observação local das duas versões; benchmarks controlados estão fora do escopo atual.

Interface da implementação anterior do Durvald, com SolidJS e Tauri.Captura da versão SolidJS/Tauri; não representa a interface nativa atual.

Consistência visual entre sistemas

A busca por interfaces próprias de cada sistema também respondeu a um problema que observei no Windows: efeitos de transparência e desfoque com backdrop-filter falhavam em componentes sobrepostos da interface Tauri. Relacionei esse comportamento à issue Chromium #40835530, que usei como referência técnica na investigação.

Essa experiência aumentava o trabalho de compatibilidade visual da interface compartilhada e contribuiu para minha decisão de adotar clientes nativos. A referência registra o problema investigado; não confirmei o estado atual de resolução da issue nesta revisão.

Menu de contexto da versão Tauri no Windows, com uma área retangular de fundo ultrapassando os cantos arredondados.Registrei esse defeito no Windows. Não observei o mesmo problema no Linux.

Distribuição Linux e custo de manutenção

Além da busca por interfaces nativas, meu fluxo de desenvolvimento Linux dependia de um ambiente Ubuntu. Relatos externos contextualizam esse custo: a discussão #12960 registra uma falha de linuxdeploy no Arch após a compilação, com incompatibilidade da ferramenta strip e observações do mantenedor sobre portabilidade de glibc. As issues #15106 e #11701 também relatam falhas na geração de AppImage no Arch.

Esses relatos reforçam a necessidade de controlar o ambiente de empacotamento e as dependências de distribuição. Não demonstram uma exigência universal de Ubuntu nem uma comparação controlada entre distribuições. A migração para GTK4 retira a WebView do cliente Linux, mas não elimina a necessidade de validar bibliotecas de sistema, empacotamento e compatibilidade entre distribuições.

Núcleo compartilhado e contratos

Concentrei no núcleo Rust indexação da biblioteca, persistência SQLite, reprodução local, histórico, configurações e integração Last.fm. Clientes SwiftUI e outros consumidores FFI usam a superfície UniFFI; o cliente GTK4, também escrito em Rust, consome diretamente a API pública do núcleo, sem bindings UniFFI.

A separação mantém as regras compartilhadas fora das interfaces. A documentação define contratos para caminhos e capas gerenciadas, varredura e cancelamento, formatos de áudio e erros públicos. Os clientes devem reagir às variantes de CoreError, sem interpretar mensagens de diagnóstico como contratos.

Consistência e operações demoradas

Somente uma varredura da biblioteca pode ocorrer por vez. O cancelamento é cooperativo: o trabalho para nos pontos seguros e os resultados cancelados não são persistidos. Uma varredura completa reconcilia arquivos removidos; uma varredura parcial ou cancelada preserva os registros existentes.

No cliente GTK4, os widgets permanecem na thread GTK/GLib e as operações do núcleo são encaminhadas para um runtime Tokio. Essa divisão evita executar trabalho bloqueante na thread da interface e exige coordenar resultados assíncronos com o ciclo de vida da janela.

Implementação por plataforma

  • macOS: cliente nativo SwiftUI com integração ao núcleo pela superfície UniFFI; frente mais avançada do desenvolvimento.
  • Windows: frente em desenvolvimento na transição para uma implementação nativa. Ainda não disponibilizei neste case uma demonstração nem uma lista validada de funcionalidades dessa versão.
  • Linux: base Rust/GTK4 que abre uma janela, inicializa o núcleo e consulta a quantidade de músicas persistidas. Importação, lista de faixas e controles de reprodução ainda são próximos passos. “Atualizar biblioteca” relê o banco; não inicia uma varredura.

Memória observada em idle

Transcrevi os valores abaixo de uma observação local no Activity Monitor, com as duas versões em idle. Identifiquei o processo Durvald como a versão nativa e os outros quatro como a versão Tauri.

ImplementaçãoProcesso ou comparaçãoMemória exibida
Nativa macOSDurvald73,5 MB
Taurihttp://localhost:142095,7 MB
Tauridurvald53,2 MB
Tauridurvald Graphics and Media17,3 MB
Tauridurvald Networking10,7 MB
Total TauriSoma dos quatro processos176,9 MB
Diferença observadaTauri menos nativa103,4 MB (aproximadamente 58% menor na nativa)

Nesta comparação, usei a soma dos valores exibidos pelo Activity Monitor, não memória física exclusiva. É uma observação pontual: não registrei neste case a máquina, a versão do macOS, os commits, o modo de build, o tamanho da biblioteca e o tempo em idle. O endereço localhost indica conteúdo servido localmente na versão Tauri. Os valores não comprovam uma redução geral de memória, consumo de CPU ou tempo de inicialização; uma comparação reproduzível requer condições equivalentes e múltiplas execuções.

Evidências e limites

Neste case, reúno código público, capturas da interface e uma observação local de memória. Meu foco é documentar o aprendizado em interfaces nativas e o reaproveitamento do núcleo Rust durante o desenvolvimento. Benchmarks comparativos não fazem parte do escopo atual; mantenho os valores de memória como registro pontual, sem promessa de desempenho geral.

Código atual

Versão anterior — Tauri

Contratos do núcleo Rust

Estado e execução do cliente Linux