From 5ca3d2750138562a20022b34623d9baa3f317935 Mon Sep 17 00:00:00 2001 From: Zubeyr Dereli Date: Wed, 19 May 2021 21:56:14 +0200 Subject: [PATCH] fix(localize): reset storage correctly long running imports were polluting newly reset storage --- .changeset/mighty-cars-grow.md | 5 ++++ packages/localize/src/LocalizeManager.js | 10 ++++++-- .../localize/test/LocalizeManager.test.js | 24 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 .changeset/mighty-cars-grow.md diff --git a/.changeset/mighty-cars-grow.md b/.changeset/mighty-cars-grow.md new file mode 100644 index 000000000..6756916c5 --- /dev/null +++ b/.changeset/mighty-cars-grow.md @@ -0,0 +1,5 @@ +--- +'@lion/localize': patch +--- + +Fix localize race condition where data was being added while namespace loader promise was no longer in cache. diff --git a/packages/localize/src/LocalizeManager.js b/packages/localize/src/LocalizeManager.js index 8fe6ed114..703e82386 100644 --- a/packages/localize/src/LocalizeManager.js +++ b/packages/localize/src/LocalizeManager.js @@ -340,8 +340,14 @@ export class LocalizeManager { * @param {Object} obj.default */ obj => { - const data = isLocalizeESModule(obj) ? obj.default : obj; - this.addData(locale, namespace, data); + // add data only if we have the promise in cache + if ( + this.__namespaceLoaderPromisesCache[locale] && + this.__namespaceLoaderPromisesCache[locale][namespace] === loaderPromise + ) { + const data = isLocalizeESModule(obj) ? obj.default : obj; + this.addData(locale, namespace, data); + } }, ); } diff --git a/packages/localize/test/LocalizeManager.test.js b/packages/localize/test/LocalizeManager.test.js index 68f8d017c..5c1bc65f1 100644 --- a/packages/localize/test/LocalizeManager.test.js +++ b/packages/localize/test/LocalizeManager.test.js @@ -60,6 +60,30 @@ describe('LocalizeManager', () => { expect(document.documentElement.lang).to.equal('en-GB'); }); + it('empties storage after reset() is invoked', async () => { + manager = new LocalizeManager(); + + let deferredResolve; + manager.loadNamespace({ + generic: () => + new Promise(resolve => { + deferredResolve = () => resolve({ greeting: 'Hello!' }); + }), + }); + + const { loadingComplete } = manager; + + manager.reset(); + expect(getProtectedMembers(manager).storage).to.be.empty; + + // @ts-ignore + deferredResolve(); + await loadingComplete; + + // storage still needs to be empty after promise is fulfilled. + expect(getProtectedMembers(manager).storage).to.be.empty; + }); + it('has teardown() method removing all side effects', () => { manager = new LocalizeManager(); const disconnectObserverSpy = sinon.spy(