From b00fa8d6cf06c0eeda5587f549ad712d2d7cbc58 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 9 Nov 2023 16:25:15 +1300 Subject: [PATCH] allow context in Rx.runtime --- .changeset/lemon-readers-tickle.md | 6 ++++++ docs/rx-react/index.ts.md | 4 ++-- docs/rx/Rx.ts.md | 22 ++++++++++---------- packages/rx-react/src/index.ts | 32 ++++++++++-------------------- packages/rx/src/Rx.ts | 30 ++++++++++++++-------------- packages/rx/test/Rx.test.ts | 6 +++--- 6 files changed, 47 insertions(+), 53 deletions(-) create mode 100644 .changeset/lemon-readers-tickle.md diff --git a/.changeset/lemon-readers-tickle.md b/.changeset/lemon-readers-tickle.md new file mode 100644 index 0000000..02847b3 --- /dev/null +++ b/.changeset/lemon-readers-tickle.md @@ -0,0 +1,6 @@ +--- +"@effect-rx/rx-react": minor +"@effect-rx/rx": minor +--- + +allow context in Rx.runtime diff --git a/docs/rx-react/index.ts.md b/docs/rx-react/index.ts.md index 72e58ae..26bceef 100644 --- a/docs/rx-react/index.ts.md +++ b/docs/rx-react/index.ts.md @@ -144,7 +144,7 @@ Added in v1.0.0 export declare const useRxSuspense: ( rx: Rx.Rx>, options?: { readonly suspendOnWaiting?: boolean } -) => { readonly isWaiting: boolean; readonly value: any } +) => any ``` Added in v1.0.0 @@ -157,7 +157,7 @@ Added in v1.0.0 export declare const useRxSuspenseSuccess: ( rx: Rx.Rx>, options?: { readonly suspendOnWaiting?: boolean } -) => { readonly isWaiting: boolean; readonly value: A } +) => Result.Success ``` Added in v1.0.0 diff --git a/docs/rx/Rx.ts.md b/docs/rx/Rx.ts.md index 98bec0a..fe30f69 100644 --- a/docs/rx/Rx.ts.md +++ b/docs/rx/Rx.ts.md @@ -285,7 +285,7 @@ Added in v1.0.0 ```ts export declare const runtime: { ( - layer: Layer.Layer, + create: (get: Context) => Layer.Layer, options?: { readonly autoDispose?: boolean readonly idleTTL?: Duration.DurationInput @@ -293,7 +293,7 @@ export declare const runtime: { } ): RxRuntime ( - layer: Layer.Layer, + create: (get: Context) => Layer.Layer, options?: | { readonly autoDispose?: boolean | undefined @@ -441,20 +441,20 @@ Added in v1.0.0 ```ts export interface Context { (rx: Rx): A - readonly get: Rx.Get - readonly result: Rx.GetResult - readonly once: Rx.Get + readonly get: (rx: Rx) => A + readonly result: (rx: Rx>) => Exit.Exit + readonly once: (rx: Rx) => A readonly addFinalizer: (f: () => void) => void readonly mount: (rx: Rx) => void - readonly refreshSync: Rx.RefreshRxSync - readonly refresh: Rx.RefreshRx + readonly refreshSync: (rx: Rx & Refreshable) => void + readonly refresh: (rx: Rx & Refreshable) => Effect.Effect readonly refreshSelfSync: () => void readonly refreshSelf: Effect.Effect readonly self: () => Option.Option readonly setSelfSync: (a: A) => void readonly setSelf: (a: A) => Effect.Effect - readonly setSync: Rx.Set - readonly set: Rx.SetEffect + readonly setSync: (rx: Writable, value: W) => void + readonly set: (rx: Writable, value: W) => Effect.Effect readonly subscribe: ( rx: Rx, f: (_: A) => void, @@ -473,10 +473,10 @@ Added in v1.0.0 ```ts export interface WriteContext { - readonly get: Rx.Get + readonly get: (rx: Rx) => A readonly refreshSelf: () => void readonly setSelf: (a: A) => void - readonly set: Rx.Set + readonly set: (rx: Writable, value: W) => void } ``` diff --git a/packages/rx-react/src/index.ts b/packages/rx-react/src/index.ts index d03aea8..49f9c64 100644 --- a/packages/rx-react/src/index.ts +++ b/packages/rx-react/src/index.ts @@ -198,35 +198,32 @@ type SuspenseResult = } | { readonly _tag: "Value" - readonly isWaiting: boolean readonly value: Result.Success | Result.Failure } const suspenseRx = Rx.family((rx: Rx.Rx>) => Rx.readable((get): SuspenseResult => { const result = get(rx) - const value = Result.noWaiting(result) - if (value._tag === "Initial") { + if (result._tag === "Initial") { return { _tag: "Suspended", promise: new Promise((resolve) => get.addFinalizer(resolve)) } as const } - const isWaiting = Result.isWaiting(result) - return { _tag: "Value", isWaiting, value } as const + return { _tag: "Value", value: result } as const }) ) const suspenseRxWaiting = Rx.family((rx: Rx.Rx>) => Rx.readable((get): SuspenseResult => { const result = get(rx) - if (result._tag === "Waiting" || result._tag === "Initial") { + if (result.waiting || result._tag === "Initial") { return { _tag: "Suspended", promise: new Promise((resolve) => get.addFinalizer(resolve)) } as const } - return { _tag: "Value", isWaiting: false, value: result } as const + return { _tag: "Value", value: result } as const }) ) @@ -239,10 +236,7 @@ const suspenseMounts = globalValue("@effect-rx/rx-react/suspenseMounts", () => n export const useRxSuspense = ( rx: Rx.Rx>, options?: { readonly suspendOnWaiting?: boolean } -): { - readonly isWaiting: boolean - readonly value: Result.Success | Result.Failure -} => { +): Result.Success | Result.Failure => { const registry = React.useContext(RegistryContext) const resultRx = React.useMemo( () => (options?.suspendOnWaiting ? suspenseRxWaiting(rx) : suspenseRx(rx)), @@ -263,7 +257,7 @@ export const useRxSuspense = ( throw result.promise } - return result + return result.value } /** @@ -273,18 +267,12 @@ export const useRxSuspense = ( export const useRxSuspenseSuccess = ( rx: Rx.Rx>, options?: { readonly suspendOnWaiting?: boolean } -): { - readonly isWaiting: boolean - readonly value: A -} => { +): Result.Success => { const result = useRxSuspense(rx, options) - if (result.value._tag === "Failure") { - throw Cause.squash(result.value.cause) - } - return { - isWaiting: result.isWaiting, - value: result.value.value + if (result._tag === "Failure") { + throw Cause.squash(result.cause) } + return result } /** diff --git a/packages/rx/src/Rx.ts b/packages/rx/src/Rx.ts index 5826fcd..6ff3a22 100644 --- a/packages/rx/src/Rx.ts +++ b/packages/rx/src/Rx.ts @@ -176,20 +176,20 @@ export interface Writable extends Rx { */ export interface Context { (rx: Rx): A - readonly get: Rx.Get - readonly result: Rx.GetResult - readonly once: Rx.Get + readonly get: (rx: Rx) => A + readonly result: (rx: Rx>) => Exit.Exit + readonly once: (rx: Rx) => A readonly addFinalizer: (f: () => void) => void readonly mount: (rx: Rx) => void - readonly refreshSync: Rx.RefreshRxSync - readonly refresh: Rx.RefreshRx + readonly refreshSync: (rx: Rx & Refreshable) => void + readonly refresh: (rx: Rx & Refreshable) => Effect.Effect readonly refreshSelfSync: () => void readonly refreshSelf: Effect.Effect readonly self: () => Option.Option readonly setSelfSync: (a: A) => void readonly setSelf: (a: A) => Effect.Effect - readonly setSync: Rx.Set - readonly set: Rx.SetEffect + readonly setSync: (rx: Writable, value: W) => void + readonly set: (rx: Writable, value: W) => Effect.Effect readonly subscribe: (rx: Rx, f: (_: A) => void, options?: { readonly immediate?: boolean }) => void @@ -200,10 +200,10 @@ export interface Context { * @category context */ export interface WriteContext { - readonly get: Rx.Get + readonly get: (rx: Rx) => A readonly refreshSelf: () => void readonly setSelf: (a: A) => void - readonly set: Rx.Set + readonly set: (rx: Writable, value: W) => void } const RxProto = { @@ -545,28 +545,28 @@ export interface RxRuntime extends Rx> * @category constructors */ export const runtime: { - (layer: Layer.Layer, options?: { + (create: (get: Context) => Layer.Layer, options?: { readonly autoDispose?: boolean readonly idleTTL?: Duration.DurationInput readonly runtime?: undefined }): RxRuntime - (layer: Layer.Layer, options?: { + (create: (get: Context) => Layer.Layer, options?: { readonly autoDispose?: boolean readonly idleTTL?: Duration.DurationInput readonly runtime: RxRuntime }): RxRuntime -} = (layer: Layer.Layer, options?: { +} = (create: (get: Context) => Layer.Layer, options?: { readonly autoDispose?: boolean readonly idleTTL?: Duration.DurationInput readonly runtime?: RxRuntime }): RxRuntime => { let rx = options?.runtime - ? scoped(() => + ? scoped((get) => Effect.flatMap( - Layer.build(layer), + Layer.build(create(get)), (context) => Effect.provide(Effect.runtime(), context) ), { runtime: options.runtime }) - : scoped(() => Layer.toRuntime(layer) as Effect.Effect>) + : scoped((get) => Layer.toRuntime(create(get)) as Effect.Effect>) if (options?.idleTTL !== undefined) { rx = setIdleTTL(rx, options.idleTTL) diff --git a/packages/rx/test/Rx.test.ts b/packages/rx/test/Rx.test.ts index acfbc90..e475d9d 100644 --- a/packages/rx/test/Rx.test.ts +++ b/packages/rx/test/Rx.test.ts @@ -680,14 +680,14 @@ const MultiplierLive = Layer.effect( }) ) -const counterRuntime = Rx.runtime(CounterLive, { +const counterRuntime = Rx.runtime(() => CounterLive, { autoDispose: true }) -const multiplierRuntime = Rx.runtime(MultiplierLive, { +const multiplierRuntime = Rx.runtime(() => MultiplierLive, { runtime: counterRuntime, autoDispose: true }) -const fiberRefRuntime = Rx.runtime(Layer.setRequestCaching(true), { +const fiberRefRuntime = Rx.runtime(() => Layer.setRequestCaching(true), { runtime: counterRuntime, autoDispose: true })