Skip to content

Commit

Permalink
refactor(headless, headless-react): no more generic engine in ssr-com…
Browse files Browse the repository at this point in the history
…merce types
  • Loading branch information
alexprudhomme committed Nov 8, 2024
1 parent 6b2b08d commit 162dd59
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 142 deletions.
26 changes: 6 additions & 20 deletions packages/headless-react/src/ssr-commerce/commerce-engine.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
Controller,
CommerceEngine,
ControllerDefinitionsMap,
CommerceEngineDefinitionOptions,
defineCommerceEngine as defineBaseCommerceEngine,
Expand All @@ -19,26 +18,17 @@ import {
import {ContextState, ReactEngineDefinition} from './types.js';

export type ReactCommerceEngineDefinition<
TControllers extends ControllerDefinitionsMap<CommerceEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
> = ReactEngineDefinition<
CommerceEngine,
TControllers,
CommerceEngineOptions,
TSolutionType
>;
> = ReactEngineDefinition<TControllers, CommerceEngineOptions, TSolutionType>;

// Wrapper to workaround the limitation that `createContext()` cannot be called directly during SSR in next.js
export function createSingletonContext<
TControllers extends ControllerDefinitionsMap<CommerceEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType = SolutionType,
>() {
return singleton(() =>
React.createContext<ContextState<
CommerceEngine,
TControllers,
TSolutionType
> | null>(null)
React.createContext<ContextState<TControllers, TSolutionType> | null>(null)
);
}

Expand All @@ -47,16 +37,12 @@ export function createSingletonContext<
* on the server and client side respectively.
*/
export function defineCommerceEngine<
TControllers extends ControllerDefinitionsMap<CommerceEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
>(options: CommerceEngineDefinitionOptions<TControllers>) {
const singletonContext = createSingletonContext<TControllers>();

type ContextStateType<TSolutionType extends SolutionType> = SingletonGetter<
React.Context<ContextState<
CommerceEngine,
TControllers,
TSolutionType
> | null>
React.Context<ContextState<TControllers, TSolutionType> | null>
>;
type ListingContext = ContextStateType<SolutionType.listing>;
type SearchContext = ContextStateType<SolutionType.search>;
Expand Down
36 changes: 15 additions & 21 deletions packages/headless-react/src/ssr-commerce/common.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
Controller,
ControllerDefinitionsMap,
CoreEngineNext,
InferControllerFromDefinition,
InferControllerStaticStateMapFromDefinitionsWithSolutionType,
InferControllersMapFromDefinition,
SolutionType,
CommerceEngine as SSRCommerceEngine,
} from '@coveo/headless/ssr-commerce';
import {
useContext,
Expand All @@ -32,23 +32,21 @@ export class MissingEngineProviderError extends Error {
}

function isHydratedStateContext<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
>(
ctx: ContextState<TEngine, TControllers, TSolutionType>
): ctx is ContextHydratedState<TEngine, TControllers, TSolutionType> {
ctx: ContextState<TControllers, TSolutionType>
): ctx is ContextHydratedState<TControllers, TSolutionType> {
return 'engine' in ctx;
}

function buildControllerHook<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TKey extends keyof TControllers,
TSolutionType extends SolutionType,
>(
singletonContext: SingletonGetter<
Context<ContextState<TEngine, TControllers, TSolutionType> | null>
Context<ContextState<TControllers, TSolutionType> | null>
>,
key: TKey
): ControllerHook<InferControllerFromDefinition<TControllers[TKey]>> {
Expand Down Expand Up @@ -87,12 +85,11 @@ function buildControllerHook<
}

export function buildControllerHooks<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
>(
singletonContext: SingletonGetter<
Context<ContextState<TEngine, TControllers, TSolutionType> | null>
Context<ContextState<TControllers, TSolutionType> | null>
>,
controllersMap?: TControllers
) {
Expand All @@ -109,12 +106,11 @@ export function buildControllerHooks<
}

export function buildEngineHook<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
>(
singletonContext: SingletonGetter<
Context<ContextState<TEngine, TControllers, TSolutionType> | null>
Context<ContextState<TControllers, TSolutionType> | null>
>
) {
return () => {
Expand All @@ -127,12 +123,11 @@ export function buildEngineHook<
}

export function buildStaticStateProvider<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
>(
singletonContext: SingletonGetter<
Context<ContextState<TEngine, TControllers, TSolutionType> | null>
Context<ContextState<TControllers, TSolutionType> | null>
>
) {
return ({
Expand All @@ -150,20 +145,19 @@ export function buildStaticStateProvider<
}

export function buildHydratedStateProvider<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
>(
singletonContext: SingletonGetter<
Context<ContextState<TEngine, TControllers, TSolutionType> | null>
Context<ContextState<TControllers, TSolutionType> | null>
>
) {
return ({
engine,
controllers,
children,
}: PropsWithChildren<{
engine: TEngine;
engine: SSRCommerceEngine;
controllers: InferControllersMapFromDefinition<TControllers, TSolutionType>;
}>) => {
const {Provider} = singletonContext.get();
Expand Down
28 changes: 12 additions & 16 deletions packages/headless-react/src/ssr-commerce/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import {
InferControllerStaticStateMapFromDefinitionsWithSolutionType,
EngineDefinition,
SolutionType,
CoreEngineNext,
CommerceEngine as SSRCommerceEngine,
} from '@coveo/headless/ssr-commerce';
import {FunctionComponent, PropsWithChildren} from 'react';

export type ContextStaticState<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
> = {
controllers: InferControllerStaticStateMapFromDefinitionsWithSolutionType<
Expand All @@ -22,43 +21,40 @@ export type ContextStaticState<
};

export type ContextHydratedState<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
> = {
engine: TEngine;
engine: SSRCommerceEngine;
controllers: InferControllersMapFromDefinition<TControllers, TSolutionType>;
};

export type ContextState<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
> =
| ContextStaticState<TEngine, TControllers, TSolutionType>
| ContextHydratedState<TEngine, TControllers, TSolutionType>;
| ContextStaticState<TControllers, TSolutionType>
| ContextHydratedState<TControllers, TSolutionType>;

export type ControllerHook<TController extends Controller> = () => {
state: TController['state'];
controller?: Omit<TController, 'state' | 'subscribe'>;
};

export type InferControllerHooksMapFromDefinition<
TControllers extends ControllerDefinitionsMap<CoreEngineNext, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
> = {
[K in keyof TControllers as `use${Capitalize<
K extends string ? K : never
>}`]: ControllerHook<InferControllerFromDefinition<TControllers[K]>>;
};

export type ReactEngineDefinition<
TEngine extends CoreEngineNext,
TControllers extends ControllerDefinitionsMap<TEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TEngineOptions,
TSolutionType extends SolutionType,
> = EngineDefinition<TEngine, TControllers, TEngineOptions, TSolutionType> & {
> = EngineDefinition<TControllers, TEngineOptions, TSolutionType> & {
controllers: InferControllerHooksMapFromDefinition<TControllers>;
useEngine(): TEngine | undefined;
useEngine(): SSRCommerceEngine | undefined;
StaticStateProvider: FunctionComponent<
PropsWithChildren<{
controllers: InferControllerStaticStateMapFromDefinitionsWithSolutionType<
Expand All @@ -69,7 +65,7 @@ export type ReactEngineDefinition<
>;
HydratedStateProvider: FunctionComponent<
PropsWithChildren<{
engine: TEngine;
engine: SSRCommerceEngine;
controllers: InferControllersMapFromDefinition<
TControllers,
TSolutionType
Expand Down
10 changes: 3 additions & 7 deletions packages/headless/src/app/commerce-engine/commerce-engine.ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface SSRCommerceEngine extends CommerceEngine {
}

export type CommerceEngineDefinitionOptions<
TControllers extends ControllerDefinitionsMap<SSRCommerceEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
> = EngineDefinitionOptions<CommerceEngineOptions, TControllers>;

function isListingFetchCompletedAction(action: unknown): action is Action {
Expand Down Expand Up @@ -107,10 +107,9 @@ function buildSSRCommerceEngine(
}

export interface CommerceEngineDefinition<
TControllers extends ControllerDefinitionsMap<SSRCommerceEngine, Controller>,
TControllers extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
> extends EngineDefinition<
SSRCommerceEngine,
TControllers,
CommerceEngineOptions,
TSolutionType
Expand All @@ -123,10 +122,7 @@ export interface CommerceEngineDefinition<
* and a build function that can be used for edge cases requiring more control.
*/
export function defineCommerceEngine<
TControllerDefinitions extends ControllerDefinitionsMap<
SSRCommerceEngine,
Controller
>,
TControllerDefinitions extends ControllerDefinitionsMap<Controller>,
>(
options: CommerceEngineDefinitionOptions<TControllerDefinitions>
): {
Expand Down
15 changes: 5 additions & 10 deletions packages/headless/src/app/commerce-ssr-engine/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Controller} from '../../controllers/controller/headless-controller.js';
import {InvalidControllerDefinition} from '../../utils/errors.js';
import {filterObject, mapObject} from '../../utils/utils.js';
import {CoreEngine, CoreEngineNext} from '../engine.js';
import {SSRCommerceEngine} from '../commerce-engine/commerce-engine.ssr.js';
import {InferControllerPropsMapFromDefinitions} from '../ssr-engine/types/common.js';
import {
ControllerDefinition,
Expand All @@ -14,16 +14,15 @@ import {
} from './types/common.js';

function buildControllerFromDefinition<
TControllerDefinition extends ControllerDefinition<TEngine, Controller>,
TEngine extends CoreEngine | CoreEngineNext,
TControllerDefinition extends ControllerDefinition<Controller>,
>({
definition,
engine,
solutionType,
props,
}: {
definition: TControllerDefinition;
engine: TEngine;
engine: SSRCommerceEngine;
solutionType: SolutionType;
props?: InferControllerPropsFromDefinition<TControllerDefinition>;
}): InferControllerFromDefinition<TControllerDefinition> {
Expand All @@ -35,11 +34,7 @@ function buildControllerFromDefinition<
}

export function buildControllerDefinitions<
TControllerDefinitionsMap extends ControllerDefinitionsMap<
CoreEngine | CoreEngineNext,
Controller
>,
TEngine extends CoreEngine | CoreEngineNext,
TControllerDefinitionsMap extends ControllerDefinitionsMap<Controller>,
TSolutionType extends SolutionType,
>({
definitionsMap,
Expand All @@ -48,7 +43,7 @@ export function buildControllerDefinitions<
propsMap,
}: {
definitionsMap: TControllerDefinitionsMap;
engine: TEngine;
engine: SSRCommerceEngine;
solutionType: TSolutionType;
propsMap: InferControllerPropsMapFromDefinitions<TControllerDefinitionsMap>;
}): InferControllersMapFromDefinition<
Expand Down
Loading

0 comments on commit 162dd59

Please sign in to comment.