Skip to content

Commit

Permalink
deps(workbench): update @scion/microfrontend-platform to version 1.0.…
Browse files Browse the repository at this point in the history
…0-rc.11

BREAKING CHANGE: Updating @scion/microfrontend-platform to version 1.0.0-rc.11 introduced a breaking change.

More information on how to migrate can be found in the [changelog](https://github.com/SchweizerischeBundesbahnen/scion-microfrontend-platform/blob/master/docs/site/changelog/changelog.md) of the SCION Microfrontend Platform.

*For Angular applications, we strongly recommend replacing zone-specific decorators for `MessageClient` and `IntentClient` with an `ObservableDecorator`. Otherwise, you may experience performance degradation due to frequent change detection cycles.*

To migrate:
- Remove decorators for `MessageClient` and `IntentClient`, including their registration in the bean manager (e.g., `NgZoneMessageClientDecorator` and `NgZoneIntentClientDecorator`).
- Provide a `NgZoneObservableDecorator` and register it in the bean manager before starting the platform. Note to register it as a bean, not as a decorator.

#### Example of an `ObservableDecorator` for Angular
```ts
export class NgZoneObservableDecorator implements ObservableDecorator {

  constructor(private zone: NgZone) {
  }

  public decorate$<T>(source$: Observable<T>): Observable<T> {
    return new Observable<T>(observer => {
      const insideAngular = NgZone.isInAngularZone();
      const subscription = source$
        .pipe(
          subscribeInside(fn => this.zone.runOutsideAngular(fn)),
          observeInside(fn => insideAngular ? this.zone.run(fn) : this.zone.runOutsideAngular(fn)),
        )
        .subscribe(observer);
      return () => subscription.unsubscribe();
    });
  }
}
```

#### Example of Registering an `ObservableDecorator` in Angular
```ts
const zone: NgZone = ...;

// Register decorator
Beans.register(ObservableDecorator, {useValue: new NgZoneObservableDecorator(zone)});
// Connect to the host
zone.runOutsideAngular(() => WorkbenchClient.connect(...));
```
  • Loading branch information
danielwiehl authored and Marcarrian committed Dec 7, 2022
1 parent f784a28 commit 34fec1d
Show file tree
Hide file tree
Showing 14 changed files with 99 additions and 217 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018-2022 Swiss Federal Railways
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/

import {Observable} from 'rxjs';
import {NgZone} from '@angular/core';
import {observeInside, subscribeInside} from '@scion/toolkit/operators';
import {ObservableDecorator} from '@scion/microfrontend-platform';

/**
* Mirrors the source, but ensures subscription and emission {@link NgZone} to be identical.
*/
export class NgZoneObservableDecorator implements ObservableDecorator {

constructor(private _zone: NgZone) {
}

public decorate$<T>(source$: Observable<T>): Observable<T> {
return new Observable<T>(observer => {
const insideAngular = NgZone.isInAngularZone();
const subscription = source$
.pipe(
subscribeInside(fn => this._zone.runOutsideAngular(fn)),
observeInside(fn => insideAngular ? this._zone.run(fn) : this._zone.runOutsideAngular(fn)),
)
.subscribe(observer);
return () => subscription.unsubscribe();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
* SPDX-License-Identifier: EPL-2.0
*/

import {APP_INITIALIZER, NgZone, Provider} from '@angular/core';
import {APP_IDENTITY, ContextService, FocusMonitor, IntentClient, ManifestService, MessageClient, OutletRouter, PlatformPropertyService, PreferredSizeService} from '@scion/microfrontend-platform';
import {APP_INITIALIZER, inject, NgZone, Provider} from '@angular/core';
import {APP_IDENTITY, ContextService, FocusMonitor, IntentClient, ManifestService, MessageClient, ObservableDecorator, OutletRouter, PlatformPropertyService, PreferredSizeService} from '@scion/microfrontend-platform';
import {WorkbenchClient, WorkbenchMessageBoxService, WorkbenchNotificationService, WorkbenchPopup, WorkbenchPopupService, WorkbenchRouter, WorkbenchView} from '@scion/workbench-client';
import {NgZoneIntentClientDecorator, NgZoneMessageClientDecorator} from './ng-zone-decorators';
import {NgZoneObservableDecorator} from './ng-zone-observable-decorator';
import {Beans} from '@scion/toolkit/bean-manager';
import {environment} from '../../environments/environment';

Expand All @@ -27,11 +27,8 @@ export function provideWorkbenchClientInitializer(): Provider[] {
{
provide: APP_INITIALIZER,
useFactory: connectToWorkbenchFn,
deps: [NgZoneMessageClientDecorator, NgZoneIntentClientDecorator, NgZone],
multi: true,
},
NgZoneMessageClientDecorator,
NgZoneIntentClientDecorator,
{provide: APP_IDENTITY, useFactory: () => Beans.get(APP_IDENTITY)},
{provide: MessageClient, useFactory: () => Beans.get(MessageClient)},
{provide: IntentClient, useFactory: () => Beans.get(IntentClient)},
Expand All @@ -53,11 +50,10 @@ export function provideWorkbenchClientInitializer(): Provider[] {
/**
* Connects this app to the workbench in the host app.
*/
export function connectToWorkbenchFn(ngZoneMessageClientDecorator: NgZoneMessageClientDecorator, ngZoneIntentClientDecorator: NgZoneIntentClientDecorator, zone: NgZone): () => Promise<void> {
export function connectToWorkbenchFn(): () => Promise<void> {
const zone = inject(NgZone);
return (): Promise<void> => {
Beans.registerDecorator(MessageClient, {useValue: ngZoneMessageClientDecorator});
Beans.registerDecorator(IntentClient, {useValue: ngZoneIntentClientDecorator});
// We connect to the host outside the Angular zone in order to avoid excessive change detection cycles of platform-internal subscriptions to global DOM events.
Beans.register(ObservableDecorator, {useValue: new NgZoneObservableDecorator(zone)});
return zone.runOutsideAngular(() => WorkbenchClient.connect(determineAppSymbolicName()));
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {Beans} from '@scion/toolkit/bean-manager';
/**
* Qualifier of the SCION DevTools view capability.
*/
const DEVTOOLS_QUALIFIER_MATCHER = new QualifierMatcher({component: 'devtools', vendor: 'scion'}, {evalAsterisk: false, evalOptional: false});
const DEVTOOLS_QUALIFIER_MATCHER = new QualifierMatcher({component: 'devtools', vendor: 'scion'});

/**
* Intercepts the DevTools view capability to pin it to the start page.
Expand Down
2 changes: 1 addition & 1 deletion apps/workbench-testing-app/src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const microfrontendPlatformConfig: MicrofrontendPlatformConfig = {
applications: [
{symbolicName: 'workbench-client-testing-app1', manifestUrl: 'http://localhost:4201/assets/manifest-app1.json', intentionRegisterApiDisabled: false},
{symbolicName: 'workbench-client-testing-app2', manifestUrl: 'http://localhost:4202/assets/manifest-app2.json', intentionRegisterApiDisabled: false},
{symbolicName: 'devtools', manifestUrl: 'https://scion-microfrontend-platform-devtools-v1-0-0-rc-10.vercel.app/assets/manifest.json', intentionCheckDisabled: true, scopeCheckDisabled: true},
{symbolicName: 'devtools', manifestUrl: 'https://scion-microfrontend-platform-devtools-v1-0-0-rc-11.vercel.app/assets/manifest.json', intentionCheckDisabled: true, scopeCheckDisabled: true},
],
properties: {
'workbench-client-testing-app1': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const microfrontendPlatformConfig: MicrofrontendPlatformConfig = {
applications: [
{symbolicName: 'workbench-client-testing-app1', manifestUrl: 'https://scion-workbench-client-testing-app1.vercel.app/assets/manifest-app1.json', intentionRegisterApiDisabled: false},
{symbolicName: 'workbench-client-testing-app2', manifestUrl: 'https://scion-workbench-client-testing-app2.vercel.app/assets/manifest-app2.json', intentionRegisterApiDisabled: false},
{symbolicName: 'devtools', manifestUrl: 'https://scion-microfrontend-platform-devtools-v1-0-0-rc-10.vercel.app/assets/manifest.json', intentionCheckDisabled: true, scopeCheckDisabled: true},
{symbolicName: 'devtools', manifestUrl: 'https://scion-microfrontend-platform-devtools-v1-0-0-rc-11.vercel.app/assets/manifest.json', intentionCheckDisabled: true, scopeCheckDisabled: true},
],
properties: {
'workbench-client-testing-app1': {
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"@angular/router": "14.2.3",
"@scion/components": "14.0.2",
"@scion/components.internal": "14.0.1",
"@scion/microfrontend-platform": "1.0.0-rc.10",
"@scion/microfrontend-platform": "1.0.0-rc.11",
"@scion/toolkit": "1.3.1",
"rxjs": "7.5.7",
"tslib": "2.4.0",
Expand Down
2 changes: 1 addition & 1 deletion projects/scion/workbench-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"peerDependencies": {
"rxjs": "^7.5.0",
"@scion/toolkit": "^1.0.0-0",
"@scion/microfrontend-platform": "^1.0.0-0"
"@scion/microfrontend-platform": "^1.0.0-rc.11"
},
"keywords": [
"scion",
Expand Down
2 changes: 1 addition & 1 deletion projects/scion/workbench/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@angular/router": "^14.0.0",
"@scion/components": "^14.0.0",
"@scion/toolkit": "^1.3.0",
"@scion/microfrontend-platform": "^1.0.0-rc.9",
"@scion/microfrontend-platform": "^1.0.0-rc.11",
"@scion/workbench-client": "^1.0.0-0",
"rxjs": "^7.5.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
*/

import {Injectable, Injector, NgZone, OnDestroy} from '@angular/core';
import {CapabilityInterceptor, HostManifestInterceptor, IntentClient, IntentInterceptor, MessageClient, MicrofrontendPlatform, MicrofrontendPlatformConfig, Runlevel} from '@scion/microfrontend-platform';
import {CapabilityInterceptor, HostManifestInterceptor, IntentInterceptor, MicrofrontendPlatform, MicrofrontendPlatformConfig, ObservableDecorator, Runlevel} from '@scion/microfrontend-platform';
import {Beans} from '@scion/toolkit/bean-manager';
import {Logger, LoggerNames} from '../../logging';
import {NgZoneIntentClientDecorator, NgZoneMessageClientDecorator} from './ng-zone-decorators';
import {NgZoneObservableDecorator} from './ng-zone-observable-decorator';
import {MICROFRONTEND_PLATFORM_POST_STARTUP, MICROFRONTEND_PLATFORM_PRE_STARTUP, runWorkbenchInitializers, WorkbenchInitializer} from '../../startup/workbench-initializer';
import {MicrofrontendPlatformConfigLoader} from '../microfrontend-platform-config-loader';
import {MicrofrontendViewIntentInterceptor} from '../routing/microfrontend-view-intent-interceptor.service';
Expand All @@ -29,8 +29,7 @@ export class MicrofrontendPlatformInitializer implements WorkbenchInitializer, O

constructor(private _microfrontendPlatformConfigLoader: MicrofrontendPlatformConfigLoader,
private _hostManifestInterceptor: WorkbenchHostManifestInterceptor,
private _ngZoneMessageClientDecorator: NgZoneMessageClientDecorator,
private _ngZoneIntentClientDecorator: NgZoneIntentClientDecorator,
private _ngZoneObservableDecorator: NgZoneObservableDecorator,
private _microfrontendViewIntentInterceptor: MicrofrontendViewIntentInterceptor,
private _microfrontendPopupIntentInterceptor: MicrofrontendPopupIntentInterceptor,
private _microfrontendViewCapabilityInterceptor: MicrofrontendViewCapabilityInterceptor,
Expand Down Expand Up @@ -61,9 +60,8 @@ export class MicrofrontendPlatformInitializer implements WorkbenchInitializer, O
// Register host manifest interceptor for the workbench to register workbench-specific intentions and capabilities.
Beans.register(HostManifestInterceptor, {useValue: this._hostManifestInterceptor, multi: true});

// Synchronize emissions of messaging Observables with the Angular zone.
Beans.registerDecorator(MessageClient, {useValue: this._ngZoneMessageClientDecorator});
Beans.registerDecorator(IntentClient, {useValue: this._ngZoneIntentClientDecorator});
// Synchronize emissions of Observables exposed by the SCION Microfrontend Platform with the Angular zone.
Beans.register(ObservableDecorator, {useValue: this._ngZoneObservableDecorator});

// Register view intent interceptor to translate view intents into workbench router commands.
Beans.register(IntentInterceptor, {useValue: this._microfrontendViewIntentInterceptor, multi: true});
Expand Down

This file was deleted.

Loading

0 comments on commit 34fec1d

Please sign in to comment.