Skip to content

Commit af49fbd

Browse files
committed
Add to app-compat
1 parent 4fc5410 commit af49fbd

File tree

3 files changed

+94
-10
lines changed

3 files changed

+94
-10
lines changed

packages-exp/app-compat/src/firebaseApp.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
Component,
2121
ComponentContainer,
2222
ComponentType,
23+
InstantiationMode,
2324
Name
2425
} from '@firebase/component';
2526
import {
@@ -121,8 +122,17 @@ export class FirebaseAppImpl implements Compat<_FirebaseAppExp>, _FirebaseApp {
121122
): _FirebaseService {
122123
this._delegate.checkDestroyed();
123124

125+
// Initialize instance if InstatiationMode is `EXPLICIT`.
126+
const provider = this._delegate.container.getProvider(name as Name);
127+
if (
128+
!provider.isInitialized() &&
129+
provider.getComponent()?.instantiationMode === InstantiationMode.EXPLICIT
130+
) {
131+
provider.initialize();
132+
}
133+
124134
// getImmediate will always succeed because _getService is only called for registered components.
125-
return (this._delegate.container.getProvider(name as Name).getImmediate({
135+
return (provider.getImmediate({
126136
identifier: instanceIdentifier
127137
}) as unknown) as _FirebaseService;
128138
}

packages-exp/app-compat/test/firebaseAppCompat.test.ts

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ import { stub } from 'sinon';
2121
import { FirebaseNamespace, FirebaseOptions } from '../src/public-types';
2222
import { _FirebaseApp, _FirebaseNamespace } from '../src/types';
2323
import { _components, _clearComponents } from '@firebase/app-exp';
24-
import { ComponentType } from '@firebase/component';
24+
import {
25+
Component,
26+
ComponentType,
27+
InstantiationMode
28+
} from '@firebase/component';
2529

2630
import { createFirebaseNamespace } from '../src/firebaseNamespace';
2731
import { createFirebaseNamespaceLite } from '../src/lite/firebaseNamespaceLite';
@@ -67,6 +71,7 @@ function executeFirebaseTests(): void {
6771

6872
expect(serviceNamespace).to.eq(serviceNamespace2);
6973
expect(registerStub).to.have.not.thrown();
74+
registerStub.restore();
7075
});
7176

7277
it('returns cached service instances', () => {
@@ -80,6 +85,71 @@ function executeFirebaseTests(): void {
8085
expect(service).to.eq((firebase as any).test());
8186
});
8287

88+
it('does not instantiate explicit components unless called explicitly', () => {
89+
firebase.initializeApp({});
90+
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(
91+
createTestComponent('explicit1').setInstantiationMode(
92+
InstantiationMode.EXPLICIT
93+
)
94+
);
95+
96+
let explicitService;
97+
98+
// Expect getImmediate in a consuming component to return null.
99+
const consumerComponent = new Component(
100+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
101+
'consumer' as any,
102+
container => {
103+
explicitService = container
104+
.getProvider('explicit1' as any)
105+
.getImmediate({ optional: true });
106+
return new TestService(
107+
container.getProvider('app-compat').getImmediate()
108+
);
109+
},
110+
ComponentType.PUBLIC
111+
);
112+
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(
113+
consumerComponent
114+
);
115+
116+
(firebase as any).consumer();
117+
expect(explicitService).to.be.null;
118+
});
119+
120+
it('does instantiate explicit components when called explicitly', () => {
121+
firebase.initializeApp({});
122+
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(
123+
createTestComponent('explicit2').setInstantiationMode(
124+
InstantiationMode.EXPLICIT
125+
)
126+
);
127+
128+
let explicitService;
129+
130+
// Expect getImmediate in a consuming component to return the service.
131+
const consumerComponent = new Component(
132+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
133+
'consumer' as any,
134+
container => {
135+
explicitService = container
136+
.getProvider('explicit2' as any)
137+
.getImmediate({ optional: true });
138+
return new TestService(
139+
container.getProvider('app-compat').getImmediate()
140+
);
141+
},
142+
ComponentType.PUBLIC
143+
);
144+
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(
145+
consumerComponent
146+
);
147+
148+
(firebase as any).explicit2();
149+
(firebase as any).consumer();
150+
expect(explicitService).to.not.be.null;
151+
});
152+
83153
it(`creates a new instance of a service after removing the existing instance`, () => {
84154
const app = firebase.initializeApp({});
85155
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(

packages/app/test/firebaseApp.test.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,25 @@ function executeFirebaseTests(): void {
8484
expect(service).to.eq((firebase as any).test());
8585
});
8686

87-
it('does not instantiate explicit components unless called explicitly', done => {
87+
it('does not instantiate explicit components unless called explicitly', () => {
8888
firebase.initializeApp({});
8989
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(
9090
createTestComponent('test').setInstantiationMode(
9191
InstantiationMode.EXPLICIT
9292
)
9393
);
9494

95+
let explicitService;
96+
9597
// Expect getImmediate in a consuming component to return null.
9698
const consumerComponent = new Component(
9799
// eslint-disable-next-line @typescript-eslint/no-explicit-any
98100
'consumer' as any,
99101
container => {
100-
const testService = container
102+
explicitService = container
101103
.getProvider('test' as any)
102104
.getImmediate({ optional: true });
103-
expect(testService).to.be.null;
104-
done();
105+
return new TestService(container.getProvider('app').getImmediate());
105106
},
106107
ComponentType.PUBLIC
107108
);
@@ -110,26 +111,28 @@ function executeFirebaseTests(): void {
110111
);
111112

112113
(firebase as any).consumer();
114+
expect(explicitService).to.be.null;
113115
});
114116

115-
it('does instantiate explicit components when called explicitly', done => {
117+
it('does instantiate explicit components when called explicitly', () => {
116118
firebase.initializeApp({});
117119
(firebase as _FirebaseNamespace).INTERNAL.registerComponent(
118120
createTestComponent('test').setInstantiationMode(
119121
InstantiationMode.EXPLICIT
120122
)
121123
);
122124

125+
let explicitService;
126+
123127
// Expect getImmediate in a consuming component to return the service.
124128
const consumerComponent = new Component(
125129
// eslint-disable-next-line @typescript-eslint/no-explicit-any
126130
'consumer' as any,
127131
container => {
128-
const testService = container
132+
explicitService = container
129133
.getProvider('test' as any)
130134
.getImmediate({ optional: true });
131-
expect(testService).to.not.be.null;
132-
done();
135+
return new TestService(container.getProvider('app').getImmediate());
133136
},
134137
ComponentType.PUBLIC
135138
);
@@ -139,6 +142,7 @@ function executeFirebaseTests(): void {
139142

140143
(firebase as any).test();
141144
(firebase as any).consumer();
145+
expect(explicitService).to.not.be.null;
142146
});
143147

144148
it(`creates a new instance of a service after removing the existing instance`, () => {

0 commit comments

Comments
 (0)