Effect CommunityEC
Effect Communityโ€ข17mo agoโ€ข
28 replies
zougi

nested runtimes

For a bit of context I'm developing an app where I can create Pages of a website and store them in sqlite

so far I have the page creation working, tests passing but now I want to implement undo/redo. and ideally I would like to be able to group actions in order for instance to add two pages in the same transaction

here is the code I have so far

const PageCommandsLive = Layer.mergeAll(
  CreatePageCommand.Live,
  ...
)

const runWithContext = async <T, K>(
  method: Effect.Effect<
    T,
    K,
    | CreatePageCommand
    | ...
  >,
) => {
  const DbLive = Layer.succeed(DbTag, db)
  const pageRepository = PageRepository.Live.pipe(Layer.provide(DbLive))
  const layers = PageCommandsLive.pipe(Layer.provide(pageRepository))
  const runtime = ManagedRuntime.make(layers)

  const result = await runtime.runPromise(method)
  await runtime.dispose()
  return result
}


and here is the CreatePageCommand

import { Effect, Layer } from 'effect'
import type { PageModelType } from '../../domain/PageModel'
import PageRepository from '../../infrastructure/PageRepository'

const make = Effect.gen(function* CreatePageCommandGen(_) {
  const { insertPage } = yield* _(PageRepository)

  return {
    command: (newPage: PageModelType) =>
      Effect.gen(function* commandGen() {
        const pageId = yield* insertPage(newPage)
        return pageId
      }),
  } // satisfies Command
})

export default class CreatePageCommand extends Effect.Tag(
  '@command/page/create',
)<CreatePageCommand, Effect.Effect.Success<typeof make>>() {
  static Live = Layer.effect(this, make)
}


and I call it like this

  await runWithContext(
    CreatePageCommand.command({
      pageId,
      title: 'homepage',
      appId: 'app_id',
    }),
  )


this works but it does not support undo/redo nor grouping commands

๐Ÿงต๐Ÿ‘‡
Was this page helpful?