diff --git a/.changeset/config.json b/.changeset/config.json index 1aea6d127a0..038541fb90b 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -24,6 +24,7 @@ "@firebase/installations-compat", "@firebase/messaging-exp", "@firebase/performance-exp", + "@firebase/performance-compat", "@firebase/remote-config-exp", "@firebase/remote-config-compat", "firebase-exp", diff --git a/packages-exp/performance-compat/.eslintrc.js b/packages-exp/performance-compat/.eslintrc.js new file mode 100644 index 00000000000..ca80aa0f69a --- /dev/null +++ b/packages-exp/performance-compat/.eslintrc.js @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + extends: '../../config/.eslintrc.js', + parserOptions: { + project: 'tsconfig.json', + // to make vscode-eslint work with monorepo + // https://github.com/typescript-eslint/typescript-eslint/issues/251#issuecomment-463943250 + tsconfigRootDir: __dirname + } +}; diff --git a/packages-exp/performance-compat/README.md b/packages-exp/performance-compat/README.md new file mode 100644 index 00000000000..eb4da067f01 --- /dev/null +++ b/packages-exp/performance-compat/README.md @@ -0,0 +1,5 @@ +# @firebase/performance-compat + +This is the compat package that recreates the v8 APIs. + +**This package is not intended for direct usage, and should only be used via the officially supported [firebase](https://www.npmjs.com/package/firebase) package.** diff --git a/packages-exp/performance-compat/karma.conf.js b/packages-exp/performance-compat/karma.conf.js new file mode 100644 index 00000000000..c0737457c55 --- /dev/null +++ b/packages-exp/performance-compat/karma.conf.js @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const karmaBase = require('../../config/karma.base'); + +const files = ['test/**/*', 'src/**/*.test.ts']; + +module.exports = function (config) { + const karmaConfig = Object.assign({}, karmaBase, { + // files to load into karma + files: files, + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + preprocessors: { '**/*.ts': ['webpack', 'sourcemap'] }, + frameworks: ['mocha'] + }); + + config.set(karmaConfig); +}; + +module.exports.files = files; diff --git a/packages-exp/performance-compat/package.json b/packages-exp/performance-compat/package.json new file mode 100644 index 00000000000..89159441f8b --- /dev/null +++ b/packages-exp/performance-compat/package.json @@ -0,0 +1,61 @@ +{ + "name": "@firebase/performance-compat", + "version": "0.0.900", + "description": "The compatibility package of Firebase Performance", + "author": "Firebase (https://firebase.google.com/)", + "private": true, + "main": "dist/index.cjs.js", + "browser": "dist/index.esm5.js", + "module": "dist/index.esm5.js", + "esm2017": "dist/index.esm2017.js", + "files": ["dist"], + "scripts": { + "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", + "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", + "build": "rollup -c", + "build:release": "rollup -c rollup.config.release.js", + "build:deps": "lerna run --scope @firebase/performance-compat --include-dependencies build", + "dev": "rollup -c -w", + "test": "run-p lint test:all", + "test:all": "run-p test:browser", + "test:ci": "node ../../scripts/run_tests_in_ci.js -s test:all", + "test:browser": "karma start --single-run", + "test:browser:debug": "karma start --browsers Chrome --auto-watch", + "prettier": "prettier --write '{src,test}/**/*.{js,ts}'" + }, + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-compat": "0.x", + "@firebase/app-types": "0.x" + }, + "dependencies": { + "@firebase/performance-exp": "0.0.900", + "@firebase/util": "0.4.0", + "@firebase/logger": "0.2.6", + "@firebase/component": "0.2.1", + "tslib": "^2.0.0" + }, + "devDependencies": { + "rollup": "2.35.1", + "@rollup/plugin-json": "4.1.0", + "rollup-plugin-replace": "2.2.0", + "rollup-plugin-typescript2": "0.29.0", + "typescript": "4.2.2", + "@firebase/app-compat": "0.0.900" + }, + "repository": { + "directory": "packages-exp/performance-compat", + "type": "git", + "url": "https://github.com/firebase/firebase-js-sdk.git" + }, + "bugs": { + "url": "https://github.com/firebase/firebase-js-sdk/issues" + }, + "typings": "dist/src/index.d.ts", + "nyc": { + "extension": [ + ".ts" + ], + "reportDir": "./coverage/node" + } +} diff --git a/packages-exp/performance-compat/rollup.config.js b/packages-exp/performance-compat/rollup.config.js new file mode 100644 index 00000000000..4df9d8a2f48 --- /dev/null +++ b/packages-exp/performance-compat/rollup.config.js @@ -0,0 +1,60 @@ +/** + * @license + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import typescriptPlugin from 'rollup-plugin-typescript2'; +import typescript from 'typescript'; +import json from '@rollup/plugin-json'; +import { es5BuildsNoPlugin, es2017BuildsNoPlugin } from './rollup.shared.js'; + +/** + * ES5 Builds + */ +const es5BuildPlugins = [ + typescriptPlugin({ + typescript + }), + json() +]; + +const es5Builds = es5BuildsNoPlugin.map(build => ({ + ...build, + plugins: es5BuildPlugins +})); + +/** + * ES2017 Builds + */ +const es2017BuildPlugins = [ + typescriptPlugin({ + typescript, + tsconfigOverride: { + compilerOptions: { + target: 'es2017' + } + } + }), + json({ + preferConst: true + }) +]; + +const es2017Builds = es2017BuildsNoPlugin.map(build => ({ + ...build, + plugins: es2017BuildPlugins +})); + +export default [...es5Builds, ...es2017Builds]; diff --git a/packages-exp/performance-compat/rollup.config.release.js b/packages-exp/performance-compat/rollup.config.release.js new file mode 100644 index 00000000000..b0b1dc5154a --- /dev/null +++ b/packages-exp/performance-compat/rollup.config.release.js @@ -0,0 +1,67 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import typescriptPlugin from 'rollup-plugin-typescript2'; +import typescript from 'typescript'; +import json from '@rollup/plugin-json'; +import { es5BuildsNoPlugin, es2017BuildsNoPlugin } from './rollup.shared.js'; +import { importPathTransformer } from '../../scripts/exp/ts-transform-import-path'; + +/** + * ES5 Builds + */ +const es5BuildPlugins = [ + typescriptPlugin({ + typescript, + clean: true, + abortOnError: false, + transformers: [importPathTransformer] + }), + json() +]; + +const es5Builds = es5BuildsNoPlugin.map(build => ({ + ...build, + plugins: es5BuildPlugins +})); + +/** + * ES2017 Builds + */ +const es2017BuildPlugins = [ + typescriptPlugin({ + typescript, + tsconfigOverride: { + compilerOptions: { + target: 'es2017' + } + }, + clean: true, + abortOnError: false, + transformers: [importPathTransformer] + }), + json({ + preferConst: true + }) +]; + +const es2017Builds = es2017BuildsNoPlugin.map(build => ({ + ...build, + plugins: es2017BuildPlugins +})); + +export default [...es5Builds, ...es2017Builds]; diff --git a/packages-exp/performance-compat/rollup.shared.js b/packages-exp/performance-compat/rollup.shared.js new file mode 100644 index 00000000000..5474a15ba7c --- /dev/null +++ b/packages-exp/performance-compat/rollup.shared.js @@ -0,0 +1,51 @@ +/** + * @license + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import pkg from './package.json'; + +const deps = Object.keys( + Object.assign({}, pkg.peerDependencies, pkg.dependencies) +); + +export const es5BuildsNoPlugin = [ + /** + * Browser Builds + */ + { + input: 'src/index.ts', + output: [ + { file: pkg.main, format: 'cjs', sourcemap: true }, + { file: pkg.browser, format: 'es', sourcemap: true } + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + } +]; + +export const es2017BuildsNoPlugin = [ + /** + * Browser Builds + */ + { + input: 'src/index.ts', + output: { + file: pkg.esm2017, + format: 'es', + sourcemap: true + }, + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + } +]; diff --git a/packages-exp/performance-compat/src/index.ts b/packages-exp/performance-compat/src/index.ts new file mode 100644 index 00000000000..2a18854193d --- /dev/null +++ b/packages-exp/performance-compat/src/index.ts @@ -0,0 +1,57 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import firebase, { _FirebaseNamespace } from '@firebase/app-compat'; +import { + Component, + ComponentContainer, + ComponentType +} from '@firebase/component'; +import { PerformanceCompatImpl } from './performance'; +import { name as packageName, version } from '../package.json'; +import { FirebasePerformance as FirebasePerformanceCompat } from '@firebase/performance-types'; + +// TODO: move it to the future performance-compat-types package +declare module '@firebase/component' { + interface NameServiceMapping { + 'performance-compat': FirebasePerformanceCompat; + } +} + +function registerPerformanceCompat(firebaseInstance: _FirebaseNamespace): void { + firebaseInstance.INTERNAL.registerComponent( + new Component( + 'performance-compat', + performanceFactory, + ComponentType.PUBLIC + ) + ); + + firebaseInstance.registerVersion(packageName, version); +} + +function performanceFactory( + container: ComponentContainer +): PerformanceCompatImpl { + const app = container.getProvider('app-compat').getImmediate(); + // The following call will always succeed. + const performance = container.getProvider('performance-exp').getImmediate(); + + return new PerformanceCompatImpl(app, performance); +} + +registerPerformanceCompat(firebase as _FirebaseNamespace); diff --git a/packages-exp/performance-compat/src/performance.test.ts b/packages-exp/performance-compat/src/performance.test.ts new file mode 100644 index 00000000000..1ef81428e7b --- /dev/null +++ b/packages-exp/performance-compat/src/performance.test.ts @@ -0,0 +1,66 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '../test/setup'; +import { expect } from 'chai'; +import { stub } from 'sinon'; +import { + getFakeApp, + getFakeModularPerformance, + getFakeModularPerformanceTrace +} from '../test/util'; +import * as perfModularApi from '@firebase/performance-exp'; +import { PerformanceCompatImpl } from './performance'; + +describe('Performance Compat', () => { + let performanceCompat!: PerformanceCompatImpl; + let fakeModularPerformance!: perfModularApi.FirebasePerformance; + + beforeEach(() => { + fakeModularPerformance = getFakeModularPerformance(); + performanceCompat = new PerformanceCompatImpl( + getFakeApp(), + fakeModularPerformance + ); + }); + + it('sets instrumnetation flag on the modular package', () => { + // Default value of the flag is true. + performanceCompat.instrumentationEnabled = false; + + expect(fakeModularPerformance.instrumentationEnabled).to.be.false; + }); + + it('sets data collection flag on the modular package', () => { + // Default value of the flag is true. + performanceCompat.dataCollectionEnabled = false; + + expect(fakeModularPerformance.dataCollectionEnabled).to.be.false; + }); + + it('calls modular trace api when trace is called on compat api', () => { + const modularTraceStub = stub(perfModularApi, 'trace').callsFake(() => + getFakeModularPerformanceTrace() + ); + performanceCompat.trace('test'); + + expect(modularTraceStub).to.have.been.calledWithExactly( + fakeModularPerformance, + 'test' + ); + }); +}); diff --git a/packages-exp/performance-compat/src/performance.ts b/packages-exp/performance-compat/src/performance.ts new file mode 100644 index 00000000000..5ad44efc6ba --- /dev/null +++ b/packages-exp/performance-compat/src/performance.ts @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FirebaseApp } from '@firebase/app-types'; +import { + trace, + FirebasePerformance, + // The PerformanceTrace type has not changed between modular and non-modular packages. + PerformanceTrace +} from '@firebase/performance-exp'; +import { FirebasePerformance as FirebasePerformanceCompat } from '@firebase/performance-types'; +import { FirebaseService } from '@firebase/app-types/private'; + +export class PerformanceCompatImpl + implements FirebasePerformanceCompat, FirebaseService { + constructor( + public app: FirebaseApp, + private _performance: FirebasePerformance + ) {} + + get instrumentationEnabled(): boolean { + return this._performance.instrumentationEnabled; + } + + set instrumentationEnabled(val: boolean) { + this._performance.instrumentationEnabled = val; + } + + get dataCollectionEnabled(): boolean { + return this._performance.dataCollectionEnabled; + } + + set dataCollectionEnabled(val: boolean) { + this._performance.dataCollectionEnabled = val; + } + + trace(traceName: string): PerformanceTrace { + return trace(this._performance, traceName); + } +} diff --git a/packages-exp/performance-compat/test/setup.ts b/packages-exp/performance-compat/test/setup.ts new file mode 100644 index 00000000000..b1e3136529f --- /dev/null +++ b/packages-exp/performance-compat/test/setup.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { use } from 'chai'; +import { restore } from 'sinon'; +import * as sinonChai from 'sinon-chai'; + +use(sinonChai); + +afterEach(async () => { + restore(); +}); diff --git a/packages-exp/performance-compat/test/util.ts b/packages-exp/performance-compat/test/util.ts new file mode 100644 index 00000000000..70b242bdc1b --- /dev/null +++ b/packages-exp/performance-compat/test/util.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FirebaseApp } from '@firebase/app-types'; +import { + FirebasePerformance, + PerformanceTrace +} from '@firebase/performance-exp'; + +export function getFakeApp(): FirebaseApp { + return { + name: 'appName', + options: { + apiKey: 'apiKey', + projectId: 'projectId', + authDomain: 'authDomain', + messagingSenderId: 'messagingSenderId', + databaseURL: 'databaseUrl', + storageBucket: 'storageBucket', + appId: '1:777777777777:web:d93b5ca1475efe57' + }, + automaticDataCollectionEnabled: true, + delete: async () => {} + }; +} + +export function getFakeModularPerformance(): FirebasePerformance { + return { + instrumentationEnabled: true, + dataCollectionEnabled: true + }; +} + +export function getFakeModularPerformanceTrace(): PerformanceTrace { + return {} as PerformanceTrace; +} diff --git a/packages-exp/performance-compat/tsconfig.json b/packages-exp/performance-compat/tsconfig.json new file mode 100644 index 00000000000..72e0736c2b7 --- /dev/null +++ b/packages-exp/performance-compat/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../config/tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "resolveJsonModule": true, + "downlevelIteration": true + }, + "exclude": ["dist/**/*"] +}