v2.0.0
v2.0.0 - Major client overhaul
Warning
Release notes are still under construction
Table of contents
Note
Asterisks (*) by section names indicate those that include note of any breaking changes from v1.x to v2.x.
- What's new?
- Prerequisites*
- Data API tables support
findAndRerank
support- Overhaul of the logging system*
- Overhaul of the timeout system*
- Overhaul of cursors*
- Overhauls of certain admin functionality*
- Increased client compatibility across all environments*
- New fully-customizable ser/des system
- Errors improvements*
- Various minor changes and improvements
- Migration tips
What's new?
Prerequisites*
- Node.js v18 or higher
- TypeScript v5.0 or higher
Data API tables support
Adds complete support for Data API tables via the Table
class.
Dual types*
Classes/types such as UpdateOneOptions
, FindCursor
, InsertManyError
, etc. have been split into two different variants of each:
CollectionUpdateOneOptions
andTableUpdateOneOptions
,CollectionFind
andCursorTableFindCursor
,CollectionInsertManyError
andTableInsertManyError
,- etc.
Collection methods on the Db
class (such as db.collection()
, db.createCollection()
, db.listCollections()
, etc.) now have sister methods for tables:
db.table()
,db.createTable()
,db.listTables()
,- etc.
Indexes
Furthermore, tables necessitate indexes, which may be created through table.createIndex()
(and its sister methods), and dropped through db.dropTableIndex()
.
Utility types
New utility types to infer the table's TS-type from its schema has been added as well:
InferTableSchema
InferTablePrimaryKey
Datatypes
Lastly, of the major additions, new datatypes have been added as well to support the new tables:
DataAPIBlob
DataAPIDate
DataAPITime
DataAPIDuration
DataAPIInet
DataAPIVector
BigNumber
(re-exported frombignumber.js
)
See DATATYPES.md for more information on the new datatypes.
findAndRerank
support
Note
This is tied to the Overhaul of cursors section; please read that section as well for more information.
Preview hybrid search support has dropped via the collection.findAndRerank()
method, which uses a new FindAndRerankCursor
to iterate over its results.
New LexicalDoc
type added as well as a sister type to VectorDoc
and VectorizeDoc
.
Overhaul of the logging system*
The logging system has evolved beyond a simple, immutable monitorCommands
flag which would emit events only on the DataAPIClient
class.
Now, logging is configured through the logging
option anywhere along the options hierarchy, and adds a variety of new features:
- Events may log to the console as well now, as opposed to just being emitted as an event
- All classes in the client hierarchy are now event listeners
- These all extend the
HierarchicalLogger
class, which implements a minimal event emitter - Events are bubbled up from the class they were emitted from, all the way up to the root
DataAPIClient
- Event bubbling may be cancelled through
event.stop[Immediate]Propagation()
like the DOM
- These all extend the
Logging may also be enabled/disabled/reconfigured on the fly, via the .updateLoggingConfig(<config>)
method on any HierarchicalLogger
instance (e.g. DataAPIClient
, Db
, Collection
, etc.).
See the logging examples for more information.
Overhaul of the timeout system*
The timeout system has been overhauled to be more flexible and descriptive than the current singular maxTimeMS
.
Timeouts are now configured through the timeoutDefaults
parameter on class options interfaces, and the timeout
parameter on method calls.
They are represented by the TimeoutDescriptor
class, which contains the six following keys:
Timeout Option | Description | Default |
---|---|---|
requestTimeoutMs |
Maximum time the client waits for a response from the server | 15 seconds |
generalMethodTimeoutMs |
Timeout for general methods without a specific override (mostly doc/row-level ops) | 30 seconds |
collectionAdminTimeoutMs |
Timeout for collection admin operations (create, drop, list, etc.) | 1 minute |
tableAdminTimeoutMs |
Timeout for table admin operations (create, drop, list, alter, create/dropIndex, etc.) | 30 seconds |
databaseAdminTimeoutMs |
Timeout for database admin operations (create, drop, list, info, findEmbeddingProviders, etc.) | 10 minutes |
keyspaceAdminTimeoutMs |
Timeout for keyspace admin operations (create, drop, list) | 30 seconds |
In general, the requestTimeoutMs
always corresponds to a single request from the server, but the rest of the timeouts account for the entire duration of the method, which is relevant in the case of multi-call methods.
A few important notes:
requestTimeoutMs
applies per individual HTTP request.- The other timeouts account for the entire duration of the method, which is relevant in the case of multi-call methods.
- Passing a
timeout
value as a plain number will use the most appropriate category for the method being called. - Setting a
timeout
to 0 disables it completely. - The legacy maxTimeMS option has been removed—simply replace it with
timeout
for a quick migration path.
Overhaul of cursors*
Cursors are no longer a single FindCursor
class, but are now a hierarchy of classes (click the link for a visualization of the class hierarchy).
- The classes now include:
AbstractCursor
,FindCursor
,FindAndRerankCursor
,CollectionFindCursor
,TableFindCursor
, andCollectionFindAndRerankCursor
.
Cursor methods have also been overhauled.
- Most importantly, builder methods no longer mutate the cursor. Instead, they return a fresh copy of the cursor with the new option set.
- For example,
cursor.limit(10)
will return a new cursor with the limit set to 10, and the original cursor will remain unchanged.
- For example,
- There have been a few method/property changes as well:
.bufferedCount()
=>.buffered()
.readBufferedDocuments()
=>.consumeBuffer()
- added the
.consumed(): number
property- returns the number of documents actually consumed from the cursor
- added the
.dataSource: Table | Collection
property- returns the table or collection the cursor is associated with
- added the
.state: CursorState
property- returns the current state of the cursor; may be
'idle'
,'started'
, or'closed'
- returns the current state of the cursor; may be
- removed the
.keyspace
property- use
dataSource.keyspace
instead
- use
- removed the
.closed
property- use
.state === 'closed' instead
- use
- un-deprecated
.forEach()
Cursors are also now typed as *Cursor<T, TRaw extends SomeDoc = SomeDoc>
rather than just *Cursor<T>
.
T
represents the type of doc after any mappings have been applied (viacursor.map()
)TRaw
represents the original type of the doc, before any mappings have been applied
However, for most intents and purposes, you may continue to treat cursors as if they were still typed as *Cursor<T>
.
Lastly, of the important changes, .clone()
no longer strips the mapping from the cursor.
Overhauls of certain admin functionality*
The astraAdmin.dbInfo()
, astraAdmin.listDatabases()
, dbAdmin.info()
, and db.info()
methods have been updated to return a curated set of information about the database, rather than the raw response from the server.
The raw response may still be found in the info.raw
property, but the info
object itself now contains a more user-friendly set of properties.
The info objects have been renamed to AstraPartialDatabaseInfo
and AstraFullDatabaseInfo
to reflect this change.
Increased client compatibility across all environments*
General client compatability has been improved in many ways, the most significant of which is the new seamless dual support for both CommonJS and ES modules.
Beyond that, the client has also:
- Removed its hard dependency on the
events
package- It did this by implementing its own
HierarchicalLogger
class, which contains a minimal event emitter implementation - Any
events
polyfill may be safely removed from your project if you are not using it anywhere else
- It did this by implementing its own
- Removed its hard dependency on the
fetch-h2
package- It did this by using the native
fetch
implementation as the default fetcher - The
fetch-h2
package now must be imported separately and passed to the client manually- See the using-http2 example to see how to do this in just a couple easy steps
- It did this by using the native
- Ensures complete support across both server and browser environments
- This is guaranteed by dogfooding the client in the DataStax Astra portal
- Uses
tslib
now to help reduce the library size
New fully-customizable ser/des system
Section still under construction; more details to come
Errors improvements*
Section still under construction; more details to come
Various minor changes and improvements
Section still under construction; more details to come
db.createCollection
changes*
The checkExists
parameter has been removed; the method now does not check for existence before attempting to create the collection.
- This is because collection created is already idempotent (if the definition is the same), and thus, the check was unnecessary
Collection
typing
Note
Unless you are using custom ser/des, you may continue to treat Collection
as if it were still typed as simply Collection<Schema>
.
Collection<Schema extends SomeDoc = SomeDoc>
was updated to be typed as the following:
class Collection<WSchema extends SomeDoc = SomeDoc, RSchema extends WithId<SomeDoc> = FoundDoc<WSchema>> {}
where:
WSchema
is the type of the row as it's written to the table (the "write" schema)RSchema
is the type of the row as it's read from the table (the "read" schema)FoundDoc
is a generic type which represents the type of the document as it's returned from the Data API (i.e. in read operations).
In astra-db-ts
version 1.x, FoundDoc
was used directly in the return type of find
, findOne
, and other find
-ing types.
async findOne(filter: Filter, options: FindOneOptions): Promise<FoundDoc<Schema> | null>;
However, now that FoundDoc
and FoundRow
are type parameters of the Collection
and Table
types themselves, the read-types may explicitly override for advanced use cases.
DataAPIVector
The DataAPIVector
class is now generally recommended to be used over raw number[]
s as it offers a more performant and compact representation of vectors.
While you may still write vectors as a number[]
, the DataAPIVector
class is now what's returned from reading from a collection or table, which will cause breaking changes for code expecting number[]
s to be read back.
Other datatype updates
UUID.v1()
and UUID.v6()
are now available as static methods on the UUID
class, alongside the existing UUID.v4()
and UUID.v7()
members.
Also, new uuid
and oid
shorthand functions/objects have been added alongside the other shorthands for the new table datatypes:
uuid(...)
=>new UUID(...)
uuid.v4()
=>UUID.v4()
oid(...)
=>new ObjectId(...)
oid()
=>new ObjectId()
escapeFieldNames
/ unescapeFieldPath
New utility functions have been introduced for safely escaping and un-escaping field paths when working with the Data API.
These functions ensure that special characters such as .
and &
in field names don't interfere with query path parsing, while preserving accurate round-tripping of deeply nested fields.
// 'shows.tom&&jerry.views'
escapeFieldNames('shows', 'tom&jerry', 'views')
// ['users', 'john.doe', 'profile']
unescapeFieldPath('users.john&.doe.profile')
Documentation overhauls
The TSDoc is in the process of being heavily overhauled to be much clearer, consistent, and easier to read, through the use of section headers, separators, and admonitions.
- This is still a work in progress; not all areas of the client have been updated yet
- See the
Collection
class for an example of the new documentation style
Better type validation errors
astra-db-ts
validates options and arguments at runtime when creating/spawning new classes, and has been improved to provide better parse error messages when invalid options are passed, via the decoders
library.
Testing
- Test coverage has been heavily improved across the board
- Property-based testing via
fast-check
has been integrated into the test suite
Migration tips
Warning
Migration notes are still under construction
Helpful migration type-errors
In many cases, to help you migrate to the new version, the client will throw helpful type errors when you try to use deprecated or removed options.
const coll = await db.createCollection('my_coll', {
// TS2322: Type false is not assignable to type
// 'ERROR: `checkExists` has been removed. It is equivalent to being always `false` now.'
checkExists: false
});
// TS2322: Type number is not assignable to type
// 'ERROR: The `maxTimeMS` option is no longer available; the timeouts system has been overhauled, and timeouts should now be set using `timeout`'
await coll.findOne({}, { maxTimeMS: 1000 });
Splitting types
Many types have been split into two different variants of each:
Collection
variants (e.g.CollectionUpdateOneOptions
,CollectionFindCursor
, etc.)Table
variants (e.g.TableUpdateOneOptions
,TableFindCursor
, etc.)
If you run into a type no longer being found, check to see if it has been split into one of these variants.
Cursors
Cursors must most importantly now be mindful that they are no longer mutated by builder methods.
In general though, due to the not insignificant number of changes to cursors, please read and accommodate the changes outlined in the overhaul of cursors section, and read the TSDoc of the cursors classes for any more information.
Vectors
It is recommended to migrate to using the DataAPIVector
class rather than raw number[]
s, as it is now the default type returned from reading vectors from a collection or table.
If you really need to use number[]
s everywhere, you may write a simple codec to change this ser/des behavior.
maxTimeMS
You may generally just replace maxTimeMS
with timeout
, and it will work as expected.
Re-enabling HTTP2
If you are using HTTP2, you will need to import the fetch-h2
package separately and pass it to the client manually.
See the using-http2 example to see how to do this in just a couple easy steps.