From ade042e5b18194824aa0599d24484f0c79484943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 28 Jun 2024 22:33:40 +0200 Subject: [PATCH] TodoRepository work --- packages/server/src/TodoRepository.ts | 53 +++++++++++++++++++++------ 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/packages/server/src/TodoRepository.ts b/packages/server/src/TodoRepository.ts index 3411103..3e65fbb 100644 --- a/packages/server/src/TodoRepository.ts +++ b/packages/server/src/TodoRepository.ts @@ -1,9 +1,10 @@ import { Todo } from "@todo-tests/common/data" -import { Array, Context, Effect, Option, Ref, SubscriptionRef } from "effect" +import { Array, Context, Data, Effect, Option, Ref, SubscriptionRef } from "effect" export class TodoRepository extends Context.Tag("TodoRepository")>() {} + export class TodoRepositoryService { constructor( readonly ref: SubscriptionRef.SubscriptionRef<(Todo & { id: Option.Some })[]> @@ -14,29 +15,59 @@ export class TodoRepositoryService { Effect.map(Array.findFirst(todo => todo.id.value === id)) ) } + getIndex(id: string) { return this.ref.get.pipe( Effect.map(Array.findFirstIndex(todo => todo.id.value === id)) ) } - add(todo: Todo & { id: Option.None }) { - return Ref.update(this.ref, todos => - Array.append(todos, new Todo({ - ...todo, - id: Option.some(""), - })) - ) + add(todo: Todo) { + return Effect.gen(this, function*() { + if (Option.isSome(todo.id)) + return yield* Effect.fail(new TodoHasID({ todo })) + + yield* Ref.update(this.ref, todos => + Array.append(todos, new Todo({ + ...todo, + id: Option.some(""), + }) as Todo & { id: Option.Some }) + ) + }) } - update(todo: Todo & { id: Option.Some }) { + update(todo: Todo) { return Effect.gen(this, function*() { - const index = yield* yield* this.getIndex(todo.id.value) - yield* Ref.update(this.ref, Array.replace(index, todo)) + if (Option.isNone(todo.id)) + return yield* Effect.fail(new TodoHasNoID({ todo })) + + yield* Ref.update(this.ref, Array.replace( + yield* yield* this.getIndex(todo.id.value), + todo as Todo & { id: Option.Some }, + )) + }) + } + + remove(todo: Todo) { + return Effect.gen(this, function*() { + if (Option.isNone(todo.id)) + return yield* Effect.fail(new TodoHasNoID({ todo })) + + yield* Ref.update(this.ref, Array.remove( + yield* yield* this.getIndex(todo.id.value) + )) }) } } +export class TodoHasID extends Data.TaggedError("TodoHasID")<{ + todo: Todo +}> {} + +export class TodoHasNoID extends Data.TaggedError("TodoHasNoID")<{ + todo: Todo +}> {} + export const createDefaultTodos = TodoRepository.pipe(Effect.flatMap(repo => Ref.update(repo, todos =>