Changelog

Every SorlaDB release, from the first version in 2024 to today: what was added, what changed and what was fixed.

Technical changelog on GitHub ↗
v1.7.2 Latest

Complete documentation

A full guide in English and Brazilian Portuguese: 16 chapters, from the first five minutes to performance, testing and a cookbook. No code changes.

Documentation

  • 16 chapters in English and Brazilian Portuguese: getting started, databases and collections, inserting, querying, cursors, updating and deleting, schema validation, forms, events, live queries, server sync, the console, TypeScript, performance, testing and a cookbook with FAQ.
v1.7.1

Faster updates and custom stream handling

Updates copy only what changed, and streams can hand each block to your own code.

Added

  • stream(url, { apply(type, data) }) hands each block to your code instead of writing it to a collection, and sorla.stream(url, { apply }) works without a collection, for components that store rows themselves, like a data grid.

Performance

  • Updates copy only the objects along the changed paths; the untouched parts are shared with the previous version, and stored data is never changed in place. A bulkWrite of 100,000 $set by _id went from about 650 ms to 180 ms.
  • Change event payloads (documents, previous) are copied only when someone listens.
  • Comparing the previous and new version of a document skips the shared parts instead of serializing both to JSON.
  • Numbers, strings and booleans no longer go through structuredClone.
v1.7.0

Live queries and framework bindings

Queries that stay current on their own, with ready-made hooks for React, Vue, Svelte and Angular.

Added

  • collection.watch(query, options): live queries with subscribe() / getSnapshot(), frozen copies, incremental updates (only changed documents are copied), one notification per batch of writes, and watching only while subscribed. It is also a Svelte store and an Observable for RxJS from().
  • Optional framework bindings, with types: sorla-db/react (useQuery, useDocument), sorla-db/vue (useQuery), sorla-db/svelte (query, documentStore) and sorla-db/angular (querySignal, documentSignal).
v1.6.0

Bulk writes, an _id index and server sync

MongoDB-style bulkWrite, instant lookups by _id, and loading from a backend over Server-Sent Events or WebSocket.

⚠ Attention when upgrading

Added

  • collection.bulkWrite(operations, { ordered }) with insertOne, updateOne, updateMany, replaceOne, deleteOne and deleteMany: MongoDB counts and ids, one change event per type at the end, and BulkWriteError with writeErrors and the partial result.
  • An _id index: filters on _id ({ _id: x }, $eq, $in) find documents without scanning, in find, findOne, count, updates, replaceOne, deletes and bulkWrite.
  • sort(spec, { nulls: 'first' | 'last' }), and collection options: createCollection(name, schema, { nulls }), setOptions() and getOptions().
  • cursor.ids(), cursor.forEach() and for...of iteration over copies.
  • collection.stream(url, options): rows loaded in blocks from a Server-Sent Events endpoint, with custom headers and POST, reconnection with Last-Event-ID, upserts by _id, and progress and error callbacks.
  • collection.connect(url, options) and sorla.connect(url, options): WebSocket requests and replies (load() pages, request()), pushed rows / ops / delete applied to the collection, queued requests while connecting, reconnection with back off, heartbeats and timeouts.
  • sorla.readEventStream(body, onEvent), the text/event-stream parser, and regular expressions inside $in / $nin.

Changed

  • Missing and null values sort last in both directions by default (they came first in ascending order, as in MongoDB). Use { nulls: 'first' } per sort or per collection to keep the previous order.
  • find() no longer copies every matching document: the cursor copies a document only when it is read, and it is a snapshot of the moment find() ran. Results are the same copies as before.
v1.5.1

Inserts at scale

Inserting 100,000 documents went from minutes to well under a second.

Fixed

  • Inserts were quadratic: every inserted document re-read the ids of the whole collection, so insertMany of 100,000 documents took minutes. The ids are now read once per call, and a performance test guards it.
v1.5.0

Forms bound to collections

Insert and edit documents with a plain HTML form, validated by the collection schema.

Added

  • collection.bindForm(form, options): insert or update mode, values converted with the schema, errors next to each field, validation as fields are left, generate: true to build the fields from the schema, sorla:saved / sorla:invalid events, and a controller with values, fill, validate, submit, load, reset and destroy.
  • collection.applyDefaults(doc): a copy of a document with the schema defaults.
  • A complete form example: example/form_example.html.
