Skip to content

Commit b63c866

Browse files
committed
services: create high-level builder module DbInstance (#36)
The name is TBC, but the behaviour is what we want to focus on right now
1 parent 3fa084b commit b63c866

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as DbInstance from "@effect-mongodb/services/DbInstance"
2+
import * as DbService from "@effect-mongodb/services/DbService"
3+
import * as Collection from "effect-mongodb/Collection"
4+
import * as Db from "effect-mongodb/Db"
5+
import * as FindCursor from "effect-mongodb/FindCursor"
6+
import * as Config from "effect/Config"
7+
import * as Effect from "effect/Effect"
8+
import * as Schema from "effect/Schema"
9+
10+
const Todo = Schema.Struct({
11+
userId: Schema.Number,
12+
id: Schema.Number,
13+
title: Schema.String,
14+
completed: Schema.Boolean
15+
})
16+
17+
const MyDb = DbService.Tag("MyDb")
18+
19+
const program = Effect.gen(function*() {
20+
const db = yield* MyDb
21+
const sourceCollection = Db.collection(db, "source", Todo)
22+
const destinationCollection = Db.collection(db, "destination", Todo)
23+
24+
const items = yield* Collection.find(sourceCollection).pipe(FindCursor.toArray)
25+
26+
yield* Collection.insertMany(destinationCollection, items)
27+
})
28+
29+
/*** main.ts ***/
30+
31+
const MyDbLive = DbInstance.layerEffect(
32+
MyDb,
33+
Effect.gen(function*() {
34+
const databaseName = yield* Config.string("MONGO_DATABASE_NAME")
35+
const clientUrl = yield* Config.string("MONGO_CONNECTION_STRING")
36+
return {
37+
database: { name: databaseName },
38+
client: { url: clientUrl, timeoutMS: 5000 }
39+
}
40+
})
41+
)
42+
43+
await program.pipe(
44+
Effect.provide(MyDbLive),
45+
Effect.runPromise
46+
)

packages/services/src/DbInstance.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @since 0.0.1
3+
*/
4+
import type * as MongoClient from "effect-mongodb/MongoClient"
5+
import * as Effect from "effect/Effect"
6+
import * as F from "effect/Function"
7+
import * as Layer from "effect/Layer"
8+
import type { DbOptions } from "mongodb"
9+
import * as DbService from "./DbService.js"
10+
import * as MongoClientService from "./MongoClientService.js"
11+
12+
type DbInstanceOptions = {
13+
database: DbOptions & { name: string }
14+
client: MongoClient.MongoClientScopedOptions & { url: string }
15+
}
16+
17+
export const layerEffect = <DbK extends string, E = never, R = never>(
18+
dbTag: DbService.TagType<DbK>,
19+
options: Effect.Effect<DbInstanceOptions, E, R>
20+
) =>
21+
F.pipe(
22+
options,
23+
Effect.map((options) => layer(dbTag, options)),
24+
Layer.unwrapEffect
25+
)
26+
27+
export const layer = <DbK extends string>(
28+
dbTag: DbService.TagType<DbK>,
29+
options: DbInstanceOptions
30+
) => {
31+
const { name: databaseName, ...databaseOptions } = options.database
32+
const { url: clientUrl, ...clientOptions } = options.client
33+
34+
const dbLayer = DbService.layer(dbTag, DefaultMongoClient, databaseName, databaseOptions)
35+
const defaultClientLayer = MongoClientService.layer(DefaultMongoClient, clientUrl, clientOptions)
36+
return dbLayer.pipe(Layer.provide(defaultClientLayer))
37+
}
38+
39+
const DefaultMongoClient = MongoClientService.Tag("@effect-mongodb/services/DefaultMongoClient")

packages/services/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* @since 0.0.1
3+
*/
4+
export * as DbInstance from "./DbInstance.js"
5+
16
/**
27
* @since 0.0.1
38
*/

0 commit comments

Comments
 (0)