effect-mongodb 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +25 -19
  2. package/dist/cjs/AggregationCursor.js +18 -8
  3. package/dist/cjs/AggregationCursor.js.map +1 -1
  4. package/dist/cjs/Collection.js +40 -29
  5. package/dist/cjs/Collection.js.map +1 -1
  6. package/dist/cjs/Db.js +9 -3
  7. package/dist/cjs/Db.js.map +1 -1
  8. package/dist/cjs/DocumentAggregationCursor.js +18 -8
  9. package/dist/cjs/DocumentAggregationCursor.js.map +1 -1
  10. package/dist/cjs/DocumentCollection.js +36 -24
  11. package/dist/cjs/DocumentCollection.js.map +1 -1
  12. package/dist/cjs/DocumentFindCursor.js +24 -14
  13. package/dist/cjs/DocumentFindCursor.js.map +1 -1
  14. package/dist/cjs/FindCursor.js +25 -18
  15. package/dist/cjs/FindCursor.js.map +1 -1
  16. package/dist/cjs/ListCollectionsCursor.js +18 -8
  17. package/dist/cjs/ListCollectionsCursor.js.map +1 -1
  18. package/dist/cjs/MongoClient.js +8 -2
  19. package/dist/cjs/MongoClient.js.map +1 -1
  20. package/dist/cjs/MongoError.js +7 -18
  21. package/dist/cjs/MongoError.js.map +1 -1
  22. package/dist/cjs/internal/mongo-error.js +27 -0
  23. package/dist/cjs/internal/mongo-error.js.map +1 -0
  24. package/dist/cjs/internal/schema.js +2 -2
  25. package/dist/cjs/internal/schema.js.map +1 -1
  26. package/dist/cjs/internal/version.js +1 -1
  27. package/dist/dts/AggregationCursor.d.ts +5 -5
  28. package/dist/dts/AggregationCursor.d.ts.map +1 -1
  29. package/dist/dts/Collection.d.ts +17 -18
  30. package/dist/dts/Collection.d.ts.map +1 -1
  31. package/dist/dts/Db.d.ts.map +1 -1
  32. package/dist/dts/DocumentAggregationCursor.d.ts +5 -5
  33. package/dist/dts/DocumentAggregationCursor.d.ts.map +1 -1
  34. package/dist/dts/DocumentCollection.d.ts +7 -7
  35. package/dist/dts/DocumentCollection.d.ts.map +1 -1
  36. package/dist/dts/DocumentFindCursor.d.ts +5 -5
  37. package/dist/dts/DocumentFindCursor.d.ts.map +1 -1
  38. package/dist/dts/FindCursor.d.ts +5 -5
  39. package/dist/dts/FindCursor.d.ts.map +1 -1
  40. package/dist/dts/ListCollectionsCursor.d.ts +5 -5
  41. package/dist/dts/ListCollectionsCursor.d.ts.map +1 -1
  42. package/dist/dts/MongoClient.d.ts.map +1 -1
  43. package/dist/dts/MongoError.d.ts +32 -12
  44. package/dist/dts/MongoError.d.ts.map +1 -1
  45. package/dist/dts/internal/mongo-error.d.ts +5 -0
  46. package/dist/dts/internal/mongo-error.d.ts.map +1 -0
  47. package/dist/esm/AggregationCursor.js +16 -6
  48. package/dist/esm/AggregationCursor.js.map +1 -1
  49. package/dist/esm/Collection.js +38 -27
  50. package/dist/esm/Collection.js.map +1 -1
  51. package/dist/esm/Db.js +9 -3
  52. package/dist/esm/Db.js.map +1 -1
  53. package/dist/esm/DocumentAggregationCursor.js +16 -6
  54. package/dist/esm/DocumentAggregationCursor.js.map +1 -1
  55. package/dist/esm/DocumentCollection.js +34 -22
  56. package/dist/esm/DocumentCollection.js.map +1 -1
  57. package/dist/esm/DocumentFindCursor.js +22 -12
  58. package/dist/esm/DocumentFindCursor.js.map +1 -1
  59. package/dist/esm/FindCursor.js +23 -16
  60. package/dist/esm/FindCursor.js.map +1 -1
  61. package/dist/esm/ListCollectionsCursor.js +16 -6
  62. package/dist/esm/ListCollectionsCursor.js.map +1 -1
  63. package/dist/esm/MongoClient.js +8 -2
  64. package/dist/esm/MongoClient.js.map +1 -1
  65. package/dist/esm/MongoError.js +3 -17
  66. package/dist/esm/MongoError.js.map +1 -1
  67. package/dist/esm/internal/mongo-error.js +18 -0
  68. package/dist/esm/internal/mongo-error.js.map +1 -0
  69. package/dist/esm/internal/schema.js +2 -2
  70. package/dist/esm/internal/schema.js.map +1 -1
  71. package/dist/esm/internal/version.js +1 -1
  72. package/package.json +1 -1
  73. package/src/AggregationCursor.ts +31 -6
  74. package/src/Collection.ts +80 -50
  75. package/src/Db.ts +7 -3
  76. package/src/DocumentAggregationCursor.ts +27 -5
  77. package/src/DocumentCollection.ts +52 -27
  78. package/src/DocumentFindCursor.ts +34 -11
  79. package/src/FindCursor.ts +36 -13
  80. package/src/ListCollectionsCursor.ts +31 -7
  81. package/src/MongoClient.ts +6 -2
  82. package/src/MongoError.ts +24 -32
  83. package/src/internal/mongo-error.ts +34 -0
  84. package/src/internal/schema.ts +2 -2
  85. package/src/internal/version.ts +1 -1