v1.4.0

Schema validation

Collections can enforce a JSON Schema on every insert, update and upsert, with clear errors per field.

Added

  • Schema validation with a subset of JSON Schema: type (plus date), required, properties, additionalProperties, enum, const, numeric ranges, minLength / maxLength / pattern / format (email, date, date-time, uri), items / minItems / maxItems / uniqueItems, and default. Function schemas work too.
  • sorla.ValidationError with errors: [{ path, rule, message }].
  • collection.validate(doc), collection.setSchema(schema) and collection.getSchema().

Fixed

  • The schema given to createCollection(name, schema) was never stored.
v1.3.0

Updates, deletes and change events

The full write side of the MongoDB API, plus events to react to every change.

Added

  • updateOne / updateMany with $set, $unset, $inc, $push (with $each) and $pull, "a.b" paths and { upsert }.
  • replaceOne, deleteOne, deleteMany and count(query).
  • Change events: collection.on, once and off for insert, update, replace, delete and change.
  • Query operators $regex (with $options, or a RegExp value) and $exists.
  • cursor.skip() and cursor.limit(), and inclusion projection ({ name: 1 }).
  • Database management: sorla.listDatabases(), sorla.dropDb(), db.listCollections(), db.getCollection(), db.dropCollection() and db.getStats().
  • Type declarations for all of the above.

Changed

  • cursor.projection() returns the cursor and throws on invalid projections.
v1.2.0

Solid foundations and an npm package

A long list of fixes, MongoDB-compatible sorting, TypeScript types, and a browser bundle that went from 1.6 MB to 9.5 kB.

⚠ Attention when upgrading

Added

  • insertOne returns the inserted _id and insertMany returns the ids; callbacks receive them too.
  • insertMany validates the whole batch before inserting anything.
  • sort() follows MongoDB’s order across types, supports "a.b" paths and a collation option, and returns the cursor.
  • require('sorla-db') and import sorla from 'sorla-db' both work, with TypeScript declarations.
  • Tests run on GitHub Actions on Node 18, 20, 22 and 24.

Changed

  • insertOne stores a copy: the given object no longer receives _id and is no longer linked to the stored document. Use the returned id.
  • last() returns the document data, like first().
  • The browser bundle no longer includes faker: from 1.6 MB to 9.5 kB. The npm package ships only the library.
  • Node 18 or later is required.

Fixed

  • cursor.sort() works (it always threw because of circular requires), and toArray() returns plain copies.
  • insertOne accepts null values and rejects insertOne(null); a duplicated _id is rejected.
  • Every nested object and array item is checked for prohibited keys, not just the first object.
  • findOne() returns null when nothing matches, and first() / last() return null on an empty cursor.
  • "a.b" paths return undefined when a step is missing instead of the parent object.
  • Changing a field of a stored document throws a clear error, documents work with symbol keys, and nothing is printed to the console anymore.
v1.1.0

Nested logical operators

Combine $and, $or and $nor at any depth, with several operators per field.

Added

  • Nested logical operators: $and, $or and $nor at any depth.
  • Several operators per field, at the top level and inside logical operators.

Changed

  • A document without the queried field matches $ne and $nin, like MongoDB.

Fixed

  • Nested $and / $or threw this[operator] is not a function.
  • Only the first operator of a field was evaluated inside $and / $or.
  • $not negates the whole condition.
  • null values can be used in query conditions.
v1.0.0

First release

The first version of SorlaDB: in-memory collections in the browser, queried with the MongoDB language. Started in 2023 by Anderson Arruda.

Added

  • Databases and collections: createDb, useDb and createCollection, with documents stored in memory.
  • insertOne and insertMany.
  • find and findOne returning a cursor with first(), last(), toArray(), hasNext() and next().
  • Comparison operators $eq, $ne, $gt, $gte, $lt, $lte, $in and $nin.
  • Logical operators $and, $or and $not, which stop evaluating as soon as the result is known.
  • Dot paths to query nested objects ("address.city") and field projection.
  • Keys with $ or . are rejected, because those characters are reserved for operators and paths.
  • A minified browser build that registers window.sorla.