Skip to content

VSKI v0.7.0

Collection names are now scoped per database instead of globally unique. Two databases may each have an orders collection - they are fully independent namespaces with independent schemas, records, views, indexes, realtime topics, and tombstones. Multi-tenant consumers no longer need to prefix collection names to avoid collisions.

  • Bare-name cross-database access no longer falls back to a global lookup. Collection names and IDs resolve strictly within the database addressed by the x-dbname header (default default); a wrong or missing header is a 404. Cross-database access must qualify the database (client.db(name).collection(...), collection(name, db), or the x-dbname header).
  • Registry uniqueness is now (dbName, name) instead of name alone. Creating a collection that duplicates a live name in the same database still fails with Collection name already exists; the same name in another database is allowed.
  • Realtime topics are keyed (db, name) and the connection’s ?db= parameter is authoritative: SUBSCRIBE resolves the collection in that database and a miss is a loud ERROR frame. EVENT/SUBSCRIBED frames carry a new additive db field.
  • Duplicate relation targets must be qualified. Relation fields may declare an optional options.db for cross-database targets; relations without it resolve in the source collection’s own database (then a unique global match). A name present in several databases with no qualifier is a 400 naming the candidates.
  • System collections (_users, _stats_*, workflow queues) are platform-global and keep resolving from any namespace - stats and workflow surfaces are unchanged.
  • Legacy database files migrate automatically on boot: the inline UNIQUE(name) constraint is replaced by the uq_collections_db_name composite index via an idempotent table rebuild; rows are preserved.
  • Create-over-tombstone now revives the tombstoned row under its original id instead of a blind name-keyed resurrection followed by an error.
  • Options-based views in non-default databases now resolve (the options lookup previously ran against the target file, which never holds registry rows).
  • client (TS/JS): registry ops accept a database scope (client.db(name).settings), realtime subscriptions re-key to the db:name topic and dispatch on the frame’s db.
  • client-python: every settings.collections method takes an optional db; realtime dispatch filters subscription entries by the frame’s db. client.collection(name, db) was already scoped.