package/src/Db.ts CHANGED
@@ -8,6 +8,7 @@ import type { Document, DropCollectionOptions, ListCollectionsOptions } from "mo
8
8
  import { Db } from "mongodb"
9
9
  import type * as Collection from "./Collection.js"
10
10
  import * as DocumentCollection from "./DocumentCollection.js"
11
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
11
12
  import * as ListCollectionsCursor from "./ListCollectionsCursor.js"
12
13
  import * as MongoError from "./MongoError.js"
13
14
 
@@ -17,7 +18,7 @@ export const documentCollection: {
17
18
  } = F.dual(
18
19
  (args) => isDb(args[0]),
19
20
  (db: Db, name: string): DocumentCollection.DocumentCollection =>
20
- new DocumentCollection.DocumentCollection({
21
+ new DocumentCollection.DocumentCollectionImpl({
21
22
  collection: db.collection(name)
22
23
  })
23
24
  )
@@ -66,7 +67,7 @@ export const listCollections: {
66
67
  } = F.dual(
67
68
  (args) => isDb(args[0]),
68
69
  (db: Db, filter?: Document, options?: ListCollectionsOptions): ListCollectionsCursor.ListCollectionsCursor =>
69
- new ListCollectionsCursor.ListCollectionsCursor({ cursor: db.listCollections(filter, options) })
70
+ new ListCollectionsCursor.ListCollectionsCursorImpl({ cursor: db.listCollections(filter, options) })
70
71
  )
71
72
 
72
73
  export const dropCollection: {
@@ -79,8 +80,11 @@ export const dropCollection: {
79
80
  (db: Db, name: string, options?: DropCollectionOptions): Effect.Effect<boolean, MongoError.MongoError> =>
80
81
  F.pipe(
81
82
  Effect.promise(() => db.dropCollection(name, options)),
82
- Effect.catchAllDefect(MongoError.mongoErrorDie<boolean>("dropCollection error"))
83
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(db, "dropCollection")))
83
84
  )
84
85
  )
85
86
 
86
87
  const isDb = (x: unknown) => x instanceof Db
88
+
89
+ const errorSource = (db: Db, functionName: string) =>
90
+ new MongoError.DbErrorSource({ module: "Db", functionName, db: db.databaseName })
@@ -4,21 +4,35 @@
4
4
  import * as Data from "effect/Data"
5
5
  import * as Effect from "effect/Effect"
6
6
  import * as F from "effect/Function"
7
+ import type { Pipeable } from "effect/Pipeable"
8
+ import { pipeArguments } from "effect/Pipeable"
7
9
  import * as Stream from "effect/Stream"
8
10
  import type { AggregationCursor as MongoAggregationCursor, Document } from "mongodb"
11
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
9
12
  import * as MongoError from "./MongoError.js"
10
13
 
11
- export class DocumentAggregationCursor
12
- extends Data.TaggedClass("DocumentAggregationCursor")<{ cursor: MongoAggregationCursor<Document> }>
14
+ type DocumentAggregationCursorFields = { cursor: MongoAggregationCursor<Document> }
15
+
16
+ export interface DocumentAggregationCursor extends DocumentAggregationCursorFields, Pipeable {
17
+ _tag: "DocumentAggregationCursor"
18
+ }
19
+
20
+ /** @internal */
21
+ export class DocumentAggregationCursorImpl
22
+ extends Data.TaggedClass("DocumentAggregationCursor")<DocumentAggregationCursorFields>
23
+ implements DocumentAggregationCursor
13
24
  {
25
+ pipe() {
26
+ return pipeArguments(this, arguments)
27
+ }
14
28
  }
15
29
 
16
30
  export const toArray = (
17
31
  cursor: DocumentAggregationCursor
18
32
  ): Effect.Effect<Array<Document>, MongoError.MongoError> =>
19
33
  F.pipe(
20
- Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }),
21
- Effect.catchAll(MongoError.mongoErrorDie<Array<Document>>(`${cursor._tag}.toArray error`))
34
+ Effect.promise(() => cursor.cursor.toArray()),
35
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray")))
22
36
  )
23
37
 
