Last active
July 13, 2024 15:59
-
-
Save smhmayboudi/6f76dcf36f0218dbd6565c71206a3d76 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Schema, Serializable} from '@effect/schema'; | |
import {Brand, Console, Effect, HashMap, pipe, Ref} from 'effect'; | |
export type Int = number & Brand.Brand<'Int'>; | |
export const Int = Brand.refined<Int>( | |
n => Number.isInteger(n), | |
n => Brand.error(`expected ${n} to be an integer.`) | |
); | |
export type Positive = number & Brand.Brand<'Positive'>; | |
export const Positive = Brand.refined<Positive>( | |
n => n >= 0, | |
n => Brand.error(`expected ${n} to be positive.`) | |
); | |
export const TodoId = Brand.all(Int, Positive); | |
export type TodoId = Brand.Brand.FromConstructor<typeof TodoId>; | |
export class TodoModelDAO extends Schema.Class<TodoModelDAO>('TodoModelDAO')({ | |
id: pipe(Schema.Number, Schema.fromBrand(TodoId)), | |
title: Schema.String, | |
completed: Schema.Boolean, | |
}) {} | |
export class TodoModelBO extends Schema.Class<TodoModelBO>('TodoModelBO')({ | |
id: pipe(Schema.Number, Schema.fromBrand(TodoId)), | |
title: Schema.String, | |
completed: Schema.Boolean, | |
}) { | |
static FromEncoded = Schema.transform(TodoModelDAO, TodoModelBO, { | |
decode: ( | |
fromA: Schema.Schema.Encoded<typeof TodoModelDAO> | |
): Schema.Schema.Encoded<typeof TodoModelBO> => { | |
console.log('>TodoModelBO.FromEncoded.decode'); | |
return { | |
id: fromA.id, | |
title: fromA.title, | |
completed: fromA.completed, | |
}; | |
}, | |
encode: ( | |
toI: Schema.Schema.Encoded<typeof TodoModelBO> | |
): Schema.Schema.Type<typeof TodoModelDAO> => { | |
console.log('>TodoModelBO.FromEncoded.encode'); | |
return { | |
id: TodoId(toI.id), | |
title: toI.title, | |
completed: toI.completed, | |
}; | |
}, | |
}); | |
// get [Serializable.symbol]() { | |
// return TodoModelBO.FromEncoded; | |
// } | |
} | |
export class TodoModelDTO extends Schema.Class<TodoModelDTO>('TodoModelDTO')({ | |
id: Schema.Number, | |
title: Schema.String, | |
completed: Schema.Number, | |
}) { | |
static FromEncoded = Schema.transform(TodoModelBO, TodoModelDTO, { | |
decode: ( | |
fromA: Schema.Schema.Encoded<typeof TodoModelBO> | |
): Schema.Schema.Encoded<typeof TodoModelDTO> => { | |
console.log('>TodoModelDTO.FromEncoded.decode'); | |
return { | |
id: fromA.id, | |
title: fromA.title, | |
completed: fromA.completed ? 1 : 0, | |
}; | |
}, | |
encode: ( | |
toI: Schema.Schema.Encoded<typeof TodoModelDTO> | |
): Schema.Schema.Type<typeof TodoModelBO> => { | |
console.log('>TodoModelDTO.FromEncoded.encode'); | |
return { | |
id: TodoId(toI.id), | |
title: toI.title, | |
completed: toI.completed === 1, | |
}; | |
}, | |
}); | |
get [Serializable.symbol]() { | |
return TodoModelDTO.FromEncoded; | |
} | |
} | |
const dao = TodoModelDAO.make({ | |
id: TodoId(1), | |
title: 'HI, WHY!?', | |
completed: true, | |
}); | |
console.log('DAO >>>', dao); | |
const bo = Schema.decodeUnknownOption(TodoModelBO.FromEncoded, { | |
errors: 'all', | |
propertyOrder: 'original', | |
onExcessProperty: 'error', | |
exact: false, | |
})(dao); | |
console.log('BO >>>', bo); | |
const app = Effect.gen(function* () { | |
const nextIdRef = yield* Ref.make(TodoId(1)); | |
const todosRef = yield* Ref.make(HashMap.empty<TodoId, TodoModelDAO>()); | |
const createTodo = pipe( | |
Ref.getAndUpdate(nextIdRef, n => TodoId(n + 1)), | |
Effect.flatMap(id => | |
Ref.modify(todosRef, map => { | |
const newTodo = new TodoModelDAO({ | |
id: TodoId(1), | |
title: 'HI, WHY!?', | |
completed: true, | |
}); | |
const updated = HashMap.set(map, newTodo.id, newTodo); | |
return [newTodo.id, updated]; | |
}) | |
) | |
); | |
createTodo.pipe(Effect.runSync); | |
const apple = pipe( | |
// Effect.succeed( | |
// TodoModelDAO.make({ | |
// id: TodoId(1), | |
// title: 'HI, WHY!?', | |
// completed: true, | |
// }) | |
// ), | |
Ref.get(todosRef), | |
Effect.map(HashMap.get(TodoId(1))), | |
Effect.tap(o => Console.log('>>>1', o)), | |
Effect.map( | |
Schema.decodeUnknownOption(TodoModelBO.FromEncoded, { | |
errors: 'all', | |
propertyOrder: 'original', | |
onExcessProperty: 'error', | |
exact: false, | |
}) | |
), | |
Effect.tap(o => Console.log('>>>2', o)) | |
); | |
apple.pipe(Effect.runSync); | |
}); | |
pipe(app, Effect.runFork); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment