import { v4 } from "uuid" ; interface Todo { id : string ; text : string ; isCompleted : boolean ; } const ALL_TODOS_KEY = "SUPERMASSIVE_ALL_TODOS" ; export class TodoStorage { localStorage : Storage ; constructor ( localStorage ) { this . localStorage = localStorage ; } getAllTodos ( ) { const existingTodos = this . localStorage . getItem ( ALL_TODOS_KEY ) ; if ( existingTodos ) { return JSON . parse ( existingTodos ) as any as Array < Todo > ; } else { return [ ] ; } } saveTodos ( todos ) { this . localStorage . setItem ( ALL_TODOS_KEY , JSON . stringify ( todos ) ) ; } createTodo ( text ) { const todos = this . getAllTodos ( ) ; const todo = { id : v4 ( ) , text , isCompleted : false , } ; todos . push ( todo ) ; this . saveTodos ( todos ) ; return todo ; } updateTodo ( { id , text , isCompleted , } ) { const todos = this . getAllTodos ( ) ; const todoIndex = findIndex ( todos , ( otherTodo ) => otherTodo . id === id ) ; if ( todoIndex !== - 1 ) { if ( text ) { todos [ todoIndex ] . text = text ; } if ( isCompleted ) { todos [ todoIndex ] . isCompleted = isCompleted ; } this . saveTodos ( todos ) ; } return todos [ todoIndex ] ; } deleteTodo ( id ) { const todos = this . getAllTodos ( ) ; const todoIndex = findIndex ( todos , ( otherTodo ) => otherTodo . id === id ) ; if ( todoIndex !== - 1 ) { todos . splice ( todoIndex , 1 ) ; this . saveTodos ( todos ) ; } } } export type Context = { todoStorage : TodoStorage ; } ; export const resolvers = { Query : { allTodos ( _source , _args , context , _info ) { return context . todoStorage . getAllTodos ( ) ; } , } , Mutation : { createTodo ( _source , { input } , context , _info ) { const result = context . todoStorage . createTodo ( input . text ) ; if ( result != null ) { return { __typename : "CreateTodoSuccess" , todo : result , } ; } else { return { __typename : "CreateTodoFailure" , reason : "haha" , } ; } } , updateTodoText ( _source , { input } , context , _info ) { const result = context . todoStorage . updateTodo ( { id : input . id , text : input . text , } ) ; if ( result != null ) { return { __typename : "UpdateTodoTextSuccess" , todo : result , } ; } else { return { __typename : "UpdateTodoTextFailure" , reason : "haha" , } ; } } , setTodoCompleted ( _source , { input } , context , _info ) { const result = context . todoStorage . updateTodo ( { id : input . id , isCompleted : input . isCompleted , } ) ; if ( result != null ) { return { __typename : "SetTodoCompletedSuccess" , todo : result , } ; } else { return { __typename : "SetTodoCompletedFailure" , reason : "haha" , } ; } } , } , } ; function findIndex < A > ( arr , finder ) { const result = [ ] ; for ( let i = 0 ; i < arr . length ; i ++ ) { if ( finder ( arr [ i ] ) ) { return i ; } } return - 1 ; }