24
38
  export const toStream = (
@@ -26,5 +40,13 @@ export const toStream = (
26
40
  ): Stream.Stream<Document, MongoError.MongoError> =>
27
41
  F.pipe(
28
42
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
29
- Stream.catchAll(MongoError.mongoErrorStream<Document>(`${cursor._tag}.toStream error`))
43
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream")))
30
44
  )
45
+
46
+ const errorSource = (cursor: DocumentAggregationCursor, functionName: string) =>
47
+ new MongoError.CollectionErrorSource({
48
+ module: DocumentAggregationCursorImpl.name,
49
+ functionName,
50
+ db: cursor.cursor.namespace.db,
51
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
52
+ })
@@ -6,6 +6,8 @@ import * as Data from "effect/Data"
6
6
  import * as Effect from "effect/Effect"
7
7
  import * as F from "effect/Function"
8
8
  import * as O from "effect/Option"
9
+ import type { Pipeable } from "effect/Pipeable"
10
+ import { pipeArguments } from "effect/Pipeable"
9
11
  import type * as Schema from "effect/Schema"
10
12
  import type {
11
13
  AggregateOptions,
@@ -40,11 +42,24 @@ import * as Collection from "./Collection.js"
40
42
  import * as DocumentAggregationCursor from "./DocumentAggregationCursor.js"
41
43
  import * as DocumentFindCursor from "./DocumentFindCursor.js"
42
44
  import type { ModifyResult } from "./internal/modify-result.js"
45
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
43
46
  import * as MongoError from "./MongoError.js"
44
47
 
45
- export class DocumentCollection extends Data.TaggedClass("DocumentCollection")<{
48
+ type DocumentCollectionFields = {
46
49
  collection: MongoCollection
47
- }> {
50
+ }
51
+
52
+ export interface DocumentCollection extends DocumentCollectionFields, Pipeable {
53
+ _tag: "DocumentCollection"
54
+ }
55
+
56
+ /** @internal */
57
+ export class DocumentCollectionImpl extends Data.TaggedClass("DocumentCollection")<DocumentCollectionFields>
58
+ implements DocumentCollection
59
+ {
60
+ pipe() {
61
+ return pipeArguments(this, arguments)
62
+ }
48
63
  }
49
64
 
50
65
  export const find: {
@@ -60,7 +75,7 @@ export const find: {
60
75
  } = F.dual(
61
76
  (args) => isDocumentCollection(args[0]),
62
77
  (collection: DocumentCollection, filter?: Filter<Document>, options?: FindOptions) =>
63
- new DocumentFindCursor.DocumentFindCursor(
78
+ new DocumentFindCursor.DocumentFindCursorImpl(
64
79
  {
65
80
  cursor: collection.collection.find(filter ?? {}, options)
66
81
  }
@@ -86,7 +101,7 @@ export const findOne: {
86
101
  F.pipe(
87
102
  Effect.promise(() => collection.collection.findOne(filter, options)),
88
103
  Effect.map((value) => O.fromNullable(value)),
89
- Effect.catchAllDefect(MongoError.mongoErrorDie<O.Option<Document>>("findOne error"))
104
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "findOne")))
90
105
  )
91
106
  )
92
107
 
@@ -110,7 +125,7 @@ export const insertOne: {
110
125
  ): Effect.Effect<InsertOneResult, MongoError.MongoError> =>
111
126
  F.pipe(
112
127
  Effect.promise(() => collection.collection.insertOne(doc, options)),
113
- Effect.catchAllDefect(MongoError.mongoErrorDie<InsertOneResult>("insertOne error"))
128
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertOne")))
114
129
  ))
115
130
 
116
131
  export const insertMany: {
@@ -132,7 +147,7 @@ export const insertMany: {
132
147
  ): Effect.Effect<InsertManyResult, MongoError.MongoError> =>
133
148
  F.pipe(
134
149
  Effect.promise(() => collection.collection.insertMany(docs, options)),
135
- Effect.catchAllDefect(MongoError.mongoErrorDie<InsertManyResult>("insertMany error"))
150
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertMany")))
136
151
  ))
137
152
 
138
153
  export const deleteOne: {
@@ -153,7 +168,7 @@ export const deleteOne: {
153
168
  ): Effect.Effect<DeleteResult, MongoError.MongoError> =>
154
169
  F.pipe(
155
170
  Effect.promise(() => collection.collection.deleteOne(filter, options)),
156
- Effect.catchAllDefect(MongoError.mongoErrorDie<DeleteResult>("deleteOne error"))
171
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteOne")))
157
172
  )
158
173
  )
159
174
 
@@ -175,7 +190,7 @@ export const deleteMany: {
175
190
  ): Effect.Effect<DeleteResult, MongoError.MongoError> =>
176
191
  F.pipe(
177
192
  Effect.promise(() => collection.collection.deleteMany(filter, options)),
178
- Effect.catchAllDefect(MongoError.mongoErrorDie<DeleteResult>("deleteMany error"))
193
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteMany")))
179
194
  )
180
195
  )
181
196
 
@@ -205,7 +220,7 @@ export const updateMany: {
205
220
  Effect.promise(() =>
206
221
  collection.collection.updateMany(filter, Array.isArray(update) ? [...update] : update, options)
207
222
  ),
208
- Effect.catchAllDefect(MongoError.mongoErrorDie<UpdateResult>("updateMany error"))
223
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "updateMany")))
209
224
  )
