Skip to content

Commit be162a3

Browse files
committed
Merge branch 'master' into fis-modularization
2 parents 8e36c93 + da1c7df commit be162a3

File tree

18 files changed

+161
-70
lines changed

18 files changed

+161
-70
lines changed

.changeset/small-grapes-teach.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@firebase/component": patch
3+
---
4+
5+
Correctly delete services created by modular SDKs when calling provider.delete()

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
"sinon": "9.0.3",
144144
"sinon-chai": "3.5.0",
145145
"source-map-loader": "1.0.2",
146-
"terser": "4.8.0",
146+
"terser": "5.2.1",
147147
"ts-loader": "8.0.3",
148148
"ts-node": "8.10.2",
149149
"tslint": "6.1.3",

packages-exp/app-exp/src/api.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ import {
2929
onLog
3030
} from './api';
3131
import { DEFAULT_ENTRY_NAME } from './constants';
32-
import { _FirebaseAppInternal } from '@firebase/app-types-exp';
32+
import {
33+
_FirebaseAppInternal,
34+
_FirebaseService
35+
} from '@firebase/app-types-exp';
3336
import {
3437
_clearComponents,
3538
_components,
@@ -175,6 +178,33 @@ describe('API tests', () => {
175178
deleteApp(app).catch(() => {});
176179
expect(getApps().length).to.equal(0);
177180
});
181+
182+
it('waits for all services being deleted', async () => {
183+
_clearComponents();
184+
let count = 0;
185+
const comp1 = new Component(
186+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
187+
'test1' as any,
188+
_container =>
189+
({
190+
_delete: async () => {
191+
await Promise.resolve();
192+
expect(count).to.equal(0);
193+
count++;
194+
}
195+
} as _FirebaseService),
196+
ComponentType.PUBLIC
197+
);
198+
_registerComponent(comp1);
199+
200+
const app = initializeApp({});
201+
// create service instance
202+
const test1Provider = _getProvider(app, 'test1' as any);
203+
test1Provider.getImmediate();
204+
205+
await deleteApp(app);
206+
expect(count).to.equal(1);
207+
});
178208
});
179209

