Skip to content

Commit

Permalink
[sitecore-jss-nextjs] Rework promises in context implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
art-alexeyenko authored Jan 17, 2024
2 parents 18f0e66 + c382a99 commit 7b37f0b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 13 deletions.
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 call would reject with a reason
this.sdkErrors[name] = e;
resolve(undefined);
});
});
}
Expand Down

0 comments on commit 7b37f0b

Please sign in to comment.