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

feat(headless-react): create providers with definition #4709

Merged
merged 53 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
187fc0b
recs server-side working
y-lakhdar Oct 31, 2024
d571439
recognize search action promises
y-lakhdar Nov 1, 2024
4dc2717
add typeguard
y-lakhdar Nov 1, 2024
2e5f794
prevent multiple recommendations with the same slot
y-lakhdar Nov 1, 2024
de43049
clean
y-lakhdar Nov 3, 2024
9254b93
draft
y-lakhdar Nov 14, 2024
f2d1fa1
working draft
y-lakhdar Nov 15, 2024
bc63a92
test
y-lakhdar Nov 15, 2024
8d170d2
Merge branch 'master' of github.com:coveo/ui-kit into ssr-recs
y-lakhdar Nov 15, 2024
e60bfe5
update sample
y-lakhdar Nov 15, 2024
be888c8
recommendation hydration working
y-lakhdar Nov 15, 2024
c4ff2b9
clean build function
y-lakhdar Nov 15, 2024
2783740
clean exports
y-lakhdar Nov 15, 2024
8a6f9d8
filter invalid and duplicate recommendations
y-lakhdar Nov 16, 2024
025b34f
refacto
y-lakhdar Nov 16, 2024
07d1ec8
simplify build factory
y-lakhdar Nov 17, 2024
9b049fd
adjust factory params and throw error on bad engine definition
y-lakhdar Nov 17, 2024
84e5c53
do not ask props for disabled controllers
y-lakhdar Nov 17, 2024
018c0be
remove comments
y-lakhdar Nov 17, 2024
a7200d8
update warning message
y-lakhdar Nov 17, 2024
785951f
fix export
y-lakhdar Nov 17, 2024
f342da5
clean PR
y-lakhdar Nov 18, 2024
677fd45
clean controller build condition
y-lakhdar Nov 18, 2024
87d0792
create commerce build result type
y-lakhdar Nov 18, 2024
16c2b5e
remove unnecessary error
y-lakhdar Nov 18, 2024
dbffb51
revert EngineDefinitionControllersPropsOption
y-lakhdar Nov 18, 2024
961c28e
update UT
y-lakhdar Nov 18, 2024
c58b3ae
Add recs to sample
alexprudhomme Nov 18, 2024
81ba114
Merge branch 'master' into ssr-recs
alexprudhomme Nov 18, 2024
b8e6e16
no core engine
alexprudhomme Nov 18, 2024
3f93d51
add todo
alexprudhomme Nov 18, 2024
93b3967
Merge branch 'master' into ssr-recs
alexprudhomme Nov 22, 2024
8c37023
working recs
alexprudhomme Nov 22, 2024
5fb7c01
trying with a bunch of generics
alexprudhomme Nov 22, 2024
9f06f72
Revert "trying with a bunch of generics"
alexprudhomme Nov 22, 2024
f4177f5
weird stuff
alexprudhomme Nov 22, 2024
2e08ec0
Revert "weird stuff"
alexprudhomme Nov 22, 2024
f79746f
clean
alexprudhomme Nov 22, 2024
745b70d
deep types
alexprudhomme Nov 25, 2024
f19b86b
Revert "deep types"
alexprudhomme Nov 25, 2024
329f417
feat(headless-react): simply create providers with definition
alexprudhomme Nov 25, 2024
09c16bf
add TODO
alexprudhomme Nov 25, 2024
3f1fd0f
delete useless itnerfaces
alexprudhomme Nov 25, 2024
4cc0ed6
fix product page and fix standalone provider
alexprudhomme Nov 25, 2024
4a139b1
remove TODO
alexprudhomme Nov 25, 2024
652917d
add comments
alexprudhomme Nov 25, 2024
3399b4c
Merge branch 'master' into KIT-3734
alexprudhomme Nov 26, 2024
2a2aaee
UniversalControllerDefinitionWithoutProps -> NonRecommendationControl…
alexprudhomme Nov 26, 2024
6a35348
text clearer
alexprudhomme Nov 26, 2024
e41d2ca
fix build
alexprudhomme Nov 26, 2024
f0213f4
Merge branch 'master' into KIT-3734
alexprudhomme Nov 27, 2024
f454e9b
remove metadata
alexprudhomme Nov 27, 2024
ae9bbae
Update atomic-external.e2e.ts
alexprudhomme Nov 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe('Headless react SSR utils', () => {
listingEngineDefinition,
searchEngineDefinition,
standaloneEngineDefinition,
recommendationEngineDefinition,
...rest
} = defineCommerceEngine({configuration: sampleConfig});
const {
Expand Down
11 changes: 11 additions & 0 deletions packages/headless-react/src/ssr-commerce/commerce-engine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ export function defineCommerceEngine<
>;
type ListingContext = ContextStateType<SolutionType.listing>;
type SearchContext = ContextStateType<SolutionType.search>;
type RecommendationContext = ContextStateType<SolutionType.recommendation>;
type StandaloneContext = ContextStateType<SolutionType.standalone>;

const {
listingEngineDefinition,
searchEngineDefinition,
standaloneEngineDefinition,
recommendationEngineDefinition,
} = defineBaseCommerceEngine({...options});
return {
useEngine: buildEngineHook(singletonContext),
Expand Down Expand Up @@ -84,5 +86,14 @@ export function defineCommerceEngine<
singletonContext as StandaloneContext
),
},
recommendationEngineDefinition: {
...recommendationEngineDefinition,
StaticStateProvider: buildStaticStateProvider(
singletonContext as RecommendationContext
),
HydratedStateProvider: buildHydratedStateProvider(
singletonContext as RecommendationContext
),
},
};
}
1 change: 1 addition & 0 deletions packages/headless-react/src/ssr-commerce/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export {defineCommerceEngine} from './commerce-engine.js';
export {buildProviderWithDefinition} from './providers.js';
export type {ReactCommerceEngineDefinition} from './commerce-engine.js';
export {MissingEngineProviderError} from '../errors.js';
export * from '@coveo/headless/ssr-commerce';
103 changes: 103 additions & 0 deletions packages/headless-react/src/ssr-commerce/providers.tsx
alexprudhomme marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
'use client';

