Skip to content

Commit

Permalink
add Rx.debounce
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed May 10, 2024
1 parent 40ba57c commit cf29609
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-trains-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect-rx/rx": patch
---

add Rx.debounce
45 changes: 40 additions & 5 deletions docs/rx/Rx.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ Added in v1.0.0
- [batching](#batching)
- [batch](#batch)
- [combinators](#combinators)
- [debounce](#debounce)
- [initialValue](#initialvalue)
- [keepAlive](#keepalive)
- [map](#map)
- [mapResult](#mapresult)
- [refreshable](#refreshable)
- [setIdleTTL](#setidlettl)
- [transform](#transform)
- [withFallback](#withfallback)
- [withLabel](#withlabel)
- [constructors](#constructors)
Expand Down Expand Up @@ -94,6 +96,19 @@ Added in v1.0.0
# combinators
## debounce
**Signature**
```ts
export declare const debounce: {
(duration: Duration.DurationInput): <A extends Rx<any>>(self: A) => A
<A extends Rx<any>>(self: A, duration: Duration.DurationInput): A
}
```
Added in v1.0.0
## initialValue
**Signature**
Expand Down Expand Up @@ -122,13 +137,15 @@ Added in v1.0.0
**Signature**
```ts
export declare const map: (<R extends Rx<any>, B>(
f: (_: Rx.Infer<R>) => B
) => (self: R) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>) &
(<R extends Rx<any>, B>(
export declare const map: {
<R extends Rx<any>, B>(
f: (_: Rx.Infer<R>) => B
): (self: R) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
<R extends Rx<any>, B>(
self: R,
f: (_: Rx.Infer<R>) => B
) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>)
): [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
}
```
Added in v1.0.0
Expand Down Expand Up @@ -180,6 +197,24 @@ export declare const setIdleTTL: {
Added in v1.0.0
## transform
**Signature**
```ts
export declare const transform: {
<R extends Rx<any>, B>(
f: (get: Context) => B
): (self: R) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
<R extends Rx<any>, B>(
self: R,
f: (get: Context) => B
): [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
}
```
Added in v1.0.0
## withFallback
**Signature**
Expand Down
72 changes: 61 additions & 11 deletions packages/rx/src/Rx.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* @since 1.0.0
*/
import type { Context } from "effect"
import { NoSuchElementException } from "effect/Cause"
import * as Chunk from "effect/Chunk"
import * as Duration from "effect/Duration"
Expand Down Expand Up @@ -1143,33 +1142,52 @@ export const initialValue: {
* @since 1.0.0
* @category combinators
*/
export const map = dual<
export const transform: {
<R extends Rx<any>, B>(
f: (_: Rx.Infer<R>) => B
) => (self: R) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>,
f: (get: Context) => B
): (self: R) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
<R extends Rx<any>, B>(
self: R,
f: (_: Rx.Infer<R>) => B
) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
>(
f: (get: Context) => B
): [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
} = dual(
2,
(<A, B>(self: Rx<A>, f: (_: A) => B): Rx<B> =>
(<A, B>(self: Rx<A>, f: (get: Context) => B): Rx<B> =>
isWritable(self)
? writable(
(get) => f(get(self)),
self.write as any,
f,
function(ctx, value) {
ctx.set(self, value)
},
self.refresh ?? function(refresh) {
refresh(self)
}
)
: readable(
(get) => f(get(self)),
f,
self.refresh ?? function(refresh) {
refresh(self)
}
)) as any
)

/**
* @since 1.0.0
* @category combinators
*/
export const map: {
<R extends Rx<any>, B>(
f: (_: Rx.Infer<R>) => B
): (self: R) => [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
<R extends Rx<any>, B>(
self: R,
f: (_: Rx.Infer<R>) => B
): [R] extends [Writable<infer _, infer RW>] ? Writable<B, RW> : Rx<B>
} = dual(
2,
<A, B>(self: Rx<A>, f: (_: A) => B): Rx<B> => transform(self, (get) => f(get(self)))
)

/**
* @since 1.0.0
* @category combinators
Expand All @@ -1192,6 +1210,38 @@ export const mapResult: {
): [R] extends [Writable<infer _, infer RW>] ? Writable<Result.Result<B, Result.Result.InferE<Rx.Infer<R>>>, RW>
: Rx<Result.Result<B, Result.Result.InferE<Rx.Infer<R>>>> => map(self, Result.map(f)))

/**
* @since 1.0.0
* @category combinators
*/
export const debounce: {
(duration: Duration.DurationInput): <A extends Rx<any>>(self: A) => A
<A extends Rx<any>>(self: A, duration: Duration.DurationInput): A
} = dual(
2,
<A>(self: Rx<A>, duration: Duration.DurationInput): Rx<A> => {
const millis = Duration.toMillis(duration)
return transform(self, function(get) {
let timeout: number | undefined
let value = get.once(self)
function update() {
get.setSelfSync(get.once(self))
}
get.addFinalizer(function() {
if (timeout !== undefined) {
clearTimeout(timeout)
}
})
get.subscribe(self, function(val) {
value = val
if (timeout) return
setTimeout(update, millis)
})
return value
})
}
)

/**
* @since 1.0.0
* @category batching
Expand Down

0 comments on commit cf29609

Please sign in to comment.