210
225
  )
211
226
 
@@ -233,7 +248,7 @@ export const replaceOne: {
233
248
  ): Effect.Effect<UpdateResult | Document, MongoError.MongoError> =>
234
249
  F.pipe(
235
250
  Effect.promise(() => collection.collection.replaceOne(filter, replacement, options)),
236
- Effect.catchAllDefect(MongoError.mongoErrorDie<UpdateResult | Document>("replaceOne error"))
251
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "replaceOne")))
237
252
  )
238
253
  )
239
254
 
@@ -303,7 +318,7 @@ export const findOneAndReplace: {
303
318
  return O.fromNullable(value)
304
319
  }),
305
320
  Effect.catchAllDefect(
306
- MongoError.mongoErrorDie<O.Option<Document> | ModifyResult<Document>>("findOneAndReplace error")
321
+ mongoErrorOrDie(errorSource(collection, "findOneAndReplace"))
307
322
  )
308
323
  )
309
324
  )
@@ -326,8 +341,8 @@ export const rename: {
326
341
  ): Effect.Effect<DocumentCollection, MongoError.MongoError> =>
327
342
  F.pipe(
328
343
  Effect.promise(() => collection.collection.rename(newName, options)),
329
- Effect.map((collection) => new DocumentCollection({ collection })),
330
- Effect.catchAllDefect(MongoError.mongoErrorDie<DocumentCollection>("rename error"))
344
+ Effect.map((collection) => new DocumentCollectionImpl({ collection })),
345
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "rename")))
331
346
  )
332
347
  )
333
348
 
@@ -342,7 +357,7 @@ export const drop: {
342
357
  ): Effect.Effect<boolean, MongoError.MongoError> =>
343
358
  F.pipe(
344
359
  Effect.promise(() => collection.collection.drop(options)),
345
- Effect.catchAllDefect(MongoError.mongoErrorDie<boolean>("drop error"))
360
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "drop")))
346
361
  )
347
362
  )
348
363
 
@@ -364,7 +379,7 @@ export const createIndexes: {
364
379
  ): Effect.Effect<Array<string>, MongoError.MongoError> =>
365
380
  F.pipe(
366
381
  Effect.promise(() => collection.collection.createIndexes([...indexSpecs], options)),
367
- Effect.catchAllDefect(MongoError.mongoErrorDie<Array<string>>("createIndexes error"))
382
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndexes")))
368
383
  )
369
384
  )
370
385
 
@@ -387,32 +402,30 @@ export const createIndex: {
387
402
  ): Effect.Effect<string, MongoError.MongoError> =>
388
403
  F.pipe(
389
404
  Effect.promise(() => collection.collection.createIndex(indexSpec, options)),
390
- Effect.catchAllDefect(MongoError.mongoErrorDie<string>("createIndex error"))
405
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndex")))
391
406
  )
392
407
  )
393
408
 
394
- // TODO: review return type. Should we return Document like mongodb driver?
395
409
  export const dropIndex: {
396
410
  (
397
411
  indexName: string,
398
412
  options?: DropIndexesOptions
399
- ): (collection: DocumentCollection) => Effect.Effect<void, MongoError.MongoError>
413
+ ): (collection: DocumentCollection) => Effect.Effect<Document, MongoError.MongoError>
400
414
  (
401
415
  collection: DocumentCollection,
402
416
  indexName: string,
403
417
  options?: DropIndexesOptions
404
- ): Effect.Effect<void, MongoError.MongoError>
418
+ ): Effect.Effect<Document, MongoError.MongoError>
405
419
  } = F.dual(
406
420
  (args) => isDocumentCollection(args[0]),
407
421
  (
408
422
  collection: DocumentCollection,
409
423
  indexName: string,
410
424
  options?: DropIndexesOptions
411
- ): Effect.Effect<void, MongoError.MongoError> =>
425
+ ): Effect.Effect<Document, MongoError.MongoError> =>
412
426
  F.pipe(
413
427
  Effect.promise(() => collection.collection.dropIndex(indexName, options)),
414
- Effect.asVoid,
415
- Effect.catchAllDefect(MongoError.mongoErrorDie<void>("dropIndex error"))
428
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "dropIndex")))
416
429
  )
417
430
  )
418
431
 
@@ -432,7 +445,7 @@ export const aggregate: {
432
445
  pipeline?: ReadonlyArray<Document>,
433
446
  options?: AggregateOptions
434
447
  ): DocumentAggregationCursor.DocumentAggregationCursor =>
