Skip to content

Commit

Permalink
fix(store): provide NoopNgxsExecutionStrategy explicitly when the z…
Browse files Browse the repository at this point in the history
…one is nooped (#1819)

* fix(store): provide `NoopNgxsExecutionStrategy` explicitly when the zone is nooped

* chore: update Bundlesize

Co-authored-by: Mark Whitfeld <[email protected]>
  • Loading branch information
arturovt and markwhitfeld authored Mar 1, 2022
1 parent d470dff commit 8ecbd7f
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $ npm install @ngxs/store@dev
- Fix: Handle mixed async scenarios for action handlers [#1762](https://github.com/ngxs/store/pull/1762)
- Fix: An action with cancelUncompleted enabled should unsubscribe before the next action handler is called [#1763](https://github.com/ngxs/store/pull/1763)
- Fix: Do not run `Promise.then` within synchronous tests when decorating factory [#1753](https://github.com/ngxs/store/pull/1753)
- Fix: Provide `NoopNgxsExecutionStrategy` explicitly when the zone is nooped [#1819](https://github.com/ngxs/store/pull/1819)
- Fix: Devtools Plugin - Do not connect to devtools when the plugin is disabled [#1761](https://github.com/ngxs/store/pull/1761)
- Fix: Router Plugin - Cleanup subscriptions when the root view is destroyed [#1754](https://github.com/ngxs/store/pull/1754)
- Fix: WebSocket Plugin - Cleanup subscriptions and close the connection when the root view is destroyed [#1755](https://github.com/ngxs/store/pull/1755)
Expand Down
10 changes: 5 additions & 5 deletions bundlesize.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@
"path": "./@ngxs/store/fesm2015/ngxs-store.js",
"package": "@ngxs/store",
"target": "es2015",
"maxSize": "114.70KB",
"maxSize": "115.90KB",
"compression": "none"
},
{
"path": "./@ngxs/store/fesm5/ngxs-store.js",
"package": "@ngxs/store",
"target": "es5",
"maxSize": "133.60KB",
"maxSize": "134.80KB",
"compression": "none"
},
{
Expand Down Expand Up @@ -143,19 +143,19 @@
{
"path": "./integrations/hello-world-ng11-ivy/dist-integration/main.*.js",
"target": "es2015",
"maxSize": "250.90 kB",
"maxSize": "251.50 kB",
"compression": "none"
},
{
"path": "./integrations/hello-world-ng12-ivy/dist-integration/main.*.js",
"target": "es2015",
"maxSize": "236.50 kB",
"maxSize": "237.00 kB",
"compression": "none"
},
{
"path": "./integrations/hello-world-ng13-ivy/dist-integration/main.*.js",
"target": "es2015",
"maxSize": "236.80 kB",
"maxSize": "237.40 kB",
"compression": "none"
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { isPlatformServer } from '@angular/common';
import { NgxsExecutionStrategy } from './symbols';
import { getZoneWarningMessage } from '../configs/messages.config';

@Injectable()
@Injectable({ providedIn: 'root' })
export class DispatchOutsideZoneNgxsExecutionStrategy implements NgxsExecutionStrategy {
constructor(private _ngZone: NgZone, @Inject(PLATFORM_ID) private _platformId: string) {
// Caretaker note: we have still left the `typeof` condition in order to avoid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';

import { NgxsExecutionStrategy } from './symbols';

@Injectable()
@Injectable({ providedIn: 'root' })
export class NoopNgxsExecutionStrategy implements NgxsExecutionStrategy {
enter<T>(func: () => T): T {
return func();
Expand Down
28 changes: 26 additions & 2 deletions packages/store/src/execution/symbols.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import { InjectionToken } from '@angular/core';
import { InjectionToken, inject, INJECTOR, Type, ɵglobal } from '@angular/core';

import { NoopNgxsExecutionStrategy } from './noop-ngxs-execution-strategy';
import { DispatchOutsideZoneNgxsExecutionStrategy } from './dispatch-outside-zone-ngxs-execution-strategy';

/**
* The strategy that might be provided by users through `options.executionStrategy`.
*/
export const USER_PROVIDED_NGXS_EXECUTION_STRATEGY = new InjectionToken<
Type<NgxsExecutionStrategy> | undefined
>('USER_PROVIDED_NGXS_EXECUTION_STRATEGY');

/*
* Internal execution strategy injection token
*/
export const NGXS_EXECUTION_STRATEGY = new InjectionToken<NgxsExecutionStrategy>(
'NGXS_EXECUTION_STRATEGY'
'NGXS_EXECUTION_STRATEGY',
{
providedIn: 'root',
factory: () => {
const injector = inject(INJECTOR);
const executionStrategy = injector.get(USER_PROVIDED_NGXS_EXECUTION_STRATEGY);
return executionStrategy
? injector.get(executionStrategy)
: injector.get(
typeof ɵglobal.Zone !== 'undefined'
? DispatchOutsideZoneNgxsExecutionStrategy
: NoopNgxsExecutionStrategy
);
}
}
);

/*
Expand Down
7 changes: 3 additions & 4 deletions packages/store/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
NgxsModuleOptions,
ROOT_STATE_TOKEN
} from './symbols';
import { NGXS_EXECUTION_STRATEGY } from './execution/symbols';
import { USER_PROVIDED_NGXS_EXECUTION_STRATEGY } from './execution/symbols';
import { StateFactory } from './internal/state-factory';
import { StateContextFactory } from './internal/state-context-factory';
import { Actions, InternalActions } from './actions-stream';
Expand All @@ -32,7 +32,6 @@ import { StateStream } from './internal/state-stream';
import { PluginManager } from './plugin-manager';
import { NgxsRootModule } from './modules/ngxs-root.module';
import { NgxsFeatureModule } from './modules/ngxs-feature.module';
import { DispatchOutsideZoneNgxsExecutionStrategy } from './execution/dispatch-outside-zone-ngxs-execution-strategy';
import { InternalNgxsExecutionStrategy } from './execution/internal-ngxs-execution-strategy';
import { mergeDeep } from './utils/utils';

Expand Down Expand Up @@ -97,8 +96,8 @@ export class NgxsModule {
): Provider[] {
return [
{
provide: NGXS_EXECUTION_STRATEGY,
useClass: options.executionStrategy || DispatchOutsideZoneNgxsExecutionStrategy
provide: USER_PROVIDED_NGXS_EXECUTION_STRATEGY,
useValue: options.executionStrategy
},
{
provide: ROOT_STATE_TOKEN,
Expand Down
2 changes: 1 addition & 1 deletion packages/store/tests/dispatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('Dispatch', () => {
}
}

@Injectable()
@Injectable({ providedIn: 'root' })
class FakeExecutionStrategy implements NgxsExecutionStrategy {
enter<T>(func: () => T): T {
return func();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApplicationRef, NgZone, Component, Type } from '@angular/core';
import { ApplicationRef, NgZone, Component, Type, NgModule, ɵglobal } from '@angular/core';
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import { Observable } from 'rxjs';
import {
Expand All @@ -11,6 +11,11 @@ import {
Actions,
NoopNgxsExecutionStrategy
} from '@ngxs/store';
import { freshPlatform } from '@ngxs/store/internals/testing';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { NGXS_EXECUTION_STRATEGY } from '../../src/execution/symbols';

describe('NoopNgxsExecutionStrategy', () => {
class ZoneCounter {
Expand Down Expand Up @@ -86,6 +91,42 @@ describe('NoopNgxsExecutionStrategy', () => {
return { zone, store, ticks, get };
}

it(
'should provide NoopNgxsExecutionStrategy as an execution strategy if it is not specified explicitly',
freshPlatform(async () => {
// Arrange
const Zone = ɵglobal.Zone;
ɵglobal.Zone = undefined;

@Component({
selector: 'app-root',
template: ''
})
class TestComponent {}

@NgModule({
imports: [BrowserModule, NgxsModule.forRoot()],
declarations: [TestComponent],
bootstrap: [TestComponent]
})
class TestModule {}

// Act
const { injector } = await platformBrowserDynamic().bootstrapModule(TestModule, {
ngZone: 'noop'
});

// Assert
try {
expect(injector.get(NGXS_EXECUTION_STRATEGY)).toBeInstanceOf(
NoopNgxsExecutionStrategy
);
} finally {
ɵglobal.Zone = Zone;
}
})
);

describe('[store.select]', () => {
it('should be performed outside Angular zone, when dispatched from outside zones', () => {
// Arrange
Expand Down

0 comments on commit 8ecbd7f

Please sign in to comment.