56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { Todo } from "@todo-tests/common/data"
|
|
import { Array, Context, Effect, Option, Ref, SubscriptionRef } from "effect"
|
|
|
|
|
|
export class TodoRepository extends Context.Tag("TodoRepository")<TodoRepository, Ref.Ref<Todo[]>>() {}
|
|
|
|
export class TodoRepositoryService {
|
|
constructor(
|
|
readonly ref: SubscriptionRef.SubscriptionRef<(Todo & { id: Option.Some<string> })[]>
|
|
) {}
|
|
|
|
get(id: string) {
|
|
return this.ref.get.pipe(
|
|
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<string> }) {
|
|
return Ref.update(this.ref, todos =>
|
|
Array.append(todos, new Todo({
|
|
...todo,
|
|
id: Option.some(""),
|
|
}))
|
|
)
|
|
}
|
|
|
|
update(todo: Todo & { id: Option.Some<string> }) {
|
|
return Effect.gen(this, function*() {
|
|
const index = yield* yield* this.getIndex(todo.id.value)
|
|
yield* Ref.update(this.ref, Array.replace(index, todo))
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
export const createDefaultTodos = TodoRepository.pipe(Effect.flatMap(repo =>
|
|
Ref.update(repo, todos =>
|
|
Array.appendAll(todos, [
|
|
new Todo({
|
|
id: Option.some("1"),
|
|
title: "A test todo",
|
|
content: "Lorem ipsum",
|
|
due: Option.none(),
|
|
completed: false,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
})
|
|
])
|
|
)
|
|
))
|