From 53d565e1a1a3dc373d197d97b6ad31d9dad7fb9d Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 22 Sep 2023 15:48:02 +1200 Subject: [PATCH] improve map api types to work with Writable --- .changeset/chilled-ants-dress.md | 5 +++ docs/rx/Result.ts.md | 22 +++++++++++++ docs/rx/Rx.ts.md | 50 ++++++++++++++++++++++++++--- packages/rx/src/Result.ts | 10 ++++++ packages/rx/src/Rx.ts | 54 ++++++++++++++++++++++++++------ 5 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 .changeset/chilled-ants-dress.md diff --git a/.changeset/chilled-ants-dress.md b/.changeset/chilled-ants-dress.md new file mode 100644 index 0000000..c147140 --- /dev/null +++ b/.changeset/chilled-ants-dress.md @@ -0,0 +1,5 @@ +--- +"@effect-rx/rx": patch +--- + +improve map api types to work with Writable diff --git a/docs/rx/Result.ts.md b/docs/rx/Result.ts.md index 25948be..075e5c7 100644 --- a/docs/rx/Result.ts.md +++ b/docs/rx/Result.ts.md @@ -34,6 +34,8 @@ Added in v1.0.0 - [Result (type alias)](#result-type-alias) - [Result (namespace)](#result-namespace) - [Variance (interface)](#variance-interface) + - [Failure (type alias)](#failure-type-alias) + - [Success (type alias)](#success-type-alias) - [Success (interface)](#success-interface) - [Waiting (interface)](#waiting-interface) - [refinements](#refinements) @@ -240,6 +242,26 @@ export interface Variance { Added in v1.0.0 +### Failure (type alias) + +**Signature** + +```ts +export type Failure> = R extends Result ? E : never +``` + +Added in v1.0.0 + +### Success (type alias) + +**Signature** + +```ts +export type Success> = R extends Result ? A : never +``` + +Added in v1.0.0 + ## Success (interface) **Signature** diff --git a/docs/rx/Rx.ts.md b/docs/rx/Rx.ts.md index dc2600c..9c34183 100644 --- a/docs/rx/Rx.ts.md +++ b/docs/rx/Rx.ts.md @@ -43,6 +43,7 @@ Added in v1.0.0 - [Rx (namespace)](#rx-namespace) - [Get (type alias)](#get-type-alias) - [GetResult (type alias)](#getresult-type-alias) + - [Infer (type alias)](#infer-type-alias) - [Mount (type alias)](#mount-type-alias) - [Read (type alias)](#read-type-alias) - [ReadFn (type alias)](#readfn-type-alias) @@ -55,6 +56,8 @@ Added in v1.0.0 - [RxRuntime (interface)](#rxruntime-interface) - [StreamPullResult (type alias)](#streampullresult-type-alias) - [Writable (interface)](#writable-interface) +- [refinements](#refinements) + - [isWritable](#iswritable) - [type ids](#type-ids) - [RefreshableTypeId](#refreshabletypeid) - [RefreshableTypeId (type alias)](#refreshabletypeid-type-alias) @@ -107,7 +110,13 @@ Added in v1.0.0 **Signature** ```ts -export declare const map: { (f: (_: A) => B): (self: Rx) => Rx; (self: Rx, f: (_: A) => B): Rx } +export declare const map: (, B>( + f: (_: Rx.Infer) => B +) => (self: R) => [R] extends [Writable] ? Writable : Rx) & + (, B>( + self: R, + f: (_: Rx.Infer) => B + ) => [R] extends [Writable] ? Writable : Rx) ``` Added in v1.0.0 @@ -117,10 +126,19 @@ Added in v1.0.0 **Signature** ```ts -export declare const mapResult: (( - f: (_: A) => B -) => (self: Rx>) => Rx>) & - ((self: Rx>, f: (_: A) => B) => Rx>) +export declare const mapResult: (>, B>( + f: (_: Result.Result.Success>) => B +) => ( + self: R +) => [R] extends [Writable] + ? Writable>, B>, RW> + : Rx>, B>>) & + (>, B>( + self: R, + f: (_: Result.Result.Success>) => B + ) => [R] extends [Writable] + ? Writable>, B>, RW> + : Rx>, B>>) ``` Added in v1.0.0 @@ -420,6 +438,16 @@ export type GetResult = (rx: Rx>) => Exit.Exit> = T extends Rx ? A : never +``` + +Added in v1.0.0 + ### Mount (type alias) **Signature** @@ -555,6 +583,18 @@ export interface Writable extends Rx { Added in v1.0.0 +# refinements + +## isWritable + +**Signature** + +```ts +export declare const isWritable: (rx: Rx) => rx is Writable +``` + +Added in v1.0.0 + # type ids ## RefreshableTypeId diff --git a/packages/rx/src/Result.ts b/packages/rx/src/Result.ts index e7470db..820e9ee 100644 --- a/packages/rx/src/Result.ts +++ b/packages/rx/src/Result.ts @@ -46,6 +46,16 @@ export declare namespace Result { readonly A: (_: never) => A } } + + /** + * @since 1.0.0 + */ + export type Success> = R extends Result ? A : never + + /** + * @since 1.0.0 + */ + export type Failure> = R extends Result ? E : never } const ResultProto = Data.struct({ diff --git a/packages/rx/src/Rx.ts b/packages/rx/src/Rx.ts index 5bf18d4..0eda615 100644 --- a/packages/rx/src/Rx.ts +++ b/packages/rx/src/Rx.ts @@ -107,6 +107,11 @@ export declare namespace Rx { export type Subscribe = (rx: Rx, f: (_: A) => void, options?: { readonly immediate?: boolean }) => () => void + + /** + * @since 1.0.0 + */ + export type Infer> = T extends Rx ? A : never } /** @@ -211,6 +216,12 @@ function defaultRefresh(this: Rx, f: any) { f(this) } +/** + * @since 1.0.0 + * @category refinements + */ +export const isWritable = (rx: Rx): rx is Writable => WritableTypeId in rx + /** * @since 1.0.0 * @category constructors @@ -744,22 +755,45 @@ export const initialValue: { * @since 1.0.0 * @category combinators */ -export const map: { - (f: (_: A) => B): (self: Rx) => Rx - (self: Rx, f: (_: A) => B): Rx -} = dual< - (f: (_: A) => B) => (self: Rx) => Rx, - (self: Rx, f: (_: A) => B) => Rx ->(2, (self, f) => readable((get) => f(get(self)))) +export const map = dual< + , B>( + f: (_: Rx.Infer) => B + ) => (self: R) => [R] extends [Writable] ? Writable : Rx, + , B>( + self: R, + f: (_: Rx.Infer) => B + ) => [R] extends [Writable] ? Writable : Rx +>( + 2, + ((self: Rx, f: (_: A) => B): Rx => + isWritable(self) + ? writable((get) => f(get(self)), function(ctx, value) { + ctx.set(self, value) + }, function(refresh) { + refresh(self) + }) + : readable((get) => f(get(self)), function(refresh) { + refresh(self) + })) as any +) /** * @since 1.0.0 * @category combinators */ export const mapResult = dual< - (f: (_: A) => B) => (self: Rx>) => Rx>, - (self: Rx>, f: (_: A) => B) => Rx> ->(2, (self, f) => map(self, Result.map(f))) + >, B>( + f: (_: Result.Result.Success>) => B + ) => ( + self: R + ) => [R] extends [Writable] ? Writable>, B>, RW> + : Rx>, B>>, + >, B>( + self: R, + f: (_: Result.Result.Success>) => B + ) => [R] extends [Writable] ? Writable>, B>, RW> + : Rx>, B>> +>(2, (self, f) => map(self, Result.map(f)) as any) /** * @since 1.0.0