Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(headless, headless-react): no more generic engine in ssr-commerce types #4657

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
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 @@ -25,23 +25,21 @@ import {
} from './types.js';

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 @@ -80,12 +78,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 @@ -102,12 +99,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 @@ -120,12 +116,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 @@ -143,20 +138,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'];
methods?: 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
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,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 @@ -108,10 +108,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 @@ -124,10 +123,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
Loading