435
- new DocumentAggregationCursor.DocumentAggregationCursor({
448
+ new DocumentAggregationCursor.DocumentAggregationCursorImpl({
436
449
  cursor: collection.collection.aggregate(pipeline ? [...pipeline] : undefined, options)
437
450
  })
438
451
  )
@@ -453,7 +466,7 @@ export const estimatedDocumentCount: {
453
466
  ): Effect.Effect<number, MongoError.MongoError> =>
454
467
  F.pipe(
455
468
  Effect.promise(() => collection.collection.estimatedDocumentCount(options)),
456
- Effect.catchAllDefect(MongoError.mongoErrorDie<number>("estimatedDocumentCount error"))
469
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "estimatedDocumentCount")))
457
470
  )
458
471
  )
459
472
 
@@ -475,7 +488,7 @@ export const countDocuments: {
475
488
  ): Effect.Effect<number, MongoError.MongoError> =>
476
489
  F.pipe(
477
490
  Effect.promise(() => collection.collection.countDocuments(filter, options)),
478
- Effect.catchAllDefect(MongoError.mongoErrorDie<number>("countDocuments error"))
491
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "countDocuments")))
479
492
  )
480
493
  )
481
494
 
@@ -490,6 +503,18 @@ export const typed: {
490
503
  } = F.dual((args) => isDocumentCollection(args[0]), <A extends Document, I extends Document = A, R = never>(
491
504
  collection: DocumentCollection,
492
505
  schema: Schema.Schema<A, I, R>
493
- ): Collection.Collection<A, I, R> => new Collection.Collection<A, I, R>({ collection: collection.collection, schema }))
506
+ ): Collection.Collection<A, I, R> =>
507
+ new Collection.CollectionImpl<A, I, R>({ collection: collection.collection, schema }))
508
+
509
+ const isDocumentCollection = (x: unknown) => x instanceof DocumentCollectionImpl
494
510
 
495
- const isDocumentCollection = (x: unknown) => x instanceof DocumentCollection
511
+ const errorSource = (
512
+ collection: DocumentCollection,
513
+ functionName: string
514
+ ) =>
515
+ new MongoError.CollectionErrorSource({
516
+ module: DocumentCollectionImpl.name,
517
+ functionName,
518
+ db: collection.collection.dbName,
519
+ collection: collection.collection.collectionName
520
+ })
@@ -4,15 +4,30 @@
4
4
  import * as Data from "effect/Data"
5
5
  import * as Effect from "effect/Effect"
6
6
  import * as F from "effect/Function"
7
+ import type { Pipeable } from "effect/Pipeable"
8
+ import { pipeArguments } from "effect/Pipeable"
7
9
  import type * as Schema from "effect/Schema"
8
10
  import * as Stream from "effect/Stream"
9
11
  import type { Document, Filter, FindCursor as MongoFindCursor, Sort, SortDirection } from "mongodb"
10
12
  import * as FindCursor from "./FindCursor.js"
13
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
11
14
  import * as MongoError from "./MongoError.js"
12
15
 
