Skip to content

Commit

Permalink
add withFallback api
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed Oct 25, 2023
1 parent 47c7af7 commit aa3e481
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-donkeys-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect-rx/rx": patch
---

add withFallback api
56 changes: 56 additions & 0 deletions packages/rx/src/Rx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,62 @@ export const family = typeof WeakRef === "undefined" || typeof FinalizationRegis
}
}

/**
* @since 1.0.0
* @category combinators
*/
export const withFallback: {
<E2, A2>(
fallback: Rx<Result.Result<E2, A2>>
): <R extends Rx<Result.Result<any, any>>>(
self: R
) => [R] extends [Writable<infer _, infer RW>]
? Writable<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>, RW>
: Rx<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>>
<R extends Rx<Result.Result<any, any>>, E2, A2>(
self: R,
fallback: Rx<Result.Result<E2, A2>>
): [R] extends [Writable<infer _, infer RW>]
? Writable<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>, RW>
: Rx<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>>
} = dual<
<E2, A2>(
fallback: Rx<Result.Result<E2, A2>>
) => <R extends Rx<Result.Result<any, any>>>(
self: R
) => [R] extends [Writable<infer _, infer RW>]
? Writable<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>, RW>
: Rx<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>>,
<R extends Rx<Result.Result<any, any>>, E2, A2>(
self: R,
fallback: Rx<Result.Result<E2, A2>>
) => [R] extends [Writable<infer _, infer RW>]
? Writable<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>, RW>
: Rx<Result.Result<Result.Result.Failure<Rx.Infer<R>> | E2, Result.Result.Success<Rx.Infer<R>> | A2>>
>(2, (self, fallback) => {
function withFallback(get: Context) {
const result = get(self)
if (result._tag === "Initial" || (result._tag === "Waiting" && result.previous._tag === "Initial")) {
return Result.waiting(Result.noWaiting(get(fallback)))
}
return result
}
return isWritable(self)
? writable(
withFallback,
self.write,
self.refresh ?? function(refresh) {
refresh(self)
}
)
: readable(
withFallback,
self.refresh ?? function(refresh) {
refresh(self)
}
) as any
})

/**
* @since 1.0.0
* @category combinators
Expand Down
16 changes: 16 additions & 0 deletions packages/rx/test/Rx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,22 @@ describe("Rx", () => {
r.set(count, 1)
assert.deepEqual(r.get(count), 1)
})

it("withFallback", async () => {
const count = Rx.effect(() =>
Effect.succeed(1).pipe(
Effect.delay(100)
)
).pipe(
Rx.withFallback(Rx.effect(() => Effect.succeed(0))),
Rx.keepAlive
)
const r = Registry.make()
assert.deepEqual(r.get(count), Result.waiting(Result.success(0)))

await vitest.advanceTimersByTimeAsync(100)
assert.deepEqual(r.get(count), Result.success(1))
})
})

interface Counter {
Expand Down

0 comments on commit aa3e481

Please sign in to comment.