import {
InferHydratedState,
InferStaticState,
NavigatorContext,
} from '@coveo/headless/ssr-commerce';
import {PropsWithChildren, useEffect, useState} from 'react';
import {defineCommerceEngine} from './commerce-engine.js';

interface WithDefinitionProps {
staticState: InferStaticState<RealDefinition>;
navigatorContext: NavigatorContext;
}

type LooseDefinition = {
setNavigatorContextProvider: unknown;
build: unknown;
hydrateStaticState: unknown;
fetchStaticState: unknown;
HydratedStateProvider: unknown;
StaticStateProvider: unknown;
};

type RealDefinition =
| ReturnType<typeof defineCommerceEngine>['recommendationEngineDefinition']
| ReturnType<typeof defineCommerceEngine>['listingEngineDefinition']
| ReturnType<typeof defineCommerceEngine>['searchEngineDefinition']
| ReturnType<typeof defineCommerceEngine>['standaloneEngineDefinition'];

export function buildProviderWithDefinition(looseDefinition: LooseDefinition) {
return function WrappedProvider({
staticState,
navigatorContext,
children,
}: PropsWithChildren<WithDefinitionProps>) {
const definition = looseDefinition as RealDefinition;
type RecommendationHydratedState = InferHydratedState<typeof definition>;
const [hydratedState, setHydratedState] = useState<
RecommendationHydratedState | undefined
>(undefined);

definition.setNavigatorContextProvider(() => navigatorContext);

useEffect(() => {
alexprudhomme marked this conversation as resolved.
Show resolved Hide resolved
const {searchActions, controllers} = staticState;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hydrateControllers: Record<string, any> = {};

if ('cart' in controllers) {
hydrateControllers.cart = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initialState: {items: (controllers as any).cart.state.items},
};
}

if ('context' in controllers) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
hydrateControllers.context = (controllers as any).context.state;
}

definition
.hydrateStaticState({
searchActions,
controllers: {
...controllers,
...hydrateControllers,
},
})
.then(({engine, controllers}) => {
setHydratedState({engine, controllers});
});
}, [staticState]);

if (hydratedState) {
return (
<definition.HydratedStateProvider
engine={hydratedState.engine}
controllers={hydratedState.controllers}
>
{children}
</definition.HydratedStateProvider>
);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const StaticStateProviderWithAnyControllers = (looseDefinition as any)
.StaticStateProvider as React.ComponentType<{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
controllers: any;
children: React.ReactNode;
}>;

return (
<StaticStateProviderWithAnyControllers
controllers={staticState.controllers}
>
{children}
</StaticStateProviderWithAnyControllers>
);
};
}
Loading