180210
describe('registerVersion', () => {

packages-exp/app-exp/test/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class TestService implements _FirebaseService {
2525
return this.app_;
2626
}
2727

28-
delete(): Promise<void> {
28+
_delete(): Promise<void> {
2929
return new Promise((resolve: (v?: void) => void) => {
3030
setTimeout(() => resolve(), 10);
3131
});

packages-exp/app-types-exp/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export interface _FirebaseService {
113113
* Delete the service and free it's resources - called from
114114
* {@link @firebase/app-exp#deleteApp | deleteApp()}
115115
*/
116-
delete(): Promise<void>;
116+
_delete(): Promise<void>;
117117
}
118118

119119
export interface VersionService {

packages-exp/firebase-exp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"rollup-plugin-license": "2.2.0",
4646
"rollup-plugin-node-resolve": "5.2.0",
4747
"rollup-plugin-sourcemaps": "0.6.2",
48-
"rollup-plugin-terser": "6.1.0",
48+
"rollup-plugin-terser": "7.0.0",
4949
"rollup-plugin-typescript2": "0.27.2",
5050
"rollup-plugin-uglify": "6.0.4",
5151
"gulp": "4.0.2",

packages-exp/functions-exp/src/service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export class FunctionsService implements _FirebaseService {
9595
});
9696
}
9797

98-
delete(): Promise<void> {
98+
_delete(): Promise<void> {
9999
return this.deleteService();
100100
}
101101

packages/component/src/provider.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { expect } from 'chai';
1919
import { fake, SinonSpy } from 'sinon';
2020
import { ComponentContainer } from './component_container';
2121
import { FirebaseService } from '@firebase/app-types/private';
22+
import { _FirebaseService } from '@firebase/app-types-exp';
2223
import { Provider } from './provider';
2324
import { getFakeApp, getFakeComponent } from '../test/util';
2425
import '../test/setup';
@@ -202,7 +203,7 @@ describe('Provider', () => {
202203
});
203204

204205
describe('delete()', () => {
205-
it('calls delete() on the service instance that implements FirebaseService', () => {
206+
it('calls delete() on the service instance that implements legacy FirebaseService', () => {
206207
const deleteFake = fake();
207208
const myService: FirebaseService = {
208209
app: getFakeApp(),
@@ -226,6 +227,29 @@ describe('Provider', () => {
226227

227228
expect(deleteFake).to.have.been.called;
228229
});
230+
231+
it('calls delete() on the service instance that implements next FirebaseService', () => {
232+
const deleteFake = fake();
233+
const myService: _FirebaseService = {
234+
app: getFakeApp(),
235+
_delete: deleteFake
236+
};
237+
238+
// provide factory and create a service instance
239+
provider.setComponent(
240+
getFakeComponent(
241+
'test',
242+
() => myService,
243+
false,
244+
InstantiationMode.EAGER
245+
)
246+
);
247+
248+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
249+
provider.delete();
250+
251+
expect(deleteFake).to.have.been.called;
252+
});
229253
});
230254

231255
describe('clearCache()', () => {

packages/component/src/provider.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,16 @@ export class Provider<T extends Name> {
170170
async delete(): Promise<void> {
171171
const services = Array.from(this.instances.values());
172172

173-
await Promise.all(
174-
services
175-
.filter(service => 'INTERNAL' in service)
173+
await Promise.all([
174+
...services
175+
.filter(service => 'INTERNAL' in service) // legacy services
176176
// eslint-disable-next-line @typescript-eslint/no-explicit-any
177-
.map(service => (service as any).INTERNAL!.delete())
178-
);
177+
.map(service => (service as any).INTERNAL!.delete()),
178+
...services
179+
.filter(service => '_delete' in service) // modularized services
180+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
181+
.map(service => (service as any)._delete())
182+
]);
179183
}
180184

181185
isComponentSet(): boolean {

packages/firebase/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"rollup-plugin-license": "2.2.0",
6767
"rollup-plugin-node-resolve": "5.2.0",
6868
"rollup-plugin-sourcemaps": "0.6.2",
69-
"rollup-plugin-terser": "6.1.0",
69+
"rollup-plugin-terser": "7.0.0",
7070
"rollup-plugin-typescript2": "0.27.2",
7171
"rollup-plugin-uglify": "6.0.4",
7272
"typescript": "4.0.2"

packages/firestore/exp/src/api/components.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
OfflineComponentProvider,
2424
OnlineComponentProvider
2525
} from '../../../src/core/component_provider';
26-
import {handleUserChange, LocalStore} from '../../../src/local/local_store';
26+
import { handleUserChange, LocalStore } from '../../../src/local/local_store';
2727
import { Deferred } from '../../../src/util/promise';
2828
import { logDebug } from '../../../src/util/log';
2929
import { SyncEngine } from '../../../src/core/sync_engine';
@@ -71,7 +71,7 @@ export async function setOfflineComponentProvider(
7171
// When a user calls clearPersistence() in one client, all other clients
7272
// need to be terminated to allow the delete to succeed.
7373
offlineComponentProvider.persistence.setDatabaseDeletedListener(() =>
74-
firestore.delete()
74+
firestore._delete()
7575
);
7676
offlineDeferred.resolve(offlineComponentProvider);
7777
}

packages/firestore/exp/src/api/database.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ const LOG_TAG = 'Firestore';
6969
* The root reference to the Firestore database and the entry point for the
7070
* tree-shakeable SDK.
7171
*/
72-
export class Firestore extends LiteFirestore
72+
export class Firestore
73+
extends LiteFirestore
7374
implements firestore.FirebaseFirestore, _FirebaseService {
7475
readonly _queue = new AsyncQueue();
7576
readonly _persistenceKey: string;
@@ -320,7 +321,7 @@ export function terminate(
320321
): Promise<void> {
321322
_removeServiceInstance(firestore.app, 'firestore-exp');
322323
const firestoreImpl = cast(firestore, Firestore);
323-
return firestoreImpl.delete();
324+
return firestoreImpl._delete();
324325
}
325326

326327
function verifyNotInitialized(firestore: Firestore): void {

packages/firestore/lite/src/api/database.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export class Firestore
9595
return new DatabaseId(app.options.projectId!);
9696
}
9797

98-
delete(): Promise<void> {
98+
_delete(): Promise<void> {
9999
if (!this._terminateTask) {
100100
this._terminateTask = this._terminate();
101101
}
@@ -117,7 +117,7 @@ export class Firestore
117117
// TODO(firestoreexp): `deleteApp()` should call the delete method above,
118118
// but it still calls INTERNAL.delete().
119119
INTERNAL = {
120-
delete: () => this.delete()
120+
delete: () => this._delete()
121121
};
122122
}
123123

@@ -142,5 +142,5 @@ export function terminate(
142142
): Promise<void> {
143143
_removeServiceInstance(firestore.app, 'firestore/lite');
144144
const firestoreClient = cast(firestore, Firestore);
145-
return firestoreClient.delete();
145+
return firestoreClient._delete();
146146
}

packages/firestore/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"rollup-plugin-node-resolve": "5.2.0",
8787
"rollup-plugin-replace": "2.2.0",
8888
"rollup-plugin-sourcemaps": "0.6.2",
89-
"rollup-plugin-terser": "6.1.0",
89+
"rollup-plugin-terser": "7.0.0",
9090
"rollup-plugin-typescript2": "0.27.2",
9191
"ts-node": "8.10.2",
9292
"typescript": "4.0.2"

repo-scripts/size-analysis/analysis-helper.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,20 @@ export async function extractDependenciesAndSize(
116116
externalDepsNotResolvedOutput,
117117
'utf-8'
118118
);
119-
const externalDepsResolvedOutputContentMinimized: terser.MinifyOutput = terser.minify(
119+
const externalDepsResolvedOutputContentMinimized = await terser.minify(
120120
externalDepsResolvedOutputContent,
121121
{
122-
output: {
122+
format: {
123123
comments: false
124124
},
125125
mangle: { toplevel: true },
126126
compress: false
127127
}
128128
);
129-
const externalDepsNotResolvedOutputContentMinimized: terser.MinifyOutput = terser.minify(
129+
const externalDepsNotResolvedOutputContentMinimized = await terser.minify(
130130
externalDepsNotResolvedOutputContent,
131131
{
132-
output: {
132+
format: {
133133
comments: false
134134
},
135135
mangle: { toplevel: true },

repo-scripts/size-analysis/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"rollup-plugin-typescript2": "0.27.2",
2727
"tmp": "0.2.1",
2828
"typescript": "4.0.2",
29-
"terser": "4.8.0",
29+
"terser": "5.2.1",
3030
"yargs": "15.4.1",
3131
"@firebase/util": "0.3.1"
3232
},

scripts/size_report/report_binary_size.ts

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function generateReportForCDNScripts(): Report[] {
6565
}
6666

6767
// NPM packages
68-
function generateReportForNPMPackages(): Report[] {
68+
async function generateReportForNPMPackages(): Promise<Report[]> {
6969
const reports: Report[] = [];
7070
const fields = [
7171
'main',
@@ -81,41 +81,50 @@ function generateReportForNPMPackages(): Report[] {
8181
execSync('npx lerna ls --json --scope @firebase/*').toString()
8282
);
8383

84+
const taskPromises: Promise<void>[] = [];
8485
for (const pkg of packageInfo) {
8586
// we traverse the dir in order to include binaries for submodules, e.g. @firebase/firestore/memory
8687
// Currently we only traverse 1 level deep because we don't have any submodule deeper than that.
8788
traverseDirs(pkg.location, collectBinarySize, 0, 1);
8889
}
8990

90-
function collectBinarySize(path: string) {
91-
const packageJsonPath = `${path}/package.json`;
92-
if (!fs.existsSync(packageJsonPath)) {
93-
return;
94-
}
95-
96-
const packageJson = require(packageJsonPath);
91+
await Promise.all(taskPromises);
9792

98-
for (const field of fields) {
99-
if (packageJson[field]) {
100-
const filePath = `${path}/${packageJson[field]}`;
101-
const rawCode = fs.readFileSync(filePath, 'utf-8');
93+
return reports;
10294

103-
// remove comments and whitespaces, then get size
104-
const { code } = terser.minify(rawCode, {
105-
output: {
106-
comments: false
107-
},
108-
mangle: false,
109-
compress: false
110-
});
95+
function collectBinarySize(path: string) {
96+
const promise = new Promise<void>(async resolve => {
97+
const packageJsonPath = `${path}/package.json`;
98+
if (!fs.existsSync(packageJsonPath)) {
99+
return;
100+
}
111101

112-
const size = Buffer.byteLength(code!, 'utf-8');
113-
reports.push(makeReportObject(packageJson.name, field, size));
102+
const packageJson = require(packageJsonPath);
103+
104+
for (const field of fields) {
105+
if (packageJson[field]) {
106+
const filePath = `${path}/${packageJson[field]}`;
107+
const rawCode = fs.readFileSync(filePath, 'utf-8');
108+
109+
// remove comments and whitespaces, then get size
110+
const { code } = await terser.minify(rawCode, {
111+
format: {
112+
comments: false
113+
},
114+
mangle: false,
115+
compress: false
116+
});
117+
118+
const size = Buffer.byteLength(code!, 'utf-8');
119+
reports.push(makeReportObject(packageJson.name, field, size));
120+
}
114121
}
115-
}
116-
}
117122

118-
return reports;
123+
resolve();
124+
});
125+
126+
taskPromises.push(promise);
127+
}
119128
}
120129

121130
function traverseDirs(
@@ -147,10 +156,10 @@ function makeReportObject(sdk: string, type: string, value: number): Report {
147156
};
148157
}
149158

150-
function generateSizeReport(): BinarySizeRequestBody {
159+
async function generateSizeReport(): Promise<BinarySizeRequestBody> {
151160
const reports: Report[] = [
152161
...generateReportForCDNScripts(),
153-
...generateReportForNPMPackages()
162+
...(await generateReportForNPMPackages())
154163
];
155164

156165
for (const r of reports) {
@@ -168,5 +177,6 @@ function generateSizeReport(): BinarySizeRequestBody {
168177
};
169178
}
170179

171-
const report = generateSizeReport();
172-
upload(report, RequestEndpoint.BINARY_SIZE);
180+
generateSizeReport().then(report => {
181+
upload(report, RequestEndpoint.BINARY_SIZE);
182+
});

0 commit comments

Comments
 (0)