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

[sitecore-jss-nextjs] Rework promises in context implementation #1716

Merged
merged 6 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Our versioning strategy is as follows:
* `[templates/node-headless-ssr-proxy]` `[node-headless-ssr-proxy]` Add sc_site qs parameter to Layout Service requests by default ([#1660](https://github.com/Sitecore/jss/pull/1660))
* `[templates/nextjs-sxa]` Fixed Image component when there is using Banner variant which set property background-image when image is empty. ([#1689](https://github.com/Sitecore/jss/pull/1689)) ([#1692](https://github.com/Sitecore/jss/pull/1692))
* `[templates/nextjs-sxa]` Fix feature `show Grid column` in Experience Editor. ([#1704](https://github.com/Sitecore/jss/pull/1704))
* `[sitecore-jss-nextjs] [templates/nextjs-xmcloud]` SDK initialization rejections are now correctly handled. Errors should no longer occur after getSDK() promises resolve when they shouldn't (for example, getting Events SDK in development environment) ([#1712](https://github.com/Sitecore/jss/pull/1712) [#1715](https://github.com/Sitecore/jss/pull/1715) [#1716](https://github.com/Sitecore/jss/pull/1716))

### 🧹 Chores

Expand All @@ -32,7 +33,7 @@ Our versioning strategy is as follows:
### 🎉 New Features & Improvements

* `[templates/react]` `[templates/angular]` `[templates/vue]` `[templates/node-headless-ssr-proxy]` `[templates/node-headless-ssr-experience-edge]` ([#1647](https://github.com/Sitecore/jss/pull/1647)) ([#1672](https://github.com/Sitecore/jss/pull/1672)) Switch from using JSS_APP_NAME to SITECORE_SITE_NAME - environment and config variables in React, Vue, Angular templates as well as ssr node proxy apps templates have been renamed.
* `[templates/nextjs]` `[sitecore-jss-nextjs]` `[sitecore-jss]` ([#1640](https://github.com/Sitecore/jss/pull/1640)) ([#1662](https://github.com/Sitecore/jss/pull/1662))([#1661](https://github.com/Sitecore/jss/pull/1661)) ([#1672](https://github.com/Sitecore/jss/pull/1672)) ([#1675](https://github.com/Sitecore/jss/pull/1675)) ([#1710](https://github.com/Sitecore/jss/pull/1710)) ([#1712](https://github.com/Sitecore/jss/pull/1712) [#1715](https://github.com/Sitecore/jss/pull/1715)) Sitecore Edge Platform and Context support:
* `[templates/nextjs]` `[sitecore-jss-nextjs]` `[sitecore-jss]` ([#1640](https://github.com/Sitecore/jss/pull/1640)) ([#1662](https://github.com/Sitecore/jss/pull/1662))([#1661](https://github.com/Sitecore/jss/pull/1661)) ([#1672](https://github.com/Sitecore/jss/pull/1672)) ([#1675](https://github.com/Sitecore/jss/pull/1675)) ([#1710](https://github.com/Sitecore/jss/pull/1710)) Sitecore Edge Platform and Context support:
* Introducing the _clientFactory_ property. This property can be utilized by GraphQL-based services, the previously used _endpoint_ and _apiKey_ properties are deprecated. The _clientFactory_ serves as the central hub for executing GraphQL requests within the application.
* New SITECORE_EDGE_CONTEXT_ID environment variable has been added.
* The JSS_APP_NAME environment variable has been updated and is now referred to as SITECORE_SITE_NAME.
Expand Down
17 changes: 9 additions & 8 deletions packages/sitecore-jss-nextjs/src/context/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,16 @@ describe('Context', () => {
expect(context.siteName).to.equal('website-1');
});

it('should catch and log when SDK initialization rejects', () => {
const consoleSpy = sinon.spy(console, 'log');
it('should not fail context init when an SDK init throws', (done) => {
const localProps = { ...props, sdks: errorSdk };
const context = new Context<typeof errorSdk>(localProps);
context.init();
expect(
consoleSpy.calledWith('Initialization for SDK Error skipped. Reason: \n Cannot init Error')
);
consoleSpy.restore();
try {
context.init();
} catch (e) {
done(e);
} finally {
done();
}
});

it('should reject when getting SDK that rejected initialization', (done) => {
Expand All @@ -189,7 +190,7 @@ describe('Context', () => {
context
.getSDK('Error')
.then(() => {
throw new Error('should not resolve');
done('should not resolve');
})
.catch((e) => {
expect(e).to.be.equal('Cannot init Error');
Expand Down
19 changes: 15 additions & 4 deletions packages/sitecore-jss-nextjs/src/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export class Context<SDKModules extends SDKModulesType> {
*/
protected sdkPromises: { [module in keyof SDKModules]?: Promise<SDKModules[module]['sdk']> } = {};

protected sdkErrors: { [module in keyof SDKModules]?: string } = {};

constructor(protected props: ContextConfig<SDKModules>) {
this.sitecoreEdgeUrl = props.sitecoreEdgeUrl;
this.sitecoreEdgeContextId = props.sitecoreEdgeContextId;
Expand Down Expand Up @@ -127,7 +129,15 @@ export class Context<SDKModules extends SDKModulesType> {
* @returns initialized SDK
*/
public getSDK = <T extends keyof SDKModules>(name: T): Promise<SDKModules[T]['sdk']> => {
return this.sdkPromises[name] || Promise.reject(`Unknown SDK '${String(name)}'`);
if (!this.sdkPromises[name]) {
return Promise.reject(`Unknown SDK '${String(name)}'`);
} else {
return this.sdkPromises[name]!.then((result) => {
return (
(this.sdkErrors[name] && Promise.reject(this.sdkErrors[name])) || Promise.resolve(result)
);
});
}
};

/**
Expand All @@ -137,16 +147,17 @@ export class Context<SDKModules extends SDKModulesType> {
* @returns {void}
*/
protected initSDK<T extends keyof SDKModules>(name: T): void {
this.sdkPromises[name] = new Promise((resolve, reject) => {
this.sdkPromises[name] = new Promise((resolve) => {
this.props.sdks[name]
.init(this)
.then(() => {
this.sdks[name] = this.props.sdks[name].sdk;
resolve(this.sdks[name]);
})
.catch((e) => {
// if init rejects, getSDK will reject too now
reject(e);
// if init rejects, we mark SDK as failed - so getSDK cal would reject with a reason
art-alexeyenko marked this conversation as resolved.
Show resolved Hide resolved
this.sdkErrors[name] = e;
resolve(undefined);
});
});
}
Expand Down