diff --git a/core/js/src/main/scala/works/iterative/core/service/impl/JsStorageRepository.scala b/core/js/src/main/scala/works/iterative/core/service/impl/JsStorageRepository.scala new file mode 100644 index 0000000..0582cb5 --- /dev/null +++ b/core/js/src/main/scala/works/iterative/core/service/impl/JsStorageRepository.scala @@ -0,0 +1,25 @@ +package works.iterative.core.service.impl + +import org.scalajs.dom.Storage +import works.iterative.core.service.Repository +import zio.* +import zio.json.* + +// TODO: improve error reporting on generic repositories +// This is good just for prototypes +class JsStorageRepository[Value: JsonCodec](storage: Storage) + extends Repository[String, Value]: + + override def find(id: String): UIO[Option[Value]] = { + for + raw <- ZIO.attemptBlocking(Option(storage.getItem(id))) + data <- ZIO.foreach(raw) { r => + ZIO + .fromEither(r.fromJson[Value]) + .mapError(_ => new RuntimeException(s"Failed to parse: ${raw}")) + } + yield data + }.orDie + + override def save(key: String, value: Value): UIO[Unit] = + ZIO.attemptBlocking(storage.setItem(key, value.toJson)).orDie diff --git a/core/js/src/main/scala/works/iterative/core/service/impl/JsStorageRepository.scala b/core/js/src/main/scala/works/iterative/core/service/impl/JsStorageRepository.scala new file mode 100644 index 0000000..0582cb5 --- /dev/null +++ b/core/js/src/main/scala/works/iterative/core/service/impl/JsStorageRepository.scala @@ -0,0 +1,25 @@ +package works.iterative.core.service.impl + +import org.scalajs.dom.Storage +import works.iterative.core.service.Repository +import zio.* +import zio.json.* + +// TODO: improve error reporting on generic repositories +// This is good just for prototypes +class JsStorageRepository[Value: JsonCodec](storage: Storage) + extends Repository[String, Value]: + + override def find(id: String): UIO[Option[Value]] = { + for + raw <- ZIO.attemptBlocking(Option(storage.getItem(id))) + data <- ZIO.foreach(raw) { r => + ZIO + .fromEither(r.fromJson[Value]) + .mapError(_ => new RuntimeException(s"Failed to parse: ${raw}")) + } + yield data + }.orDie + + override def save(key: String, value: Value): UIO[Unit] = + ZIO.attemptBlocking(storage.setItem(key, value.toJson)).orDie diff --git a/core/shared/src/main/scala/works/iterative/core/Codecs.scala b/core/shared/src/main/scala/works/iterative/core/Codecs.scala new file mode 100644 index 0000000..00b64a8 --- /dev/null +++ b/core/shared/src/main/scala/works/iterative/core/Codecs.scala @@ -0,0 +1,16 @@ +package works.iterative.core + +import zio.json.* + +trait Codecs: + given JsonCodec[Email] = + JsonCodec.string.transformOrFail( + Email(_).toEitherWith(_ => "Error parsing email"), + _.value + ) + given JsonCodec[PlainMultiLine] = JsonCodec.string.transformOrFail( + PlainMultiLine(_).toEitherWith(_ => "Error parsing PlainMultiLine"), + _.asString + ) + +object Codecs extends Codecs