Histórico de versões
Todas as versões do SorlaDB, da primeira em 2024 até hoje: o que foi adicionado, o que mudou e o que foi corrigido.
Changelog técnico no GitHub ↗Documentação completa
Um guia completo em inglês e português do Brasil: 16 capítulos, dos primeiros cinco minutos a desempenho, testes e receitas. Sem mudanças no código.
Documentação
- 16 capítulos em inglês e português do Brasil: primeiros passos, bancos e coleções, inserção, consultas, cursores, atualizar e excluir, validação por schema, formulários, eventos, consultas vivas, sincronização com o servidor, console, TypeScript, desempenho, testes e receitas com perguntas frequentes.
Atualizações mais rápidas e streams sob seu controle
As atualizações copiam só o que mudou, e os streams podem entregar cada bloco ao seu próprio código.
Novidades
stream(url, { apply(type, data) })entrega cada bloco ao seu código em vez de gravar numa coleção, esorla.stream(url, { apply })funciona sem coleção, para componentes que guardam as linhas por conta própria, como um grid de dados.
Desempenho
- As atualizações copiam só os objetos no caminho alterado; as partes intocadas são compartilhadas com a versão anterior, e os dados guardados nunca são alterados no lugar. Um
bulkWritede 100.000$setpor_idcaiu de cerca de 650 ms para 180 ms. - O conteúdo dos eventos de mudança (
documents,previous) só é copiado quando alguém está escutando. - Comparar a versão anterior e a nova de um documento pula as partes compartilhadas, em vez de serializar as duas em JSON.
- Números, textos e booleanos não passam mais por
structuredClone.
Consultas vivas e integrações com frameworks
Consultas que se atualizam sozinhas, com hooks prontos para React, Vue, Svelte e Angular.
Novidades
collection.watch(query, options): consultas vivas comsubscribe()/getSnapshot(), cópias congeladas, atualização incremental (só os documentos alterados são copiados), uma notificação por lote de escritas e observação apenas enquanto houver inscritos. Também funciona como store do Svelte e como Observable para ofrom()do RxJS.- Integrações opcionais com frameworks, com tipos:
sorla-db/react(useQuery,useDocument),sorla-db/vue(useQuery),sorla-db/svelte(query,documentStore) esorla-db/angular(querySignal,documentSignal).
Escritas em lote, índice de _id e sincronização com o servidor
bulkWrite no estilo MongoDB, buscas instantâneas por _id e carga a partir de um backend por Server-Sent Events ou WebSocket.
⚠ Atenção ao atualizar
Novidades
collection.bulkWrite(operations, { ordered })cominsertOne,updateOne,updateMany,replaceOne,deleteOneedeleteMany: contagens e ids do MongoDB, um evento de mudança por tipo no final eBulkWriteErrorcomwriteErrorse oresultparcial.- Um índice de
_id: filtros por_id({ _id: x },$eq,$in) encontram documentos sem varrer a coleção, emfind,findOne,count, atualizações,replaceOne, exclusões ebulkWrite. sort(spec, { nulls: 'first' | 'last' }), e opções por coleção:createCollection(name, schema, { nulls }),setOptions()egetOptions().cursor.ids(),cursor.forEach()e iteração comfor...ofsobre cópias.collection.stream(url, options): linhas carregadas em blocos de um endpoint de Server-Sent Events, com headers personalizados e POST, reconexão comLast-Event-ID, upserts por_ide callbacks de progresso e erro.collection.connect(url, options)esorla.connect(url, options): pedidos e respostas por WebSocket (páginas comload(),request()),rows/ops/deleteenviados pelo servidor aplicados na coleção, fila de pedidos durante a conexão, reconexão com espera crescente, heartbeats e timeouts.sorla.readEventStream(body, onEvent), o leitor de text/event-stream, e expressões regulares dentro de$in/$nin.
Mudanças
- Valores ausentes e nulos vão para o fim da ordenação nos dois sentidos, por padrão (antes vinham primeiro na ordem crescente, como no MongoDB). Use
{ nulls: 'first' }por ordenação ou por coleção para manter a ordem anterior. find()não copia mais todos os documentos encontrados: o cursor copia um documento só quando ele é lido, e é uma fotografia do momento em que ofind()rodou. Os resultados são as mesmas cópias de antes.
Inserções em grande volume
Inserir 100.000 documentos passou de minutos para bem menos de um segundo.
Correções
- As inserções eram quadráticas: cada documento inserido relia os ids da coleção inteira, então um
insertManyde 100.000 documentos levava minutos. Agora os ids são lidos uma vez por chamada, e um teste de desempenho garante isso.
Formulários ligados às coleções
Insira e edite documentos com um formulário HTML comum, validado pelo schema da coleção.
Novidades
collection.bindForm(form, options): modo de inserção ou edição, valores convertidos pelo schema, erros ao lado de cada campo, validação ao sair de cada campo,generate: truepara montar os campos a partir do schema, eventossorla:saved/sorla:invalide um controlador comvalues,fill,validate,submit,load,resetedestroy.collection.applyDefaults(doc): uma cópia do documento com os valores padrão do schema.- Um exemplo completo de formulário:
example/form_example.html.
Validação por schema
As coleções podem exigir um JSON Schema em toda inserção, atualização e upsert, com erros claros por campo.
Novidades
- Validação com um subconjunto do JSON Schema:
type(maisdate),required,properties,additionalProperties,enum,const, faixas numéricas,minLength/maxLength/pattern/format(email, date, date-time, uri),items/minItems/maxItems/uniqueItemsedefault. Schemas em forma de função também funcionam. sorla.ValidationErrorcomerrors: [{ path, rule, message }].collection.validate(doc),collection.setSchema(schema)ecollection.getSchema().
Correções
- O schema passado para
createCollection(name, schema)nunca era guardado.
Atualizações, exclusões e eventos de mudança
Todo o lado de escrita da API do MongoDB, mais eventos para reagir a cada mudança.
Novidades
updateOne/updateManycom$set,$unset,$inc,$push(com$each) e$pull, caminhos"a.b"e{ upsert }.replaceOne,deleteOne,deleteManyecount(query).- Eventos de mudança:
collection.on,onceeoffparainsert,update,replace,deleteechange. - Operadores de consulta
$regex(com$options, ou uma RegExp como valor) e$exists. cursor.skip()ecursor.limit(), e projeção por inclusão ({ name: 1 }).- Gestão de bancos:
sorla.listDatabases(),sorla.dropDb(),db.listCollections(),db.getCollection(),db.dropCollection()edb.getStats(). - Declarações de tipo para tudo isso.
Mudanças
cursor.projection()retorna o cursor e lança erro em projeções inválidas.
Base sólida e pacote no npm
Uma longa lista de correções, ordenação compatível com o MongoDB, tipos TypeScript e um build para navegador que caiu de 1,6 MB para 9,5 kB.
⚠ Atenção ao atualizar
Novidades
insertOneretorna o_idinserido einsertManyretorna os ids; os callbacks também recebem esses valores.insertManyvalida o lote inteiro antes de inserir qualquer coisa.sort()segue a ordem do MongoDB entre tipos diferentes, aceita caminhos"a.b"e a opçãocollation, e retorna o cursor.require('sorla-db')eimport sorla from 'sorla-db'funcionam, com declarações TypeScript.- Os testes rodam no GitHub Actions com Node 18, 20, 22 e 24.
Mudanças
insertOneguarda uma cópia: o objeto passado não recebe mais o_ide não fica mais ligado ao documento guardado. Use o id retornado.last()retorna os dados do documento, como ofirst().- O build para navegador não inclui mais o faker: de 1,6 MB para 9,5 kB. O pacote do npm leva só a biblioteca.
- É preciso Node 18 ou mais recente.
Correções
cursor.sort()funciona (sempre lançava erro por causa de dependências circulares), etoArray()retorna cópias simples.insertOneaceita valoresnulle rejeitainsertOne(null); um_idduplicado é rejeitado.- Todo objeto aninhado e item de array é verificado em busca de chaves proibidas, não só o primeiro objeto.
findOne()retornanullquando nada é encontrado, efirst()/last()retornamnullnum cursor vazio.- Caminhos
"a.b"retornamundefinedquando falta um passo, em vez do objeto pai. - Alterar um campo de um documento guardado lança um erro claro, documentos funcionam com chaves do tipo symbol, e nada mais é impresso no console.
Operadores lógicos aninhados
Combine $and, $or e $nor em qualquer profundidade, com vários operadores por campo.
Novidades
- Operadores lógicos aninhados:
$and,$ore$norem qualquer profundidade. - Vários operadores por campo, no nível principal e dentro dos operadores lógicos.
Mudanças
- Um documento sem o campo consultado atende a
$nee$nin, como no MongoDB.
Correções
$and/$oraninhados lançavamthis[operator] is not a function.- Só o primeiro operador de um campo era avaliado dentro de
$and/$or. $notnega a condição inteira.- Valores
nullpodem ser usados nas condições de consulta.
Primeira versão
A primeira versão do SorlaDB: coleções em memória no navegador, consultadas com a linguagem do MongoDB. Um projeto iniciado em 2023 por Anderson Arruda.
Novidades
- Bancos e coleções:
createDb,useDbecreateCollection, com os documentos guardados em memória. insertOneeinsertMany.findefindOneretornando um cursor comfirst(),last(),toArray(),hasNext()enext().- Operadores de comparação
$eq,$ne,$gt,$gte,$lt,$lte,$ine$nin. - Operadores lógicos
$and,$ore$not, que param de avaliar assim que o resultado é conhecido. - Caminhos com ponto para consultar objetos aninhados (
"address.city") e projeção de campos. - Chaves com
$ou.são rejeitadas, porque esses caracteres são reservados para operadores e caminhos. - Um build minificado para o navegador que registra
window.sorla.
