- Tooling: switch to Vite + Vitest
- Tooling: define direnv devshell with Nix
- SQLite: fix time measurement. It was just measuring the time of the sqlite initial call :-/
- SQLite: accurate query time measurement. Before, query timing included any queries that were underway. This change serializes all calls to the SQLite connection when either debug has
strato-db/sqlite:query
enabled or there are listeners on thecall
event. This might have a performance impact, but likely very small. Note that SQLite itself can only do one DB operation at a time (per connection).
- SQLite: prevent interpolation in query debug output
- Remove old build dependencies
- Slightly improve types, mostly replacing null returns with undefined
- ESModel preprocessor was not resetting _maxId properly
- JsonModel: Backwards cursors
- ESDB: deprecate
undefined
in reducer results
- ESDB: fix multiple dispatches in transact returning old event
- JsonModel: throw parsing errors also with debugging enabled; remove dataloader creation debug statements
- Statement: Fix sticky errored state of prepared statements
- ESDB: fix throwing when dispatching outside but during processing
- JsonModel: from
.each()
, call.search()
withnoTotal
- deprecation warnings fail in prod
- JsonModel:
.each()
was returning too early
Fun new features:
- JsonModel:
.each(attrs, options, fn)
now takesconcurrent
to limit the concurrently running functions. This adds a dependency on the tinyasync-sema
package. - ESDB: Added
transact({event, model, store, dispatch})
phase to the event processing flow. In this callback, you can calldispatch
to generate and await sub-events, and calling ESModel will work too (any model can use thedispatch
given via the constructor). - ESDB:
dispatch({type, data, ts})
(passing everything in a single argument) is now also possible, as well as foraddEvent
. - ESModel: provide event creators for set, update and remove.
We also have some tiny API changes that don't warrant a major version:
sqlite.userVersion(v?: number)
now always returns the user version, also when setting it. This makes more sense from an API perspective and has as good as no performance impact.- EventQueue:
.setKnownV()
is now synchronous and no longer returns a Promise. This is only a breaking change if you were using.then()
instead ofawait
. This requires the use ofAsyncLocalStorage
, and thus the minimum NodeJS version is now v12.17 (which is already ancient).
- ESDB: fix deadlock on queue add in migration (due to sync version setting)
- JM: while paging, if the total == the limit, the cursor is now also null, because there is no next page.
- SQLite: add
emit
event for query result monitoring - Small typing improvements
- ESDB: fix userVersion poll loop on error
- ESModel: allow changeId while writable
- deprecations are printed as console.warn
- The
dispatch()
function that is passed to redux methods was renamed toaddEvent()
.
- SQLite: added
.runOnceOnOpen()
to register functions that should be run on the open database but shouldn't open the database - Renamed
dispatch()
toaddEvent()
inside the event processing flow.dispatch()
still works but gives a deprecation warning. The.dispatch()
method is not affected.
- Statement: fixed an issue with error propagation on opening the database
- ESDB: fix rare race condition where read-only connection doesn't see just-committed transaction
- JM: Better error message on wrong colName in
.get()
- JM: Fix small issue with table name in error message on incorrect columns
- Improve typings in JSDoc
- Add TypeScript typing file
This unfortunately means that the automatic API.md creation no longer works, because jsdoc can't parse the TS types.
- ESModel -
getNextId()
fix (was returning incorrect values when run inside a subevent)
- The
cache
argument toJsonModel.clearCache(cache, [id], [colName])
is no longer optional, and the method will now always return theDataLoader
instance
- Added TypeScript types generated from the JSDoc, and improved some definitions
- There was a deadlock in some circumstances where the initialization of ESModel could wait on the EventQueue and vice versa
JsonModel.getAll(ids, [colName])
now optimizes getting 0 and 1 objects
- The package builds for NodeJS v10 now.
- EventSourcingDB events that result in errors now halt processing and have to be fixed before processing continues
waitForP
was removed from DB, useonWillOpen
instead, if it returns a Promise that will be waited for.- The EventSourcingDB version is now stored in the SQLite
user_version
pragma, and themetadata
model is no longer available by default. If you need it, addmetadata: {}
to themodels
passed to ESDB DB.models
was renamed toDB.store
for consistency with ESDB and also to be different from themodels
option.DB.models
still works but will output an error on first use in non-production.- The
result
argument passed to derivers is now the result of the deriver's model. All results are still available atevent.result
- DB connections now set
PRAGMA recursive_triggers
- In NODE_ENV=development, the order of unordered query results will sometimes be reversed to show where ordering is not consistent. In test this is not done since the ordering is always the same and used in snapshots etc.
- The
meta
argument in ESModel.set
and.update
moved to 4th position to make room fornoResult
- EventSourcingDB no longer checks for pending events when instantiated. You have to do this yourself with
.checkForEvents()
or simply.startPolling()
- DB no longer returns itself on
.exec()
. There's no reason for having it and it saves some GC work. .applyChanges(result)
was renamed to.applyResult(result)
- the debug namespace was changed to
strato-db
applyChanges
was moved from JsonModel to a separate helper functionapplyResult(model, result)
- EventSourcingDB now passes
emitter
as an option to models, so they can subscribe to events. You have to take it out before passing the options toJsonModel
. - Migration metadata is now stored in the table
{sdb} migrations
instead of_migrations
. There is a migration procedure, but don't open your DBs with previous versions of strato-db, since the old versions will try to run the migrations again (and fail, so the data is safe).
- reducers are now called with a single
{model, event, store, dispatch, isMainEvent}
object like preprocessor and deriver. Old reducers with multiple arguments are automatically wrapped and result in a deprecation message
- EventSourcingDB refactor:
- sub-events! You can dispatch events during events; they are handled depth-first in the same transaction. If any result in error, they error the parent event
- make error handling more robust
- simplify redux loop
- retry failed events with increasing timeouts and exit program after an hour
- ESModel will now emit a
${model.INIT}
event to allow setting up the table, if you passinit: true
- DB, JsonModel, EventSourcingDB: Better debugging information for queries and errors
- DB: split into SQlite and the migrations-adding DB
- SQlite: add
autoVacuum
option, sets up incremental vacuuming. If there are > 20xvacuumPageCount
free pages, it will freevacuumPageCount
pages everyvacuumInterval
seconds. Defaults to 1MB (of 4KB pages) and 30s. - SQlite: limit WAL file size after transaction to 4MB
- SQlite: run
PRAGMA optimize
every 2 hours - SQlite: emit
'begin'
,'rollback'
,'end'
,'finally'
on transactions as EventEmitter - JsonModel:
.set
and.update
take thenoReturn
boolean as their 3rd argument to indicate they don't have to return the value, as an optimization - SQLite: add
.inTransaction
boolean that indicates ifwithTransaction
is active - JsonModel:
.update
reuses a runningwithTransaction
, so there is probably never a reason to use.updateNoTrans
- EventQueue:
.latestVersion()
is deprecated in favor of.getMaxV()
- JsonModel: if the id column is not an integer type (which means that sqlite uses it as the
rowId
),rowId
will be added as a column. This ensures that the VACUUM command doesn't change therowid
s so that references to them won't become invalid. To disable this you can passkeepRowId: false
to JsonModel. - EventSourcingDB: provide a
cache
object to the preprocessor and reducer, which can be used to optimize data fetching. The cache is shared and only valid during the read-only phase of the event handling
- JsonModel: fix using columns with paths in
getAll
- JsonModel: don't error on existing indexes
- JsonModel
- refactor: split in multiple files
- change array queries so they can be prepared
- fix expression index creation before column
- EventQueue: test before calling timer.unref()
- build: Upgrade to Babel 7 and latest ESLint
Minor version change due to index changes on queue for ESDB
- DB: add filename and stack to SQLite errors
- JsonModel: allow thunking definitions, that way you can create helpers to define columns
- JsonModel: add
.each([attrs, [options]], fn)
to iterate over search resultsfn(row, i)
will be called with row data and row number - EventSourcingDB:
withViews = true
option to add the helper views to the queue - EventQueue: drop the
type
index and usetype, size
; always addsize
column
- EventQueue: Ensure that queue insertions maintain their order
- DB/EventSourcingDB: Fix
readOnly
mode and add test
- First public release!
- EventSourcingDB: the metadata table can be used as well
- EventQueue: don't keep Node alive while waiting unless
forever: true
- JsonModel: value() on non-real columns is now stored
JsonModel:
column.alwaysObject
: for JSON columns: always have an object at that path, and store empty objects as NULLcolumn.falsyBool
: store booleanish value as true/undefined.real:true
makes the column be integer type querying also works with truthy and falsy values
JsonModel:
column.where(val, origVal)
: Now the original value is also available to thewhere
function- fix json column detection for non-JSON columns
JsonModel: breaking API change
jsonPath
is nowpath
and defaults to column name- Columns can be real or virtual
- Real columns are put where
path
wants it value
can always be used to calculate field values, for real and virtual columnsparse
andstringify
convert values from/to database values- you can nest column parsing etc, it will run them in the right order
To upgrade:
- delete
jsonPath
where it's the same as the column name - rename
jsonPath
topath
- delete
value
where it's just extracting the same field as the column name, replace withtype
(and indicate the column type) orreal: true
get
is nowtrue
by default, so remove it when true and set it tofalse
when missing
- JsonModel: stricter options with better type checking
- EventQueue: add _recentHistory and _historyTypes views for debugging
- ESModel: add metadata to event data on index 3
- JsonModel:
required
flag on column makes sure the result of value() is non-null and sets allowNull to false for proper indexing
- Directly depend on mapbox/sqlite3 by copying the relevant code from kriasoft/sqlite
- Remove Bluebird dependency