13
- export class DocumentFindCursor extends Data.TaggedClass("DocumentFindCursor")<{
16
+ type DocumentFindCursorFields = {
14
17
  cursor: MongoFindCursor<Document>
15
- }> {
18
+ }
19
+
20
+ export interface DocumentFindCursor extends DocumentFindCursorFields, Pipeable {
21
+ _tag: "DocumentFindCursor"
22
+ }
23
+
24
+ /** @internal */
25
+ export class DocumentFindCursorImpl extends Data.TaggedClass("DocumentFindCursor")<DocumentFindCursorFields>
26
+ implements DocumentFindCursor
27
+ {
28
+ pipe() {
29
+ return pipeArguments(this, arguments)
30
+ }
16
31
  }
17
32
 
18
33
  export const filter: {
@@ -21,7 +36,7 @@ export const filter: {
21
36
  } = F.dual(
22
37
  (args) => isDocumentFindCursor(args[0]),
23
38
  (cursor: DocumentFindCursor, filter: Filter<Document>): DocumentFindCursor =>
24
- new DocumentFindCursor({ cursor: cursor.cursor.filter(filter) })
39
+ new DocumentFindCursorImpl({ cursor: cursor.cursor.filter(filter) })
25
40
  )
26
41
 
27
42
  export const project: {
@@ -30,7 +45,7 @@ export const project: {
30
45
  } = F.dual(
31
46
  (args) => isDocumentFindCursor(args[0]),
32
47
  (cursor: DocumentFindCursor, value: Document): DocumentFindCursor =>
33
- new DocumentFindCursor({ cursor: cursor.cursor.project(value) })
48
+ new DocumentFindCursorImpl({ cursor: cursor.cursor.project(value) })
34
49
  )
35
50
 
36
51
  export const sort: {
@@ -39,7 +54,7 @@ export const sort: {
39
54
  } = F.dual(
40
55
  (args) => isDocumentFindCursor(args[0]),
41
56
  (cursor: DocumentFindCursor, sort: Sort | string, direction?: SortDirection): DocumentFindCursor =>
42
- new DocumentFindCursor({ cursor: cursor.cursor.sort(sort, direction) })
57
+ new DocumentFindCursorImpl({ cursor: cursor.cursor.sort(sort, direction) })
43
58
  )
44
59
 
45
60
  export const limit: {
@@ -48,13 +63,13 @@ export const limit: {
48
63
  } = F.dual(
49
64
  (args) => isDocumentFindCursor(args[0]),
50
65
  (cursor: DocumentFindCursor, value: number): DocumentFindCursor =>
51
- new DocumentFindCursor({ cursor: cursor.cursor.limit(value) })
66
+ new DocumentFindCursorImpl({ cursor: cursor.cursor.limit(value) })
52
67
  )
53
68
 
54
69
  export const toArray = (cursor: DocumentFindCursor): Effect.Effect<Array<Document>, MongoError.MongoError> =>
55
70
  F.pipe(
56
- Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }),
57
- Effect.catchAll(MongoError.mongoErrorDie<Array<Document>>("toArray error"))
71
+ Effect.promise(() => cursor.cursor.toArray()),
72
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray")))
58
73
  )
59
74
 
60
75
  export const toStream = (
@@ -62,7 +77,7 @@ export const toStream = (
62
77
  ): Stream.Stream<Document, MongoError.MongoError> =>
63
78
  F.pipe(
64
79
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
65
- Stream.catchAll(MongoError.mongoErrorStream<Document>("Unable to read from mongodb cursor"))
80
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream")))
66
81
  )
67
82
 
68
83
  export const typed: {
@@ -71,6 +86,14 @@ export const typed: {
71
86
  } = F.dual((args) => isDocumentFindCursor(args[0]), <A, I = A, R = never>(
72
87
  cursor: DocumentFindCursor,
73
88
  schema: Schema.Schema<A, I, R>
74
- ): FindCursor.FindCursor<A, I, R> => new FindCursor.FindCursor<A, I, R>({ cursor: cursor.cursor, schema }))
89
+ ): FindCursor.FindCursor<A, I, R> => new FindCursor.FindCursorImpl<A, I, R>({ cursor: cursor.cursor, schema }))
90
+
91
+ const isDocumentFindCursor = (x: unknown) => x instanceof DocumentFindCursorImpl
75
92
 
76
- const isDocumentFindCursor = (x: unknown) => x instanceof DocumentFindCursor
93
+ const errorSource = (cursor: DocumentFindCursor, functionName: string) =>
94
+ new MongoError.CollectionErrorSource({
95
+ module: DocumentFindCursorImpl.name,
96
+ functionName,
97
+ db: cursor.cursor.namespace.db,
98
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
99
+ })
package/src/FindCursor.ts CHANGED
@@ -6,17 +6,32 @@ import * as Effect from "effect/Effect"
6
6
  import type * as E from "effect/Either"
7
7
  import * as F from "effect/Function"
8
8
  import type * as ParseResult from "effect/ParseResult"
9
+ import type { Pipeable } from "effect/Pipeable"
10
+ import { pipeArguments } from "effect/Pipeable"
9
11
  import * as Schema from "effect/Schema"
10
12
  import * as Stream from "effect/Stream"
11
13
  import * as Tuple from "effect/Tuple"
12
14
  import type { Document, FindCursor as FindCursor_, Sort, SortDirection } from "mongodb"
13
15
  import type { Filter } from "./internal/filter.js"
16
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
14
17
  import * as MongoError from "./MongoError.js"
15
18
 
16
- export class FindCursor<A, I = A, R = never> extends Data.TaggedClass("FindCursor")<{
19
+ type FindCursorFields<A, I = A, R = never> = {
17
20
  cursor: FindCursor_<unknown>
18
21
  schema: Schema.Schema<A, I, R>
19
- }> {
22
+ }
23
+
24
+ export interface FindCursor<A, I = A, R = never> extends FindCursorFields<A, I, R>, Pipeable {
25
+ _tag: "FindCursor"
26
+ }
27
+
28
+ /** @internal */
29
+ export class FindCursorImpl<A, I = A, R = never> extends Data.TaggedClass("FindCursor")<FindCursorFields<A, I, R>>
30
+ implements FindCursor<A, I, R>
31
+ {
32
+ pipe() {
33
+ return pipeArguments(this, arguments)
34
+ }
20
35
  }
21
36
 
22
37
  export const filter: {
@@ -27,7 +42,7 @@ export const filter: {
27
42
  <A, I extends Document, R>(
28
43
  cursor: FindCursor<A, I, R>,
29
44
  filter: Filter<I>
30
- ): FindCursor<A, I, R> => new FindCursor({ cursor: cursor.cursor.filter(filter), schema: cursor.schema })
45
+ ): FindCursor<A, I, R> => new FindCursorImpl({ cursor: cursor.cursor.filter(filter), schema: cursor.schema })
31
46
  )
32
47
 
33
48
  export const project: {
@@ -46,7 +61,7 @@ export const project: {
46
61
  cursor: FindCursor<A, I, R>,
47
62
  newSchema: Schema.Schema<B, BI, BR>,
48
63
  value: T
49
- ): FindCursor<B, BI, BR> => new FindCursor({ cursor: cursor.cursor.project(value), schema: newSchema })
64
+ ): FindCursor<B, BI, BR> => new FindCursorImpl({ cursor: cursor.cursor.project(value), schema: newSchema })
50
65
  )
51
66
 
52
67
  export const sort: {
@@ -62,7 +77,7 @@ export const sort: {
62
77
  cursor: FindCursor<A, I, R>,
63
78
  sort: Sort | string,
64
79
  direction?: SortDirection
65
- ): FindCursor<A, I, R> => new FindCursor({ cursor: cursor.cursor.sort(sort, direction), schema: cursor.schema })
80
+ ): FindCursor<A, I, R> => new FindCursorImpl({ cursor: cursor.cursor.sort(sort, direction), schema: cursor.schema })
66
81
  )
67
82
 
68
83
  export const limit: {
@@ -71,15 +86,15 @@ export const limit: {
71
86
  } = F.dual(
72
87
  (args) => isFindCursor(args[0]),
73
88
  <A, I, R>(cursor: FindCursor<A, I, R>, value: number): FindCursor<A, I, R> =>
74
- new FindCursor({ cursor: cursor.cursor.limit(value), schema: cursor.schema })
89
+ new FindCursorImpl({ cursor: cursor.cursor.limit(value), schema: cursor.schema })
75
90
  )
76
91
 
77
92
  export const toArray = <A, I, R>(
78
93
  cursor: FindCursor<A, I, R>
79
94
  ): Effect.Effect<Array<A>, MongoError.MongoError | ParseResult.ParseError, R> => {
80
95
  const decode = Schema.decodeUnknown(cursor.schema)
81
- return Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }).pipe(
82
- Effect.catchAll(MongoError.mongoErrorDie<Array<A>>("Unable to get array from mongodb cursor")),
96
+ return Effect.promise(() => cursor.cursor.toArray()).pipe(
97
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray"))),
83
98
  Effect.flatMap(Effect.forEach((x) => decode(x)))
84
99
  )
85
100
  }
@@ -92,8 +107,8 @@ export const toArrayEither = <A, I, R>(
92
107
  R
93
108
  > => {
94
109
  const decode = Schema.decodeUnknown(cursor.schema)
95
- return Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }).pipe(
96
- Effect.catchAll(MongoError.mongoErrorDie<Array<unknown>>("Unable to get array from mongodb cursor")),
110
+ return Effect.promise(() => cursor.cursor.toArray()).pipe(
111
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArrayEither"))),
97
112
  Effect.flatMap(Effect.forEach((x) =>
98
113
  F.pipe(
99
114
  decode(x),
@@ -110,7 +125,7 @@ export const toStream = <A, I, R>(
110
125
  const decode = Schema.decodeUnknown(cursor.schema)
111
126
  return F.pipe(
112
127
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
113
- Stream.catchAll(MongoError.mongoErrorStream<A>("Unable to get stream from mongodb cursor")),
128
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream"))),
114
129
  Stream.mapEffect((x) => decode(x))
115
130
  )
116
131
  }
@@ -121,7 +136,7 @@ export const toStreamEither = <A, I, R>(
121
136
  const decode = Schema.decodeUnknown(cursor.schema)
122
137
  return F.pipe(
123
138
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
124
- Stream.catchAll(MongoError.mongoErrorStream<A>("Unable to get stream either from mongodb cursor")),
139
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStreamEither"))),
125
140
  Stream.mapEffect((x) =>
126
141
  F.pipe(
127
142
  // keep new line
@@ -133,4 +148,12 @@ export const toStreamEither = <A, I, R>(
133
148
  )
134
149
  }
135
150
 
136
- const isFindCursor = (x: unknown): x is FindCursor<unknown> => x instanceof FindCursor
151
+ const isFindCursor = (x: unknown): x is FindCursor<unknown> => x instanceof FindCursorImpl
152
+
153
+ const errorSource = <A, I, R>(cursor: FindCursor<A, I, R>, functionName: string) =>
154
+ new MongoError.CollectionErrorSource({
155
+ module: FindCursorImpl.name,
156
+ functionName,
157
+ db: cursor.cursor.namespace.db,
158
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
159
+ })
@@ -4,11 +4,14 @@
4
4
  import * as Data from "effect/Data"
5
5
  import * as Effect from "effect/Effect"
6
6
  import * as F from "effect/Function"
7
+ import type { Pipeable } from "effect/Pipeable"
8
+ import { pipeArguments } from "effect/Pipeable"
7
9
  import * as Stream from "effect/Stream"
8
10
  import type {
9
11
  CollectionInfo as MongoCollectionInfo,
10
12
  ListCollectionsCursor as MongoListCollectionsCursor
11
13
  } from "mongodb"
14
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
12
15
  import * as MongoError from "./MongoError.js"
13
16
 
14
17
  export type NameOnlyCollectionInfo = Pick<MongoCollectionInfo, "name" | "type">
@@ -16,11 +19,24 @@ export type FullCollectionInfo = MongoCollectionInfo
16
19
 
17
20
  type DefaultCollectionInfo = NameOnlyCollectionInfo | FullCollectionInfo
18
21
 
19
- export class ListCollectionsCursor<
20
- T extends DefaultCollectionInfo = DefaultCollectionInfo
21
- > extends Data.TaggedClass("ListCollectionsCursor")<{
22
+ type ListCollectionsCursorFields<T extends DefaultCollectionInfo = DefaultCollectionInfo> = {
22
23
  cursor: MongoListCollectionsCursor<T>
23
- }> {}
24
+ }
25
+
26
+ export interface ListCollectionsCursor<T extends DefaultCollectionInfo = DefaultCollectionInfo>
27
+ extends ListCollectionsCursorFields<T>, Pipeable
28
+ {
29
+ _tag: "ListCollectionsCursor"
30
+ }
31
+
32
+ /** @internal */
33
+ export class ListCollectionsCursorImpl<
34
+ T extends DefaultCollectionInfo = DefaultCollectionInfo
35
+ > extends Data.TaggedClass("ListCollectionsCursor")<ListCollectionsCursorFields<T>> implements Pipeable {
36
+ pipe() {
37
+ return pipeArguments(this, arguments)
38
+ }
39
+ }
24
40
 
25
41
  export type NameOnlyListCollectionsCursor = ListCollectionsCursor<
26
42
  Pick<MongoCollectionInfo, "name" | "type">
@@ -32,8 +48,8 @@ export const toArray = <T extends DefaultCollectionInfo>(
32
48
  cursor: ListCollectionsCursor<T>
33
49
  ): Effect.Effect<Array<T>, MongoError.MongoError> =>
34
50
  F.pipe(
35
- Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }),
36
- Effect.catchAll(MongoError.mongoErrorDie<Array<T>>(`${cursor._tag}.toArray error`))
51
+ Effect.promise(() => cursor.cursor.toArray()),
52
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray")))
37
53
  )
38
54
 
39
55
  export const toStream = <T extends DefaultCollectionInfo>(
@@ -41,5 +57,13 @@ export const toStream = <T extends DefaultCollectionInfo>(
41
57
  ): Stream.Stream<T, MongoError.MongoError> =>
42
58
  F.pipe(
43
59
  Stream.fromAsyncIterable(cursor.cursor, F.identity),
44
- Stream.catchAll(MongoError.mongoErrorStream<T>(`${cursor._tag}.toStream error`))
60
+ Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream")))
45
61
  )
62
+
63
+ const errorSource = (cursor: ListCollectionsCursor, functionName: string) =>
64
+ new MongoError.CollectionErrorSource({
65
+ module: ListCollectionsCursorImpl.name,
66
+ functionName,
67
+ db: cursor.cursor.namespace.db,
68
+ collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
69
+ })
@@ -6,6 +6,7 @@ import * as F from "effect/Function"
6
6
  import type * as Scope from "effect/Scope"
7
7
  import type { Db, DbOptions, MongoClientOptions } from "mongodb"
8
8
  import { MongoClient as MongoClient_ } from "mongodb"
9
+ import { mongoErrorOrDie } from "./internal/mongo-error.js"
9
10
  import * as MongoError from "./MongoError.js"
10
11
 
11
12
  export type MongoClient = MongoClient_
@@ -15,7 +16,7 @@ export const connect = (
15
16
  options?: MongoClientOptions
16
17
  ): Effect.Effect<MongoClient, MongoError.MongoError> =>
17
18
  Effect.promise(() => MongoClient_.connect(url, options)).pipe(
18
- Effect.catchAll(MongoError.mongoErrorDie<MongoClient_>("connect error"))
19
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource([new URL(url).host], "connect")))
19
20
  )
20
21
 
21
22
  export const close: {
@@ -25,7 +26,7 @@ export const close: {
25
26
  (args) => isMongoClient(args[0]),
26
27
  (client: MongoClient, force?: boolean): Effect.Effect<void, MongoError.MongoError> =>
27
28
  Effect.promise(() => client.close(force)).pipe(
28
- Effect.catchAll(MongoError.mongoErrorDie<void>("close error"))
29
+ Effect.catchAllDefect(mongoErrorOrDie(errorSource(client.options.hosts.map((x) => x.host ?? "NO_HOST"), "close")))
29
30
  )
30
31
  )
31
32
 
@@ -47,3 +48,6 @@ export const db: {
47
48
  )
48
49
 
49
50
  const isMongoClient = (x: unknown) => x instanceof MongoClient_
51
+
52
+ const errorSource = (hosts: Array<string>, functionName: string) =>
53
+ new MongoError.ClientErrorSource({ module: "MongoClient", functionName, hosts })