diff --git a/packages/effect-fc/src/Component.ts b/packages/effect-fc/src/Component.ts index 1052e49..5168910 100644 --- a/packages/effect-fc/src/Component.ts +++ b/packages/effect-fc/src/Component.ts @@ -21,6 +21,10 @@ export namespace Component { } } +export interface ComponentClass extends Component { + +} + const ComponentProto = Object.seal({ pipe() { return Pipeable.pipeArguments(this, arguments) } @@ -378,28 +382,31 @@ export namespace Suspense { export type Props = Omit } -export const suspense = , P extends {}>( - self: ExcludeKeys & Component> -): T & Suspense => Object.setPrototypeOf( - { ...self, suspense: true, suspenseOptions: {} }, - Object.getPrototypeOf(self), -) +export const suspense = | Component & Suspense, P extends {}>( + self: T & Component> +): ( + & T + & Component, Component.Context, P & Suspense.Props> + & Suspense +) => Object.setPrototypeOf({ + ...self, + suspense: true, + suspenseOptions: Predicate.hasProperty(self, "suspense") ? { ...self.suspenseOptions } : {}, +}, Object.getPrototypeOf(self)) -export const suspenseWithOptions: { - , P extends {}>( +export const withSuspenseOptions: { + & Suspense>( suspenseOptions: Partial - ): ( - self: ExcludeKeys & Component> - ) => T & Suspense - , P extends {}>( - self: ExcludeKeys & Component>, + ): (self: T) => T + & Suspense>( + self: T, suspenseOptions: Partial, - ): T & Suspense -} = Function.dual(2, , P extends {}>( - self: ExcludeKeys & Component>, + ): T +} = Function.dual(2, & Suspense>( + self: T, suspenseOptions: Partial, -): T & Suspense => Object.setPrototypeOf( - { ...self, suspense: true, suspenseOptions }, +): T => Object.setPrototypeOf( + { ...self, suspense: true, suspenseOptions: { ...self.suspenseOptions, ...suspenseOptions } }, Object.getPrototypeOf(self), )) diff --git a/packages/example/src/routes/dev/memo.tsx b/packages/example/src/routes/dev/memo.tsx index f58e6ad..b457d3d 100644 --- a/packages/example/src/routes/dev/memo.tsx +++ b/packages/example/src/routes/dev/memo.tsx @@ -28,12 +28,17 @@ const RouteComponent = Component.make(function* RouteComponent() { Component.withRuntime(runtime.context) ) -const SubComponent = Component.make(function* SubComponent() { +const SubComponent = Component.make(function* SubComponent(props: { readonly value?: string }) { const id = yield* makeUuid4.pipe(Effect.provide(GetRandomValues.CryptoRandom)) return {id} }) -const MemoizedSubComponent = Component.memo(SubComponent) +const MemoizedSubComponent = SubComponent.pipe( + Component.memo, + Component.suspense, + Component.memo, +) +type T = typeof MemoizedSubComponent extends Component.Memoized ? P : never export const Route = createFileRoute("/dev/memo")({ component: RouteComponent,