2
2
3
3
` astra-db-ts ` is a TypeScript client for interacting with [ DataStax Astra DB] ( https://astra.datastax.com/signup ) .
4
4
5
- * This README targets v1.0.0+, which introduces a whole new API. Click [ here] ( https://www.youtube.com/watch?v=dQw4w9WgXcQ ) for the pre-existing client readme.*
6
-
7
- * For the sake of my job, I hope I remember to update that link before release.*
5
+ * This README targets v1.0.0+, which introduces a whole new API. Click [ here] ( https://github.com/datastax/astra-db-ts/tree/90ebeac6fec53fd951126c2bcc010c87f7f678f8?tab=readme-ov-file#datastaxastra-db-ts ) for the pre-existing client readme.*
8
6
9
7
## Quickstart
10
8
11
- Use your preferred package manager to install ` @datastax/astra-db-ts ` . Note that this requires a Node-compatable runtime .
9
+ Use your preferred package manager to install ` @datastax/astra-db-ts ` . Note that this is not supported in browsers .
12
10
13
- Get the * API endpoint* and your * applicaton token* for your Astra DB instance @ [ astra.datastax.com] ( https://astra.datastax.com ) .
11
+ Get the * API endpoint* and your * application token* for your Astra DB instance @ [ astra.datastax.com] ( https://astra.datastax.com ) .
14
12
15
13
Try the following code after setting the following environment variables:
16
14
@@ -93,7 +91,7 @@ Next steps:
93
91
94
92
### Abstraction diagram
95
93
96
- astra-db-ts's abstractions for working at the data and admin layers are structured as depicted by this diagram:
94
+ ` astra-db-ts ` 's abstractions for working at the data and admin layers are structured as depicted by this diagram:
97
95
98
96
![ Class hierarchy diagram] ( assets/imgs/class-hierarchy.png )
99
97
@@ -118,17 +116,106 @@ const admin = client.admin();
118
116
})();
119
117
```
120
118
121
- ## Working with ObjectIds and UUIDs
119
+ ### Getting the most out of the typing
120
+
121
+ ` astra-db-ts ` is a typescript-first library, performing minimal runtime type-checking. As such, it provides
122
+ a rich set of types to help you write type-safe code.
123
+
124
+ Here are some examples of how you can properly leverage types to make your code more robust:
125
+
126
+ ``` typescript
127
+ import { DataAPIClient , StrictFilter , StrictSort , UUID } from ' @/src/index' ;
128
+
129
+ const client = new DataAPIClient (' *TOKEN*' );
130
+ const db = client .db (' *ENDPOINT*' , { namespace: ' *NAMESPACE*' });
131
+
132
+ // You can strictly type your collections for proper type-checking
133
+ interface Person {
134
+ _id: UUID ,
135
+ name: string ,
136
+ interests: {
137
+ favoriteBand? : string ,
138
+ friend? : UUID ,
139
+ }
140
+ }
141
+
142
+ (async () => {
143
+ // Create your collections with a defaultId type to enforce the type of the _id field
144
+ // (Otherwise it'll default to a string UUID that wouldn't be deserialized as a UUID by the client)
145
+ const collection = await db .createCollection <Person >(' my_collection' , { defaultId: { type: ' uuidv7' } });
146
+
147
+ // Now it'll raise type-errors if you try to insert a document with the wrong shape
148
+ await collection .insertOne ({
149
+ _id: new UUID (' e7f1f3a0-7e3d-11eb-9439-0242ac130002' ),
150
+ name: ' John' ,
151
+ interests: {
152
+ favoriteBand: ' Nightwish' ,
153
+ },
154
+ // @ts-expect-error - 'eyeColor' does not exist in type MaybeId<Person>
155
+ eyeColor: ' blue' ,
156
+ });
157
+
158
+ // You can use the 'Strict*' version of Sort/Projection/Filter/UpdateFilter for proper type-checking and autocomplete
159
+ await collection .findOne ({
160
+ // @ts-expect-error - Type number is not assignable to type FilterExpr<UUID | undefined>
161
+ ' interests.friend' : 3 ,
162
+ } satisfies StrictFilter <Person >, {
163
+ sort: {
164
+ name: 1 ,
165
+ // @ts-expect-error - 'interests.favoriteColor' does not exist in type StrictProjection<Person>
166
+ ' interests.favoriteColor' : 1 as const ,
167
+ } satisfies StrictSort <Person >,
168
+ });
169
+ })();
170
+ ```
171
+
172
+ ### Working with Dates
173
+
174
+ Native JS ` Date ` objects can be used anywhere in documents to represent dates and times.
175
+
176
+ Document fields stored using the ` { $date: number } ` will also be returned as Date objects when read.
177
+
178
+ ``` typescript
179
+ import { DataApiClient } from ' @datastax/astra-db-ts' ;
180
+
181
+ // Reference an untyped collection
182
+ const client = new DataApiClient (' TOKEN' );
183
+ const db = client .db (' ENDPOINT' , { namespace: ' NAMESPACE' });
184
+ const collection = db .collection (' COLLECTION' );
185
+
186
+ // Insert documents with some dates
187
+ await collection .insertOne ({ dateOfBirth: new Date (1394104654000 ) });
188
+ await collection .insertOne ({ dateOfBirth: new Date (' 1863-05-28' ) });
189
+
190
+ // Update a document with a date and setting lastModified to now
191
+ await collection .updateOne (
192
+ {
193
+ dateOfBirth: new Date (' 1863-05-28' ),
194
+ },
195
+ {
196
+ $set: { message: ' Happy Birthday!' },
197
+ $currentDate: { lastModified: true },
198
+ },
199
+ );
200
+
201
+ // Will print *around* `new Date()` (i.e. when server processed the request)
202
+ const found = await collection .findOne ({ dateOfBirth: { $lt: new Date (' 1900-01-01' ) } });
203
+ console .log (found ?.lastModified );
204
+ ```
205
+
206
+ ### Working with ObjectIds and UUIDs
207
+
208
+ ` astra-db-ts ` exports an ` ObjectId ` and ` UUID ` class for working with these types in the database.
122
209
123
- astra-db-ts exports an ` ObjectId ` and ` UUID ` class for working with these types in the database. Here's an example:
210
+ Note that these are custom classes, and * not * the ones from the ` bson ` package. Make sure you're using the right one!
124
211
125
212
``` typescript
126
213
import { DataAPIClient , ObjectId , UUID } from ' @datastax/astra-db-ts' ;
127
214
128
215
interface Person {
129
216
_id: ObjectId | UUID ,
130
217
name: string ,
131
- friendId? : string ,
218
+ friendId? : ObjectId | UUID ,
132
219
}
133
220
134
221
// Connect to the db
@@ -152,7 +239,7 @@ const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' });
152
239
153
240
await collection .updateOne (
154
241
{ name: ' Jane' },
155
- { $set: { friendId: friendId . toString () } },
242
+ { $set: { friendId } },
156
243
);
157
244
158
245
// And let's get Jane as a document
@@ -162,4 +249,44 @@ const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' });
162
249
})();
163
250
```
164
251
165
- Note that these are custom classes, and * not* the ones from the ` bson ` package. Make sure you're using the right one!
252
+ ### Monitoring/logging
253
+
254
+ [ Like Mongo] ( https://www.mongodb.com/docs/drivers/node/current/fundamentals/logging/ ) , ` astra-db-ts ` doesn't provide a
255
+ traditional logging system—instead, it uses a "monitoring" system based on event emitters, which allow you to listen to
256
+ events and log them as you see fit.
257
+
258
+ Supported events include ` commandStarted ` , ` commandSucceeded ` , ` commandFailed ` , and ` adminCommandStarted ` ,
259
+ ` adminCommandPolling ` , ` adminCommandSucceeded ` , ` adminCommandFailed ` .
260
+
261
+ Note that it's disabled by default, and it can be enabled by passing ` monitorCommands: true ` option to the root options'
262
+ ` dbOptions ` and ` adminOptions ` .
263
+
264
+ ``` typescript
265
+ import { DataAPIClient } from ' @datastax/astra-db-ts' ;
266
+
267
+ const client = new DataAPIClient (' *TOKEN*' , {
268
+ dbOptions: {
269
+ monitorCommands: true ,
270
+ },
271
+ });
272
+
273
+ client .on (' commandStarted' , (event ) => {
274
+ console .log (` Running command ${event .commandName } ` );
275
+ });
276
+
277
+ client .on (' commandSucceeded' , (event ) => {
278
+ console .log (` Command ${event .commandName } succeeded in ${event .duration }ms ` );
279
+ });
280
+
281
+ client .on (' commandFailed' , (event ) => {
282
+ console .error (` Command ${event .commandName } failed w/ error ${event .error } ` );
283
+ });
284
+
285
+ const db = client .db (' *ENDPOINT*' );
286
+ const coll = db .collection (' *COLLECTION*' );
287
+
288
+ // Should log
289
+ // - "Running command insertOne"
290
+ // - "Command insertOne succeeded in <time>ms"
291
+ await coll .insertOne ({ name: ' Queen' });
292
+ ```
0 commit comments