// TODO: Convert to effect/core /* eslint-disable @typescript-eslint/ban-types */ import { Tagged } from "@effect-ts/core/Case" export { matchTag } from "@effect-ts/core/Utils" export class Initial extends Tagged("Initial")<{}> {} export class Loading extends Tagged("Loading")<{}> {} export class Refreshing extends Tagged("Refreshing")<{ readonly current: Either readonly previous: Opt }> { static succeed(a: A) { return new Refreshing({ current: Either(a), previous: Opt.none }) } static fail(e: E, previous?: A) { return new Refreshing({ current: Either.left(e), previous: previous === undefined ? Opt.none : Opt(previous) }) } static fromDone(d: Done) { return new Refreshing(d) } } export class Done extends Tagged("Done")<{ readonly current: Either readonly previous: Opt }> { static succeed(this: void, a: A) { return new Done({ current: Either(a), previous: Opt.none }) } static fail(this: void, e: E, previous?: A) { return new Done({ current: Either.left(e), previous: previous === undefined ? Opt.none : Opt(previous) }) } static refresh(d: Done) { return new Refreshing(d) } } /** * @tsplus type QueryResult */ export type QueryResult = Initial | Loading | Refreshing | Done type Result = Omit, "current"> | Omit, "current"> /** * @tsplus fluent QueryResult isSuccess */ export function isSuccess( qr: QueryResult ): qr is Result & { current: Right } { return qr.hasValue() && qr.current.isRight() } /** * @tsplus fluent QueryResult hasValue */ export function hasValue( qr: QueryResult ): qr is Done | Refreshing { return qr.isDone() || qr.isRefreshing() } /** * @tsplus fluent QueryResult isRefreshing */ export function isRefreshing( qr: QueryResult ): qr is Refreshing { return qr._tag === "Refreshing" } /** * @tsplus fluent QueryResult isDone */ export function isDone( qr: QueryResult ): qr is Done { return qr._tag === "Done" } /** * @tsplus fluent QueryResult isInitializing */ export function isInitializing( qr: QueryResult ): qr is Initial | Loading { return qr._tag === "Initial" || qr._tag === "Loading" } /** * @tsplus fluent QueryResult isFailed */ export function isFailed( qr: QueryResult ): qr is Result & { current: Left } { return qr.hasValue() && qr.current.isLeft() } export type ResultTuple = readonly [result: Result, refresh: () => void] export type QueryResultTuple = ResultTuple> export const { fail, succeed } = Done /** * @tsplus getter effect/io/Effect asQueryResult */ export function queryResult( self: Effect ): Effect> { return self.match(fail, succeed) }