Skip to content

Commit 7d643c0

Browse files
authored
feat(scully runtime config): user forRoot to pass config to Scully (#271)
* feat(Scully runtime config): user forRoot to pass config to Scully The transfer-state service now only gets activated when the config using forRoot says so. * fix(scullyconfig.ts): turn default of useTranferState to `true` to prevent breaking change This is a better default as it's not breaking anymore, but still enables people to opt-out
1 parent 2da6614 commit 7d643c0

5 files changed

Lines changed: 47 additions & 20 deletions

File tree

projects/sampleBlog/src/app/app.module.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ import {AppComponent} from './app.component';
77

88
@NgModule({
99
declarations: [AppComponent],
10-
imports: [BrowserModule, HttpClientModule, AppRoutingModule, ScullyLibModule],
10+
imports: [
11+
BrowserModule,
12+
HttpClientModule,
13+
AppRoutingModule,
14+
ScullyLibModule.forRoot({useTranferState: true}),
15+
],
1116
bootstrap: [AppComponent],
1217
})
1318
export class AppModule {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {InjectionToken} from '@angular/core';
2+
3+
export interface ScullyLibConfig {
4+
useTranferState: boolean;
5+
}
6+
7+
export const ScullyDefaultSettings: ScullyLibConfig = {
8+
useTranferState: true,
9+
};
10+
11+
export const SCULLY_LIB_CONFIG = new InjectionToken<ScullyLibConfig>('scullyLibConfig', {
12+
factory: () => ScullyDefaultSettings,
13+
});

projects/scullyio/ng-lib/src/lib/idleMonitor/idle-monitor.service.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import {Injectable, NgZone} from '@angular/core';
1+
import {Inject, Injectable, NgZone} from '@angular/core';
22
import {NavigationEnd, Router} from '@angular/router';
33
import {BehaviorSubject} from 'rxjs';
44
import {filter, pluck, take, tap} from 'rxjs/operators';
5+
import {ScullyLibConfig, SCULLY_LIB_CONFIG} from '../config/scully-config';
56
import {TransferStateService} from '../transfer-state/transfer-state.service';
7+
import {isScullyRunning} from '../utils/isScully';
68

79
// tslint:disable-next-line: no-any
810
// tslint:disable: no-string-literal
@@ -27,8 +29,13 @@ export class IdleMonitorService {
2729
private appReady = new Event('AngularReady', {bubbles: true, cancelable: false});
2830
private appTimeout = new Event('AngularTimeout', {bubbles: true, cancelable: false});
2931

30-
constructor(private zone: NgZone, private router: Router, private tss: TransferStateService) {
31-
if (window) {
32+
constructor(
33+
private zone: NgZone,
34+
private router: Router,
35+
@Inject(SCULLY_LIB_CONFIG) conf: ScullyLibConfig,
36+
tss: TransferStateService
37+
) {
38+
if (window && isScullyRunning()) {
3239
window.dispatchEvent(this.initApp);
3340
this.router.events
3441
.pipe(
@@ -37,6 +44,10 @@ export class IdleMonitorService {
3744
)
3845
.subscribe();
3946
}
47+
if (conf && conf.useTranferState) {
48+
/** don't start monitoring if people don't use the transferState */
49+
tss.startMonitoring();
50+
}
4051
}
4152

4253
public async init() {

projects/scullyio/ng-lib/src/lib/scully-lib.module.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {NgModule} from '@angular/core';
1+
import {ModuleWithProviders, NgModule} from '@angular/core';
2+
import {ScullyDefaultSettings, ScullyLibConfig, SCULLY_LIB_CONFIG} from './config/scully-config';
23
import {IdleMonitorService} from './idleMonitor/idle-monitor.service';
34
import {ScullyContentModule} from './scully-content/scully-content.module';
45

@@ -14,5 +15,11 @@ export class ScullyLibModule {
1415
* there will be only 1 instance in our app.
1516
* We don't need forRoot, as we are not configuring anything in here.
1617
*/
18+
static forRoot(config: ScullyLibConfig = ScullyDefaultSettings): ModuleWithProviders {
19+
return {
20+
ngModule: ScullyLibModule,
21+
providers: [{provide: SCULLY_LIB_CONFIG, useValue: config}],
22+
};
23+
}
1724
constructor(private idle: IdleMonitorService) {}
1825
}

projects/scullyio/ng-lib/src/lib/transfer-state/transfer-state.service.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ export class TransferStateService {
2727
private stateBS = new BehaviorSubject<State>({});
2828
private state$ = this.stateBS.pipe(filter(state => state !== undefined));
2929

30-
constructor(@Inject(DOCUMENT) private document: Document, private router: Router) {
30+
constructor(@Inject(DOCUMENT) private document: Document, private router: Router) {}
31+
32+
startMonitoring() {
3133
this.setupEnvForTransferState();
3234
this.setupNavStartDataFetching();
3335
}
@@ -50,22 +52,10 @@ export class TransferStateService {
5052
/**
5153
* Getstate will return an observable that fires once and completes.
5254
* It does so right after the navigation for the page has finished.
55+
* please note, this works SYNC on initial route, preventing a flash of content.
5356
* @param name The name of the state to
5457
*/
5558
getState<T>(name: string): Observable<T> {
56-
/**
57-
* We need the initial state only when the app is booting.
58-
* In this case, the router doesn't fire an event.
59-
* As the boot process is SYNC, putting in anything async will cause flicker in the view.
60-
* we can't use the subject in this case, because it will fire the
61-
* data sync before the component is ready.
62-
*/
63-
// if (this.initial) {
64-
// this.initial = false;
65-
// // this.stateBS.next(this.state);
66-
// return of(this.state[name]);
67-
// }
68-
/** once booted, the router will make sure this event fires after navigation */
6959
return this.state$.pipe(pluck(name));
7060
}
7161

@@ -92,6 +82,7 @@ export class TransferStateService {
9282
filter(e => e instanceof NavigationStart),
9383
switchMap((e: NavigationStart) => {
9484
if (this.initialUrl === e.url) {
85+
/** don't kick off on initial load to prevent flicker */
9586
this.initialUrl = '__done__with__Initial__navigation__';
9687
return NEVER;
9788
}
@@ -113,7 +104,7 @@ export class TransferStateService {
113104
}),
114105
]);
115106
}),
116-
/** parse out the relevant piece off text, and conver to json */
107+
/** parse out the relevant piece off text, and convert to json */
117108
map(([e, html]: [any, string]) => {
118109
try {
119110
const newStateStr = html.split(SCULLY_STATE_START)[1].split(SCULLY_STATE_END)[0];

0 commit comments

Comments
 (0)