1.0.65 • Published 3 months ago

ts-fp-di-mikroorm v1.0.65

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

ts-fp-di-mikroorm

Use MikroORM Entities inside ts-fp-di State and achieve auto persistence in DB

Knowledge requirements

Basic knowledge of ts-fp-di and MikroORM

Get started

Firstly, need to wrap each life cycle of your backend application (each HTTP request/response, handle MQ message, ...) with ts-fp-di-mikroorm Example of middleware for typical Koa application, where each HTTP request will be wrapped:

const orm = await MikroORM.init(
  defineConfig({
    /* DB config */
    entities: [
      /* init MikroORM Entities */
    ],
  })
)

app.use(async (ctx, next) => {
  await wrapTsFpDiMikroorm(orm, async () => {
    return await next()
  })
})

Further, simply use ts-fp-di and MikroORM "as is" in code and auto persistence in DB will "magically" works 🪄 Only need to use em helper for MikroORM, which can help to consider context of appropriate life cycle

Example

import { Entity, PrimaryKey, Property, wrap } from '@mikro-orm/core'
import { em, entityConstructor, onPersist, wrapTsFpDiMikroorm } from 'ts-fp-di-mikroorm'
import { dis, dic } from 'ts-fp-di'

@Entity()
class UserEntity {
  constructor(entity: Partial<UserEntity>) {
    // just little sugar, for avoiding boilerplate this.key = value
    entityConstructor(this, entity)
  }

  @PrimaryKey()
  id!: number

  @Property()
  name!: string

  // service property for deleting Entity, see below
  $forDelete?: boolean
}

const fetchUser = async (id: number) => {
  // `em()` will return MikroORM Entity Manager for appropriate life cycle
  // need use `em()` everywhere, when you want to use MikroORM API
  return em().findOne(UserEntity, { id })
}

// diOnce, dic, diMap also supported
const $user = dis<UserEntity | null>((state, payload) =>
  state ? wrap(state).assign(payload) : payload instanceof UserEntity ? payload : new UserEntity(payload)
)

// Entities can be placed in Array, Promise, Set, Map (as values) and fp-ts Some, Right
// Persistance for them will works
const $users = dic<UserEntity[]>()

// `wrapTsFpDiMikroorm` here just for example
// Need to use `wrapTsFpDiMikroorm` as middleware of your framework, see example above
await wrapTsFpDiMikroorm(orm, async () => {
  // Mutate $user State for futher mutation
  $user({ name: 'Vasya' })
  // Optional hook, which will be called after DB persist
  onPersist(async () => {
    $user() // BTW, $user already contains `id`, because it's already persisted in DB
  })
})

// By the way, user Vasya already persisted in DB!

await wrapTsFpDiMikroorm(orm, async () => {
  $user(await fetchUser(1))
  $user({ name: 'Petya' })
})

// user Vasya realized that he is Petya in DB now

await wrapTsFpDiMikroorm(orm, async () => {
  $user({ id: 1, name: 'Petya', $forUpdate: true })
})

// if you know id, you can update entity without fetching

await wrapTsFpDiMikroorm(orm, async () => {
  $user({ name: 'Petya', $forUpsert: true })
})

// upsert also works, Entity fetching will be happens on flush afterwards

await wrapTsFpDiMikroorm(orm, async () => {
  $user(await fetchUser(1))
  $user({ $noPersist: true })
})

// Persistance to DB ignored

await wrapTsFpDiMikroorm(orm, async () => {
  $user(await fetchUser(1))
  $user({ $forDelete: true })
})

// user Petya go away from DB

await wrapTsFpDiMikroorm(orm, async () => {
  $users([
    new UserEntity({ id: 1, name: 'Petya', $forUpdate: true }),
    new UserEntity({ id: 2, name: 'Vasya', $forUpdate: true }),
    new UserEntity({ id: 3, name: 'Kolya', $forUpdate: true }),
  ])
})

// all company will be persisted, despite the fact that they are in an Array
1.0.65

3 months ago

1.0.63

4 months ago

1.0.58

4 months ago

1.0.56

4 months ago

0.0.54

4 months ago

0.0.52

4 months ago

0.0.40

6 months ago

0.0.33

6 months ago

0.0.47

6 months ago

0.0.36

6 months ago

0.0.25

7 months ago

0.0.50

6 months ago

0.0.27

7 months ago

0.0.29

7 months ago

0.0.18

7 months ago

0.0.14

7 months ago

0.0.12

8 months ago

0.0.9

10 months ago

0.0.5

11 months ago

0.0.3

11 months ago