Chunk instead of Array

This commit is contained in:
Julien Valverdé
2024-07-09 00:12:22 +02:00
parent e88a6f7b1c
commit fb9ce1bb67
2 changed files with 21 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
import { Todo, type IdentifiedTodo } from "@todo-tests/common/data" import { Todo, type IdentifiedTodo } from "@todo-tests/common/data"
import { Array, Context, Data, Effect, Equal, Layer, Option, Order, Ref, SubscriptionRef, flow } from "effect" import { Chunk, Context, Data, Effect, Equal, Layer, Option, Order, Ref, SubscriptionRef, flow } from "effect"
import crypto from "node:crypto" import crypto from "node:crypto"
@@ -7,7 +7,7 @@ export class TodoRepository extends Context.Tag("TodoRepository")<TodoRepository
export module TodoRepository { export module TodoRepository {
export const Live = Layer.effect(TodoRepository, export const Live = Layer.effect(TodoRepository,
SubscriptionRef.make(Array.empty<IdentifiedTodo>()).pipe( SubscriptionRef.make(Chunk.empty<IdentifiedTodo>()).pipe(
Effect.map(ref => new TodoRepositoryService(ref)) Effect.map(ref => new TodoRepositoryService(ref))
) )
) )
@@ -17,19 +17,19 @@ export module TodoRepository {
export class TodoRepositoryService { export class TodoRepositoryService {
constructor( constructor(
readonly todos: SubscriptionRef.SubscriptionRef<IdentifiedTodo[]> readonly todos: SubscriptionRef.SubscriptionRef<Chunk.Chunk<IdentifiedTodo>>
) {} ) {}
getByID(id: string) { getByID(id: string) {
return this.todos.get.pipe( return this.todos.get.pipe(
Effect.map(Array.findFirst(todo => Equal.equals(todo.id.value, id))) Effect.map(Chunk.findFirst(todo => Equal.equals(todo.id.value, id)))
) )
} }
getIndexByID(id: string) { getIndexByID(id: string) {
return this.todos.get.pipe( return this.todos.get.pipe(
Effect.map(Array.findFirstIndex(todo => Equal.equals(todo.id.value, id))) Effect.map(Chunk.findFirstIndex(todo => Equal.equals(todo.id.value, id)))
) )
} }
@@ -42,7 +42,7 @@ export class TodoRepositoryService {
const id: string = crypto.randomUUID() const id: string = crypto.randomUUID()
yield* Ref.update(this.todos, flow( yield* Ref.update(this.todos, flow(
Array.append(new Todo({ Chunk.append(new Todo({
...todo, ...todo,
id: Option.some(id), id: Option.some(id),
}) as IdentifiedTodo), }) as IdentifiedTodo),
@@ -61,7 +61,7 @@ export class TodoRepositoryService {
return yield* Effect.fail(new TodoHasNoID({ todo })) return yield* Effect.fail(new TodoHasNoID({ todo }))
yield* Ref.update(this.todos, flow( yield* Ref.update(this.todos, flow(
Array.replace( Chunk.replace(
yield* yield* this.getIndexByID(todo.id.value), yield* yield* this.getIndexByID(todo.id.value),
todo as IdentifiedTodo, todo as IdentifiedTodo,
), ),
@@ -78,7 +78,7 @@ export class TodoRepositoryService {
return yield* Effect.fail(new TodoHasNoID({ todo })) return yield* Effect.fail(new TodoHasNoID({ todo }))
yield* Ref.update(this.todos, flow( yield* Ref.update(this.todos, flow(
Array.remove( Chunk.remove(
yield* yield* this.getIndexByID(todo.id.value) yield* yield* this.getIndexByID(todo.id.value)
), ),
updateTodosOrder, updateTodosOrder,
@@ -88,11 +88,14 @@ export class TodoRepositoryService {
} }
const sortTodos = Array.sortBy<IdentifiedTodo[]>( const sortTodos = Chunk.sort<IdentifiedTodo>(
Order.mapInput(Order.number, todo => todo.order) Order.mapInput(Order.number, todo => todo.order)
) )
const updateTodosOrder = Array.map<IdentifiedTodo[], IdentifiedTodo>((todo, order) => const updateTodosOrder = Chunk.map<
Chunk.Chunk<IdentifiedTodo>,
IdentifiedTodo
>((todo, order) =>
new Todo({ ...todo, order }, { disableValidation: true }) as IdentifiedTodo new Todo({ ...todo, order }, { disableValidation: true }) as IdentifiedTodo
) )

View File

@@ -1,11 +1,15 @@
import { Schema as S } from "@effect/schema" import { Schema as S } from "@effect/schema"
import { JsonifiableTodo } from "@todo-tests/common/data" import { JsonifiableTodo } from "@todo-tests/common/data"
import { Effect } from "effect" import { Chunk, Effect } from "effect"
import { TodoRepository } from "../../TodoRepository" import { TodoRepository } from "../../TodoRepository"
import { TRPCBuilder } from "../../trpc/TRPCBuilder" import { TRPCBuilder } from "../../trpc/TRPCBuilder"
import { RPCProcedureBuilder } from "../procedures/RPCProcedureBuilder" import { RPCProcedureBuilder } from "../procedures/RPCProcedureBuilder"
const encodeTodos = S.encode(S.Array(JsonifiableTodo))
const encodeOptionalTodo = S.encode(S.OptionFromNullOr(JsonifiableTodo))
export const todosRouter = Effect.gen(function*() { export const todosRouter = Effect.gen(function*() {
const t = yield* TRPCBuilder const t = yield* TRPCBuilder
const procedure = yield* RPCProcedureBuilder const procedure = yield* RPCProcedureBuilder
@@ -15,8 +19,8 @@ export const todosRouter = Effect.gen(function*() {
.query(({ ctx }) => ctx.run(Effect.gen(function*() { .query(({ ctx }) => ctx.run(Effect.gen(function*() {
const todos = yield* TodoRepository const todos = yield* TodoRepository
return yield* S.encode(S.Array(JsonifiableTodo))( return yield* encodeTodos(
yield* todos.todos.get Chunk.toReadonlyArray(yield* todos.todos.get)
) )
}))), }))),
@@ -25,7 +29,7 @@ export const todosRouter = Effect.gen(function*() {
.query(({ ctx, input }) => ctx.run(Effect.gen(function*() { .query(({ ctx, input }) => ctx.run(Effect.gen(function*() {
const todos = yield* TodoRepository const todos = yield* TodoRepository
return yield* S.encode(S.OptionFromNullOr(JsonifiableTodo))( return yield* encodeOptionalTodo(
yield* todos.getByID(input) yield* todos.getByID(input)
) )
}))), }))),