1
1
/* eslint-disable @typescript-eslint/ban-ts-comment */
2
- import { Injectable , NgZone } from ' @angular/core' ;
2
+ import { Injectable , NgZone } from " @angular/core" ;
3
3
import {
4
4
Observable ,
5
5
Operator ,
@@ -9,30 +9,32 @@ import {
9
9
Subscription ,
10
10
TeardownLogic ,
11
11
asyncScheduler ,
12
- queueScheduler
13
- } from ' rxjs' ;
14
- import { observeOn , subscribeOn , tap } from ' rxjs/operators' ;
12
+ queueScheduler ,
13
+ } from " rxjs" ;
14
+ import { observeOn , subscribeOn , tap } from " rxjs/operators" ;
15
15
16
16
// eslint-disable-next-line @typescript-eslint/no-empty-function
17
- function noop ( ) {
18
- }
17
+ function noop ( ) { }
19
18
20
19
/**
21
20
* Schedules tasks so that they are invoked inside the Zone that is passed in the constructor.
22
21
*/
23
22
export class ɵZoneScheduler implements SchedulerLike {
24
- constructor ( private zone : any , private delegate : any = queueScheduler ) {
25
- }
23
+ constructor ( private zone : any , private delegate : any = queueScheduler ) { }
26
24
27
25
now ( ) {
28
26
return this . delegate . now ( ) ;
29
27
}
30
28
31
- schedule ( work : ( this : SchedulerAction < any > , state ?: any ) => void , delay ?: number , state ?: any ) : Subscription {
29
+ schedule (
30
+ work : ( this : SchedulerAction < any > , state ?: any ) => void ,
31
+ delay ?: number ,
32
+ state ?: any
33
+ ) : Subscription {
32
34
const targetZone = this . zone ;
33
35
// Wrap the specified work function to make sure that if nested scheduling takes place the
34
36
// work is executed in the correct zone
35
- const workInZone = function ( this : SchedulerAction < any > , state : any ) {
37
+ const workInZone = function ( this : SchedulerAction < any > , state : any ) {
36
38
targetZone . runGuarded ( ( ) => {
37
39
work . apply ( this , [ state ] ) ;
38
40
} ) ;
@@ -49,24 +51,32 @@ class BlockUntilFirstOperator<T> implements Operator<T, T> {
49
51
// @ts -ignore
50
52
private task : MacroTask | null = null ;
51
53
52
- constructor ( private zone : any ) {
53
- }
54
+ constructor ( private zone : any ) { }
54
55
55
56
call ( subscriber : Subscriber < T > , source : Observable < T > ) : TeardownLogic {
56
57
const unscheduleTask = this . unscheduleTask . bind ( this ) ;
57
58
// @ts -ignore
58
- this . task = this . zone . run ( ( ) => Zone . current . scheduleMacroTask ( 'firebaseZoneBlock' , noop , { } , noop , noop ) ) ;
59
+ this . task = this . zone . run ( ( ) =>
60
+ Zone . current . scheduleMacroTask ( "firebaseZoneBlock" , noop , { } , noop , noop )
61
+ ) ;
59
62
60
- return source . pipe (
61
- tap ( { next : unscheduleTask , complete : unscheduleTask , error : unscheduleTask } )
62
- ) . subscribe ( subscriber ) . add ( unscheduleTask ) ;
63
+ return source
64
+ . pipe (
65
+ tap ( {
66
+ next : unscheduleTask ,
67
+ complete : unscheduleTask ,
68
+ error : unscheduleTask ,
69
+ } )
70
+ )
71
+ . subscribe ( subscriber )
72
+ . add ( unscheduleTask ) ;
63
73
}
64
74
65
75
private unscheduleTask ( ) {
66
76
// maybe this is a race condition, invoke in a timeout
67
77
// hold for 10ms while I try to figure out what is going on
68
78
setTimeout ( ( ) => {
69
- if ( this . task != null && this . task . state === ' scheduled' ) {
79
+ if ( this . task != null && this . task . state === " scheduled" ) {
70
80
this . task . invoke ( ) ;
71
81
this . task = null ;
72
82
}
@@ -75,27 +85,34 @@ class BlockUntilFirstOperator<T> implements Operator<T, T> {
75
85
}
76
86
77
87
@Injectable ( {
78
- providedIn : ' root' ,
88
+ providedIn : " root" ,
79
89
} )
80
90
export class ɵAngularFireSchedulers {
81
91
public readonly outsideAngular : ɵZoneScheduler ;
82
92
public readonly insideAngular : ɵZoneScheduler ;
83
93
84
94
constructor ( public ngZone : NgZone ) {
85
95
// @ts -ignore
86
- this . outsideAngular = ngZone . runOutsideAngular ( ( ) => new ɵZoneScheduler ( Zone . current ) ) ;
96
+ this . outsideAngular = ngZone . runOutsideAngular (
97
+ ( ) => new ɵZoneScheduler ( Zone . current )
98
+ ) ;
87
99
// @ts -ignore
88
- this . insideAngular = ngZone . run ( ( ) => new ɵZoneScheduler ( Zone . current , asyncScheduler ) ) ;
100
+ this . insideAngular = ngZone . run (
101
+ ( ) => new ɵZoneScheduler ( Zone . current , asyncScheduler )
102
+ ) ;
89
103
globalThis . ɵAngularFireScheduler ||= this ;
90
104
}
91
105
}
92
106
93
107
function getSchedulers ( ) {
94
- const schedulers = globalThis . ɵAngularFireScheduler as ɵAngularFireSchedulers | undefined ;
108
+ const schedulers = globalThis . ɵAngularFireScheduler as
109
+ | ɵAngularFireSchedulers
110
+ | undefined ;
95
111
if ( ! schedulers ) {
96
112
throw new Error (
97
- `Either AngularFireModule has not been provided in your AppModule (this can be done manually or implictly using
98
- provideFirebaseApp) or you're calling an AngularFire method outside of an NgModule (which is not supported).` ) ;
113
+ `Either AngularFireModule has not been provided in your AppModule (this can be done manually or implictly using
114
+ provideFirebaseApp) or you're calling an AngularFire method outside of an NgModule (which is not supported).`
115
+ ) ;
99
116
}
100
117
return schedulers ;
101
118
}
@@ -126,11 +143,13 @@ export function keepUnstableUntilFirst<T>(obs$: Observable<T>): Observable<T> {
126
143
* value from firebase but doesn't block the zone forever since the firebase subscription
127
144
* is still alive.
128
145
*/
129
- export function ɵkeepUnstableUntilFirstFactory ( schedulers : ɵAngularFireSchedulers ) {
130
- return function keepUnstableUntilFirst < T > ( obs$ : Observable < T > ) : Observable < T > {
131
- obs$ = obs$ . lift (
132
- new BlockUntilFirstOperator ( schedulers . ngZone )
133
- ) ;
146
+ export function ɵkeepUnstableUntilFirstFactory (
147
+ schedulers : ɵAngularFireSchedulers
148
+ ) {
149
+ return function keepUnstableUntilFirst < T > (
150
+ obs$ : Observable < T >
151
+ ) : Observable < T > {
152
+ obs$ = obs$ . lift ( new BlockUntilFirstOperator ( schedulers . ngZone ) ) ;
134
153
135
154
return obs$ . pipe (
136
155
// Run the subscribe body outside of Angular (e.g. calling Firebase SDK to add a listener to a change event)
@@ -144,15 +163,18 @@ export function ɵkeepUnstableUntilFirstFactory(schedulers: ɵAngularFireSchedul
144
163
}
145
164
146
165
// @ts -ignore
147
- const zoneWrapFn = ( it : ( ...args : any [ ] ) => any , macrotask : MacroTask | undefined ) => {
166
+ const zoneWrapFn = (
167
+ it : ( ...args : any [ ] ) => any ,
168
+ macrotask : MacroTask | undefined
169
+ ) => {
148
170
// eslint-disable-next-line @typescript-eslint/no-this-alias
149
171
const _this = this ;
150
172
// function() is needed for the arguments object
151
- return function ( ) {
173
+ return function ( ) {
152
174
const _arguments = arguments ;
153
175
if ( macrotask ) {
154
176
setTimeout ( ( ) => {
155
- if ( macrotask . state === ' scheduled' ) {
177
+ if ( macrotask . state === " scheduled" ) {
156
178
macrotask . invoke ( ) ;
157
179
}
158
180
} , 10 ) ;
@@ -161,19 +183,27 @@ const zoneWrapFn = (it: (...args: any[]) => any, macrotask: MacroTask|undefined)
161
183
} ;
162
184
} ;
163
185
164
- export const ɵzoneWrap = < T = unknown > ( it : T , blockUntilFirst : boolean ) : T => {
186
+ export const ɵzoneWrap = < T = unknown > ( it : T , blockUntilFirst : boolean ) : T => {
165
187
// function() is needed for the arguments object
166
- return function ( ) {
188
+ return function ( ) {
167
189
// @ts -ignore
168
190
let macrotask : MacroTask | undefined ;
169
191
const _arguments = arguments ;
170
192
// if this is a callback function, e.g, onSnapshot, we should create a microtask and invoke it
171
193
// only once one of the callback functions is tripped.
172
194
for ( let i = 0 ; i < arguments . length ; i ++ ) {
173
- if ( typeof _arguments [ i ] === ' function' ) {
195
+ if ( typeof _arguments [ i ] === " function" ) {
174
196
if ( blockUntilFirst ) {
175
197
// @ts -ignore
176
- macrotask ||= run ( ( ) => Zone . current . scheduleMacroTask ( 'firebaseZoneBlock' , noop , { } , noop , noop ) ) ;
198
+ macrotask ||= run ( ( ) =>
199
+ Zone . current . scheduleMacroTask (
200
+ "firebaseZoneBlock" ,
201
+ noop ,
202
+ { } ,
203
+ noop ,
204
+ noop
205
+ )
206
+ ) ;
177
207
}
178
208
// TODO create a microtask to track callback functions
179
209
_arguments [ i ] = zoneWrapFn ( _arguments [ i ] , macrotask ) ;
@@ -185,7 +215,7 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
185
215
const schedulers = getSchedulers ( ) ;
186
216
return ret . pipe (
187
217
subscribeOn ( schedulers . outsideAngular ) ,
188
- observeOn ( schedulers . insideAngular ) ,
218
+ observeOn ( schedulers . insideAngular )
189
219
) ;
190
220
} else {
191
221
return run ( ( ) => ret ) ;
@@ -195,13 +225,21 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
195
225
return ret . pipe ( keepUnstableUntilFirst ) as any ;
196
226
} else if ( ret instanceof Promise ) {
197
227
// eslint-disable-next-line @typescript-eslint/no-misused-promises
198
- return run ( ( ) => new Promise ( ( resolve , reject ) => ret . then ( it => run ( ( ) => resolve ( it ) ) , reason => run ( ( ) => reject ( reason ) ) ) ) ) ;
199
- } else if ( typeof ret === 'function' && macrotask ) {
228
+ return run (
229
+ ( ) =>
230
+ new Promise ( ( resolve , reject ) =>
231
+ ret . then (
232
+ ( it ) => run ( ( ) => resolve ( it ) ) ,
233
+ ( reason ) => run ( ( ) => reject ( reason ) )
234
+ )
235
+ )
236
+ ) ;
237
+ } else if ( typeof ret === "function" && macrotask ) {
200
238
// Handle unsubscribe
201
239
// function() is needed for the arguments object
202
- return function ( ) {
240
+ return function ( ) {
203
241
setTimeout ( ( ) => {
204
- if ( macrotask && macrotask . state === ' scheduled' ) {
242
+ if ( macrotask && macrotask . state === " scheduled" ) {
205
243
macrotask . invoke ( ) ;
206
244
}
207
245
} , 10 ) ;
0 commit comments