From af297a6b47f8ca2763d11f35bfea33c63d43b5ef Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 22 Sep 2025 14:28:14 -0400 Subject: [PATCH 01/12] WIP react support --- config/webpack.test.js | 2 +- packages/telemetry/index.node.ts | 1 + packages/telemetry/index.ts | 1 + packages/telemetry/karma.conf.js | 5 +- packages/telemetry/package.json | 11 ++- packages/telemetry/src/react.test.tsx | 57 ++++++++++++ packages/telemetry/src/react.tsx | 38 ++++++++ packages/telemetry/tsconfig.json | 3 +- yarn.lock | 120 ++++++++++++++++++++++++-- 9 files changed, 228 insertions(+), 10 deletions(-) create mode 100644 packages/telemetry/src/react.test.tsx create mode 100644 packages/telemetry/src/react.tsx diff --git a/config/webpack.test.js b/config/webpack.test.js index cc739313779..20a86740797 100644 --- a/config/webpack.test.js +++ b/config/webpack.test.js @@ -94,7 +94,7 @@ module.exports = { resolve: { modules: ['node_modules', path.resolve(__dirname, '../../node_modules')], mainFields: ['browser', 'module', 'main'], - extensions: ['.js', '.ts'], + extensions: ['.js', '.ts', '.tsx'], symlinks: true }, plugins: [ diff --git a/packages/telemetry/index.node.ts b/packages/telemetry/index.node.ts index d2fb87c965b..0cb8c3eef80 100644 --- a/packages/telemetry/index.node.ts +++ b/packages/telemetry/index.node.ts @@ -29,3 +29,4 @@ registerTelemetry(); export * from './src/api'; export * from './src/public-types'; export * from './src/next'; +export * from './src/react'; diff --git a/packages/telemetry/index.ts b/packages/telemetry/index.ts index 4eeaf214acf..f47b4394769 100644 --- a/packages/telemetry/index.ts +++ b/packages/telemetry/index.ts @@ -22,3 +22,4 @@ registerTelemetry(); export * from './src/api'; export * from './src/public-types'; export * from './src/next'; +export * from './src/react'; diff --git a/packages/telemetry/karma.conf.js b/packages/telemetry/karma.conf.js index 02647ba4c35..1c1419f9e32 100644 --- a/packages/telemetry/karma.conf.js +++ b/packages/telemetry/karma.conf.js @@ -17,12 +17,15 @@ const karmaBase = require('../../config/karma.base'); -const files = [`src/**/*.test.ts`]; +const files = [`src/**/*.test.ts*`]; module.exports = function (config) { const karmaConfig = { ...karmaBase, files, + preprocessors: { + 'src/**/*.test.ts*': ['webpack', 'sourcemap'] + }, frameworks: ['mocha'] }; diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 6cd9ee81f9f..6ae7c56057e 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -41,7 +41,9 @@ }, "peerDependencies": { "@firebase/app": "0.x", - "@firebase/app-types": "0.x" + "@firebase/app-types": "0.x", + "@types/react": "19.x", + "react": "19.x" }, "dependencies": { "@firebase/component": "0.7.0", @@ -52,7 +54,7 @@ "@opentelemetry/otlp-transformer": "0.205.0", "@opentelemetry/resources": "2.0.1", "@opentelemetry/sdk-logs": "0.203.0", - "@opentelemetry/semantic-conventions": "1.36.0", + "@opentelemetry/semantic-conventions": "1.36.0", "tslib": "^2.1.0" }, "license": "Apache-2.0", @@ -60,7 +62,12 @@ "@firebase/app": "0.14.2", "@opentelemetry/sdk-trace-web": "2.1.0", "@rollup/plugin-json": "6.1.0", + "@testing-library/dom": "10.4.1", + "@testing-library/react": "16.3.0", + "@types/react": "19.1.13", "next": "15.5.2", + "react": "19.1.1", + "react-dom": "19.1.1", "rollup": "2.79.2", "rollup-plugin-replace": "2.2.0", "rollup-plugin-typescript2": "0.36.0", diff --git a/packages/telemetry/src/react.test.tsx b/packages/telemetry/src/react.test.tsx new file mode 100644 index 00000000000..a6f85fa46bd --- /dev/null +++ b/packages/telemetry/src/react.test.tsx @@ -0,0 +1,57 @@ +/** + * @license + * Copyright 2025 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 { expect, use } from 'chai'; +import sinonChai from 'sinon-chai'; +import chaiAsPromised from 'chai-as-promised'; +import { restore, stub } from 'sinon'; +import * as app from '@firebase/app'; +import * as telemetry from './api'; +import { FirebaseApp } from '@firebase/app'; +import { Telemetry } from './public-types'; +import { FirebaseTelemetryBoundary } from './react'; +import React from 'react'; +import { render } from '@testing-library/react'; + +use(sinonChai); +use(chaiAsPromised); + +describe('firebaseTelemetryBoundary', () => { + let getTelemetryStub: sinon.SinonStub; + // let captureErrorStub: sinon.SinonStub; + let fakeApp: FirebaseApp; + let fakeTelemetry: Telemetry; + + beforeEach(() => { + fakeApp = {} as FirebaseApp; + fakeTelemetry = {} as Telemetry; + + stub(app, 'getApp').returns(fakeApp); + getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry); + // captureErrorStub = stub(telemetry, 'captureError'); + }); + + afterEach(() => { + restore(); + }); + + it('does something else', async () => { + render(here are my children); + + expect(1).to.equal(1); + }); +}); diff --git a/packages/telemetry/src/react.tsx b/packages/telemetry/src/react.tsx new file mode 100644 index 00000000000..65a5aa88476 --- /dev/null +++ b/packages/telemetry/src/react.tsx @@ -0,0 +1,38 @@ +/** + * @license + * Copyright 2025 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 React from 'react'; + +console.log(React); + + +export interface FirebaseTelemetryBoundaryProps { + children: React.ReactNode; +} + +export class FirebaseTelemetryBoundary extends React.Component { + constructor(public props: FirebaseTelemetryBoundaryProps) { + super(props); + + console.info('init firebase telemetry boundary'); + } + + render(): React.ReactNode { + console.info('abc'); + return this.props.children; + } +} \ No newline at end of file diff --git a/packages/telemetry/tsconfig.json b/packages/telemetry/tsconfig.json index 4e0ae05eebc..1840ca4857e 100644 --- a/packages/telemetry/tsconfig.json +++ b/packages/telemetry/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../config/tsconfig.base.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "jsx": "react" }, "exclude": ["dist/**/*"] } diff --git a/yarn.lock b/yarn.lock index 8452a622544..e6e4692d51e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,6 +29,15 @@ js-tokens "^4.0.0" picocolors "^1.0.0" +"@babel/code-frame@^7.10.4": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.26.5": version "7.26.5" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz#df93ac37f4417854130e21d72c66ff3d4b897fc7" @@ -228,6 +237,11 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + "@babel/helper-validator-option@^7.25.9": version "7.25.9" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" @@ -946,6 +960,11 @@ pirates "^4.0.6" source-map-support "^0.5.16" +"@babel/runtime@^7.12.5": + version "7.28.4" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" + integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== + "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4": version "7.26.7" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz#f4e7fe527cd710f8dc0618610b61b4b060c3c341" @@ -3187,6 +3206,27 @@ resolved "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz#86e04e677cd6c05fa230dd15ac223fa72d1d7090" integrity sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g== +"@testing-library/dom@10.4.1": + version "10.4.1" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz#d444f8a889e9a46e9a3b4f3b88e0fcb3efb6cf95" + integrity sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.3.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + picocolors "1.1.1" + pretty-format "^27.0.2" + +"@testing-library/react@16.3.0": + version "16.3.0" + resolved "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz#3a85bb9bdebf180cd76dba16454e242564d598a6" + integrity sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw== + dependencies: + "@babel/runtime" "^7.12.5" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -3227,6 +3267,11 @@ resolved "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + "@types/body-parser@*": version "1.19.5" resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" @@ -3549,6 +3594,13 @@ resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== +"@types/react@19.1.13": + version "19.1.13" + resolved "https://registry.npmjs.org/@types/react/-/react-19.1.13.tgz#fc650ffa680d739a25a530f5d7ebe00cdd771883" + integrity sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ== + dependencies: + csstype "^3.0.2" + "@types/request@2.48.12", "@types/request@^2.48.8": version "2.48.12" resolved "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz#0f590f615a10f87da18e9790ac94c29ec4c5ef30" @@ -4409,6 +4461,13 @@ argsarray@^0.0.1: resolved "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz#6e7207b4ecdb39b0af88303fa5ae22bda8df61cb" integrity sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg== +aria-query@5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -6317,6 +6376,11 @@ css@^3.0.0: source-map "^0.6.1" source-map-resolve "^0.6.0" +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + csv-parse@^5.0.4: version "5.6.0" resolved "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz#219beace2a3e9f28929999d2aa417d3fb3071c7f" @@ -6657,6 +6721,11 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + des.js@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" @@ -6768,6 +6837,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + dom-serialize@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" @@ -11335,6 +11409,11 @@ lunr@^2.3.8: resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + magic-string@^0.25.2, magic-string@^0.25.7: version "0.25.9" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" @@ -13349,16 +13428,16 @@ pgpass@1.x: dependencies: split2 "^4.1.0" +picocolors@1.1.1, picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picocolors@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== -picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -13540,6 +13619,15 @@ prettier@2.8.8, prettier@^2.7.1: resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -13919,11 +14007,28 @@ re2@^1.17.7: nan "^2.20.0" node-gyp "^10.2.0" +react-dom@19.1.1: + version "19.1.1" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz#2daa9ff7f3ae384aeb30e76d5ee38c046dc89893" + integrity sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw== + dependencies: + scheduler "^0.26.0" + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^18.0.0: version "18.3.1" resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== +react@19.1.1: + version "19.1.1" + resolved "https://registry.npmjs.org/react/-/react-19.1.1.tgz#06d9149ec5e083a67f9a1e39ce97b06a03b644af" + integrity sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ== + read-cmd-shim@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz#4a50a71d6f0965364938e9038476f7eede3928d9" @@ -14687,6 +14792,11 @@ sax@>=0.6.0: resolved "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== +scheduler@^0.26.0: + version "0.26.0" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz#4ce8a8c2a2095f13ea11bf9a445be50c555d6337" + integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== + schema-utils@^2.6.5: version "2.7.1" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" From 894e9703af876def0bf7d7abacf24902bed44712 Mon Sep 17 00:00:00 2001 From: abrook Date: Tue, 23 Sep 2025 11:48:34 -0400 Subject: [PATCH 02/12] WIP react support with sub-package --- packages/telemetry/api-extractor.react.json | 17 ++++ packages/telemetry/index.node.ts | 1 - packages/telemetry/index.ts | 1 - packages/telemetry/package.json | 30 +++++- packages/telemetry/rollup.config.js | 100 +++++++++++++++++++- packages/telemetry/src/react.test.tsx | 57 ----------- packages/telemetry/src/react.tsx | 38 -------- packages/telemetry/src/react/index.ts | 18 ++++ packages/telemetry/tsconfig.json | 3 +- packages/telemetry/tsconfig.react.json | 8 ++ 10 files changed, 168 insertions(+), 105 deletions(-) create mode 100644 packages/telemetry/api-extractor.react.json delete mode 100644 packages/telemetry/src/react.test.tsx delete mode 100644 packages/telemetry/src/react.tsx create mode 100644 packages/telemetry/src/react/index.ts create mode 100644 packages/telemetry/tsconfig.react.json diff --git a/packages/telemetry/api-extractor.react.json b/packages/telemetry/api-extractor.react.json new file mode 100644 index 00000000000..20309f44fb5 --- /dev/null +++ b/packages/telemetry/api-extractor.react.json @@ -0,0 +1,17 @@ +{ + "extends": "../../config/api-extractor.json", + "mainEntryPointFilePath": "/dist/react/index.d.ts", + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "/dist/react/index.d.ts" + }, + "apiReport": { + "enabled": false + }, + "docModel": { + "enabled": false + }, + "tsdocMetadata": { + "enabled": false + } +} diff --git a/packages/telemetry/index.node.ts b/packages/telemetry/index.node.ts index 0cb8c3eef80..d2fb87c965b 100644 --- a/packages/telemetry/index.node.ts +++ b/packages/telemetry/index.node.ts @@ -29,4 +29,3 @@ registerTelemetry(); export * from './src/api'; export * from './src/public-types'; export * from './src/next'; -export * from './src/react'; diff --git a/packages/telemetry/index.ts b/packages/telemetry/index.ts index f47b4394769..4eeaf214acf 100644 --- a/packages/telemetry/index.ts +++ b/packages/telemetry/index.ts @@ -22,4 +22,3 @@ registerTelemetry(); export * from './src/api'; export * from './src/public-types'; export * from './src/next'; -export * from './src/react'; diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 6ae7c56057e..824ad23939b 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -19,6 +19,18 @@ }, "default": "./dist/index.esm.js" }, + "./react": { + "types": "./dist/react/index.d.ts", + "node": { + "import": "./dist/react-node-esm/index.node.esm.js", + "default": "./dist/react.node.cjs.js" + }, + "browser": { + "require": "./dist/react.cjs.js", + "import": "./dist/react.esm.js" + }, + "default": "./dist/react.esm.js" + }, "./package.json": "./package.json" }, "files": [ @@ -36,14 +48,24 @@ "test:browser": "karma start", "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha src/**/*.test.* --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", - "api-report": "api-extractor run --local --verbose", + "api-report": "yarn api-report:main && yarn api-report:react", + "api-report:main": "api-extractor run --local --verbose", + "api-report:react": "api-extractor run --config api-extractor.react.json --local --verbose", "typings:public": "node ../../scripts/build/use_typings.js ./dist/telemetry-public.d.ts" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-types": "0.x", - "@types/react": "19.x", - "react": "19.x" + "@types/react": "17.x || 18.x || 19.x", + "react": "17.x || 18.x || 19.x" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "@types/react": { + "optional": true + } }, "dependencies": { "@firebase/component": "0.7.0", @@ -54,7 +76,7 @@ "@opentelemetry/otlp-transformer": "0.205.0", "@opentelemetry/resources": "2.0.1", "@opentelemetry/sdk-logs": "0.203.0", - "@opentelemetry/semantic-conventions": "1.36.0", + "@opentelemetry/semantic-conventions": "1.36.0", "tslib": "^2.1.0" }, "license": "Apache-2.0", diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js index 6ce188cb72d..ac6a48f4835 100644 --- a/packages/telemetry/rollup.config.js +++ b/packages/telemetry/rollup.config.js @@ -41,7 +41,7 @@ const browserBuilds = [ { input: 'index.ts', output: { - file: './dist/index.cjs.js', + file: pkg.exports['.'].browser.require, format: 'cjs', sourcemap: true }, @@ -73,4 +73,100 @@ const nodeBuilds = [ } ]; -export default [...browserBuilds, ...nodeBuilds]; +const reactBuilds = [ + { + input: 'src/react/index.ts', + output: { + file: pkg.exports['./react'].browser.import, + format: 'es', + sourcemap: true, + banner: `'use client';` + }, + plugins: [ + typescriptPlugin({ + typescript, + tsconfigOverride: { + compilerOptions: { + declarationDir: 'dist/react' + } + } + }), + json() + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + }, + { + input: 'src/react/index.ts', + output: { + file: pkg.exports['./react'].browser.require, + format: 'cjs', + sourcemap: true, + banner: `'use client';` + }, + plugins: [ + typescriptPlugin({ + typescript, + tsconfigOverride: { + compilerOptions: { + declarationDir: 'dist/react' + } + } + }), + json() + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + } +]; + +const reactNodeBuilds = [ + { + input: 'src/react/index.ts', + output: { + file: pkg.exports['./react'].node.default, + format: 'cjs', + sourcemap: true, + banner: `'use client';` + }, + plugins: [ + typescriptPlugin({ + typescript, + tsconfigOverride: { + compilerOptions: { + declarationDir: 'dist/react' + } + } + }), + json() + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + }, + { + input: 'src/react/index.ts', + output: { + file: pkg.exports['./react'].node.import, + format: 'es', + sourcemap: true, + banner: `'use client';` + }, + plugins: [ + typescriptPlugin({ + typescript, + tsconfigOverride: { + compilerOptions: { + declarationDir: 'dist/react' + } + } + }), + json(), + emitModulePackageFile() + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + } +]; + +export default [ + ...browserBuilds, + ...nodeBuilds, + ...reactBuilds, + ...reactNodeBuilds +]; diff --git a/packages/telemetry/src/react.test.tsx b/packages/telemetry/src/react.test.tsx deleted file mode 100644 index a6f85fa46bd..00000000000 --- a/packages/telemetry/src/react.test.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @license - * Copyright 2025 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 { expect, use } from 'chai'; -import sinonChai from 'sinon-chai'; -import chaiAsPromised from 'chai-as-promised'; -import { restore, stub } from 'sinon'; -import * as app from '@firebase/app'; -import * as telemetry from './api'; -import { FirebaseApp } from '@firebase/app'; -import { Telemetry } from './public-types'; -import { FirebaseTelemetryBoundary } from './react'; -import React from 'react'; -import { render } from '@testing-library/react'; - -use(sinonChai); -use(chaiAsPromised); - -describe('firebaseTelemetryBoundary', () => { - let getTelemetryStub: sinon.SinonStub; - // let captureErrorStub: sinon.SinonStub; - let fakeApp: FirebaseApp; - let fakeTelemetry: Telemetry; - - beforeEach(() => { - fakeApp = {} as FirebaseApp; - fakeTelemetry = {} as Telemetry; - - stub(app, 'getApp').returns(fakeApp); - getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry); - // captureErrorStub = stub(telemetry, 'captureError'); - }); - - afterEach(() => { - restore(); - }); - - it('does something else', async () => { - render(here are my children); - - expect(1).to.equal(1); - }); -}); diff --git a/packages/telemetry/src/react.tsx b/packages/telemetry/src/react.tsx deleted file mode 100644 index 65a5aa88476..00000000000 --- a/packages/telemetry/src/react.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @license - * Copyright 2025 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 React from 'react'; - -console.log(React); - - -export interface FirebaseTelemetryBoundaryProps { - children: React.ReactNode; -} - -export class FirebaseTelemetryBoundary extends React.Component { - constructor(public props: FirebaseTelemetryBoundaryProps) { - super(props); - - console.info('init firebase telemetry boundary'); - } - - render(): React.ReactNode { - console.info('abc'); - return this.props.children; - } -} \ No newline at end of file diff --git a/packages/telemetry/src/react/index.ts b/packages/telemetry/src/react/index.ts new file mode 100644 index 00000000000..4f14fcf7ef3 --- /dev/null +++ b/packages/telemetry/src/react/index.ts @@ -0,0 +1,18 @@ +import React from 'react'; + +export interface FirebaseTelemetryBoundaryProps { + children: React.ReactNode; +} + +export class FirebaseTelemetryBoundary extends React.Component { + constructor(public props: FirebaseTelemetryBoundaryProps) { + super(props); + + console.info('init firebase telemetry boundary'); + } + + render(): React.ReactNode { + console.info('abc'); + return this.props.children; + } +} \ No newline at end of file diff --git a/packages/telemetry/tsconfig.json b/packages/telemetry/tsconfig.json index 1840ca4857e..4e0ae05eebc 100644 --- a/packages/telemetry/tsconfig.json +++ b/packages/telemetry/tsconfig.json @@ -1,8 +1,7 @@ { "extends": "../../config/tsconfig.base.json", "compilerOptions": { - "outDir": "dist", - "jsx": "react" + "outDir": "dist" }, "exclude": ["dist/**/*"] } diff --git a/packages/telemetry/tsconfig.react.json b/packages/telemetry/tsconfig.react.json new file mode 100644 index 00000000000..1bc891ef501 --- /dev/null +++ b/packages/telemetry/tsconfig.react.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist/react", + "declarationDir": "dist/react" + }, + "include": ["src/react/index.ts"] +} \ No newline at end of file From fcad227be546c3dc338bd5d62943b311aa66f2da Mon Sep 17 00:00:00 2001 From: abrook Date: Tue, 23 Sep 2025 13:22:58 -0400 Subject: [PATCH 03/12] Fix package structure; capture client errors --- common/api-review/telemetry.api.md | 9 ++---- packages/telemetry/api-extractor.json | 2 +- packages/telemetry/api-extractor.react.json | 2 +- packages/telemetry/package.json | 10 +++---- packages/telemetry/rollup.config.js | 24 +++------------- packages/telemetry/src/react/index.ts | 31 +++++++++++++++++---- 6 files changed, 38 insertions(+), 40 deletions(-) diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 066c7c9e4e2..623299b1ee8 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,6 +6,7 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; +import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -17,13 +18,7 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -// @public (undocumented) -export namespace Instrumentation { - // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts - // - // (undocumented) - export type onRequestError = InstrumentationOnRequestError; -} +export { Instrumentation } // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json index 12e2ecdc56b..c7ec595b57c 100644 --- a/packages/telemetry/api-extractor.json +++ b/packages/telemetry/api-extractor.json @@ -7,5 +7,5 @@ "untrimmedFilePath": "/dist/.d.ts", "betaTrimmedFilePath": "/dist/-public.d.ts" }, - "bundledPackages": ["next"] + "bundledPackages": ["react"] } diff --git a/packages/telemetry/api-extractor.react.json b/packages/telemetry/api-extractor.react.json index 20309f44fb5..1623cf8c6d5 100644 --- a/packages/telemetry/api-extractor.react.json +++ b/packages/telemetry/api-extractor.react.json @@ -1,6 +1,6 @@ { "extends": "../../config/api-extractor.json", - "mainEntryPointFilePath": "/dist/react/index.d.ts", + "mainEntryPointFilePath": "/dist/react/react/index.d.ts", "dtsRollup": { "enabled": true, "untrimmedFilePath": "/dist/react/index.d.ts" diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 824ad23939b..9e4e871353d 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -22,14 +22,14 @@ "./react": { "types": "./dist/react/index.d.ts", "node": { - "import": "./dist/react-node-esm/index.node.esm.js", - "default": "./dist/react.node.cjs.js" + "import": "./dist/react/index.node.esm.js", + "default": "./dist/react/index.node.cjs.js" }, "browser": { - "require": "./dist/react.cjs.js", - "import": "./dist/react.esm.js" + "require": "./dist/react/index.cjs.js", + "import": "./dist/react/index.esm.js" }, - "default": "./dist/react.esm.js" + "default": "./dist/react/index.esm.js" }, "./package.json": "./package.json" }, diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js index ac6a48f4835..0453c0160a5 100644 --- a/packages/telemetry/rollup.config.js +++ b/packages/telemetry/rollup.config.js @@ -85,11 +85,7 @@ const reactBuilds = [ plugins: [ typescriptPlugin({ typescript, - tsconfigOverride: { - compilerOptions: { - declarationDir: 'dist/react' - } - } + tsconfig: 'tsconfig.react.json' }), json() ], @@ -106,11 +102,7 @@ const reactBuilds = [ plugins: [ typescriptPlugin({ typescript, - tsconfigOverride: { - compilerOptions: { - declarationDir: 'dist/react' - } - } + tsconfig: 'tsconfig.react.json' }), json() ], @@ -130,11 +122,7 @@ const reactNodeBuilds = [ plugins: [ typescriptPlugin({ typescript, - tsconfigOverride: { - compilerOptions: { - declarationDir: 'dist/react' - } - } + tsconfig: 'tsconfig.react.json' }), json() ], @@ -151,11 +139,7 @@ const reactNodeBuilds = [ plugins: [ typescriptPlugin({ typescript, - tsconfigOverride: { - compilerOptions: { - declarationDir: 'dist/react' - } - } + tsconfig: 'tsconfig.react.json' }), json(), emitModulePackageFile() diff --git a/packages/telemetry/src/react/index.ts b/packages/telemetry/src/react/index.ts index 4f14fcf7ef3..78b191e57ae 100644 --- a/packages/telemetry/src/react/index.ts +++ b/packages/telemetry/src/react/index.ts @@ -1,18 +1,37 @@ -import React from 'react'; +import { getApp } from '@firebase/app'; +import { captureError, getTelemetry } from '../api'; +import { Component, ReactNode } from 'react'; export interface FirebaseTelemetryBoundaryProps { - children: React.ReactNode; + children: ReactNode; } -export class FirebaseTelemetryBoundary extends React.Component { +export class FirebaseTelemetryBoundary extends Component { constructor(public props: FirebaseTelemetryBoundaryProps) { super(props); + } + + componentDidMount(): void { + if (typeof window === 'undefined') { + return; + } + + // TODO: This will be obsolete once the SDK has a default endpoint + process.env.OTEL_ENDPOINT = window.location.origin; + + const telemetry = getTelemetry(getApp()); + + console.info(telemetry); + + window.addEventListener('error', (event: ErrorEvent) => { + captureError(telemetry, event.error, {'example_attribute': 'hello'}); + }); + + // TODO: add listener for unhandledrejection - console.info('init firebase telemetry boundary'); } - render(): React.ReactNode { - console.info('abc'); + render(): ReactNode { return this.props.children; } } \ No newline at end of file From 391c2e818e27a344a682c3f4012b9e3a47a59cc2 Mon Sep 17 00:00:00 2001 From: abrook Date: Wed, 24 Sep 2025 14:39:28 -0400 Subject: [PATCH 04/12] Implement and test FirebaseTelemetry component --- packages/telemetry/api-extractor.react.json | 2 +- packages/telemetry/package.json | 2 +- packages/telemetry/src/react/index.test.tsx | 111 ++++++++++++++++++++ packages/telemetry/src/react/index.ts | 60 ++++++++--- packages/telemetry/tsconfig.json | 3 +- packages/telemetry/tsconfig.react.json | 3 +- 6 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 packages/telemetry/src/react/index.test.tsx diff --git a/packages/telemetry/api-extractor.react.json b/packages/telemetry/api-extractor.react.json index 1623cf8c6d5..d3cb5d97e93 100644 --- a/packages/telemetry/api-extractor.react.json +++ b/packages/telemetry/api-extractor.react.json @@ -1,6 +1,6 @@ { "extends": "../../config/api-extractor.json", - "mainEntryPointFilePath": "/dist/react/react/index.d.ts", + "mainEntryPointFilePath": "/dist/react/src/react/index.d.ts", "dtsRollup": { "enabled": true, "untrimmedFilePath": "/dist/react/index.d.ts" diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 9e4e871353d..524f1e9a454 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -46,7 +46,7 @@ "test:ci": "node ../../scripts/run_tests_in_ci.js -s test:all", "test:all": "run-p --npm-path npm test:browser test:node", "test:browser": "karma start", - "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha src/**/*.test.* --config ../../config/mocharc.node.js", + "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", "api-report": "yarn api-report:main && yarn api-report:react", "api-report:main": "api-extractor run --local --verbose", diff --git a/packages/telemetry/src/react/index.test.tsx b/packages/telemetry/src/react/index.test.tsx new file mode 100644 index 00000000000..4f5d4325150 --- /dev/null +++ b/packages/telemetry/src/react/index.test.tsx @@ -0,0 +1,111 @@ +/** + * @license + * Copyright 2025 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 { expect, use } from 'chai'; +import sinonChai from 'sinon-chai'; +import chaiAsPromised from 'chai-as-promised'; +import { restore, stub } from 'sinon'; +import * as app from '@firebase/app'; +import * as telemetry from '../api'; +import { FirebaseApp } from '@firebase/app'; +import { Telemetry } from '../public-types'; +import { FirebaseTelemetry } from '.'; +import React from 'react'; +import { render } from '@testing-library/react'; + +use(sinonChai); +use(chaiAsPromised); + +describe('FirebaseTelemetry', () => { + let getTelemetryStub: sinon.SinonStub; + let captureErrorStub: sinon.SinonStub; + let initializeAppStub: sinon.SinonStub; + let fakeApp: FirebaseApp; + let fakeTelemetry: Telemetry; + + beforeEach(() => { + fakeApp = { name: 'fakeApp' } as FirebaseApp; + fakeTelemetry = {} as Telemetry; + + initializeAppStub = stub(app, 'initializeApp').returns(fakeApp); + getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry); + captureErrorStub = stub(telemetry, 'captureError'); + }); + + afterEach(() => { + restore(); + }); + + it('gets telemetry with the default app if no firebaseOptions are provided', () => { + render(); + expect(getTelemetryStub).to.have.been.called; + expect(initializeAppStub).not.to.have.been.called; + }); + + it('initializes a new app and gets telemetry if firebaseOptions are provided', () => { + const firebaseOptions = { apiKey: 'test' }; + render(); + expect(initializeAppStub).to.have.been.calledWith(firebaseOptions); + expect(getTelemetryStub).to.have.been.calledWith(fakeApp); + }); + + it('captures window errors', done => { + render(); + const error = new Error('test error'); + window.onerror = () => { + // Prevent error from bubbling up to test suite + }; + window.addEventListener('error', (event: ErrorEvent) => { + // Registers another listener (sequential) to confirm behaviour. + expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, error); + done(); + }); + window.dispatchEvent(new ErrorEvent('error', { error })); + }); + + it('captures unhandled promise rejections', () => { + render(); + const reason = new Error('test rejection'); + const promise = Promise.reject(reason); + promise.catch(() => {}); + window.dispatchEvent( + new PromiseRejectionEvent('unhandledrejection', { reason, promise }) + ); + expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, reason); + }); + + it('renders children', () => { + const { getByText } = render( + + here are my children + + ); + expect(getByText('here are my children')).to.exist; + }); + + it('fails silently when getTelemetry fails', () => { + const error = new Error('getTelemetry failed'); + getTelemetryStub.throws(error); + const consoleWarnStub = stub(console, 'warn'); + + expect(() => render()).not.to.throw(); + expect(consoleWarnStub).to.have.been.calledWith( + 'Firebase Telemetry was not initialized:\n', + error + ); + }); +}); diff --git a/packages/telemetry/src/react/index.ts b/packages/telemetry/src/react/index.ts index 78b191e57ae..cae643fb655 100644 --- a/packages/telemetry/src/react/index.ts +++ b/packages/telemetry/src/react/index.ts @@ -1,13 +1,34 @@ -import { getApp } from '@firebase/app'; +/** + * @license + * Copyright 2025 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 { FirebaseOptions, initializeApp } from '@firebase/app'; +import { registerTelemetry } from '../register'; import { captureError, getTelemetry } from '../api'; import { Component, ReactNode } from 'react'; -export interface FirebaseTelemetryBoundaryProps { - children: ReactNode; +registerTelemetry(); + +export interface FirebaseTelemetryProps { + firebaseOptions?: FirebaseOptions; + children?: ReactNode; } -export class FirebaseTelemetryBoundary extends Component { - constructor(public props: FirebaseTelemetryBoundaryProps) { +export class FirebaseTelemetry extends Component { + constructor(public props: FirebaseTelemetryProps) { super(props); } @@ -16,22 +37,31 @@ export class FirebaseTelemetryBoundary extends Component { - captureError(telemetry, event.error, {'example_attribute': 'hello'}); - }); - - // TODO: add listener for unhandledrejection + window.addEventListener('error', (event: ErrorEvent) => { + captureError(telemetry, event.error, {}); + }); + window.addEventListener( + 'unhandledrejection', + (event: PromiseRejectionEvent) => { + captureError(telemetry, event.reason, {}); + } + ); + } catch (error) { + // Log the error here, but don't die. + console.warn(`Firebase Telemetry was not initialized:\n`, error); + } } render(): ReactNode { return this.props.children; } -} \ No newline at end of file +} diff --git a/packages/telemetry/tsconfig.json b/packages/telemetry/tsconfig.json index 4e0ae05eebc..1840ca4857e 100644 --- a/packages/telemetry/tsconfig.json +++ b/packages/telemetry/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../config/tsconfig.base.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "jsx": "react" }, "exclude": ["dist/**/*"] } diff --git a/packages/telemetry/tsconfig.react.json b/packages/telemetry/tsconfig.react.json index 1bc891ef501..de2b1885562 100644 --- a/packages/telemetry/tsconfig.react.json +++ b/packages/telemetry/tsconfig.react.json @@ -2,7 +2,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "dist/react", - "declarationDir": "dist/react" + "declarationDir": "dist/react", + "jsx": "react" }, "include": ["src/react/index.ts"] } \ No newline at end of file From 6dace8a59dba4eb00a96724f3e1d525ee25d5cde Mon Sep 17 00:00:00 2001 From: abrook Date: Wed, 24 Sep 2025 14:58:34 -0400 Subject: [PATCH 05/12] docgen --- common/api-review/telemetry.api.md | 9 +++++-- docs-devsite/telemetry.instrumentation.md | 31 ----------------------- docs-devsite/telemetry.md | 6 ----- packages/telemetry/api-extractor.json | 2 +- 4 files changed, 8 insertions(+), 40 deletions(-) delete mode 100644 docs-devsite/telemetry.instrumentation.md diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 623299b1ee8..066c7c9e4e2 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,7 +6,6 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; -import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -18,7 +17,13 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -export { Instrumentation } +// @public (undocumented) +export namespace Instrumentation { + // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts + // + // (undocumented) + export type onRequestError = InstrumentationOnRequestError; +} // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/docs-devsite/telemetry.instrumentation.md b/docs-devsite/telemetry.instrumentation.md deleted file mode 100644 index 2e2be64711e..00000000000 --- a/docs-devsite/telemetry.instrumentation.md +++ /dev/null @@ -1,31 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# Instrumentation namespace -Signature: - -```typescript -export declare namespace Instrumentation -``` - -## Type Aliases - -| Type Alias | Description | -| --- | --- | -| [onRequestError](./telemetry.instrumentation.md#instrumentationonrequesterror) | | - -## Instrumentation.onRequestError - -Signature: - -```typescript -type onRequestError = InstrumentationOnRequestError; -``` diff --git a/docs-devsite/telemetry.md b/docs-devsite/telemetry.md index fa62b62e7b8..c06f7365457 100644 --- a/docs-devsite/telemetry.md +++ b/docs-devsite/telemetry.md @@ -27,12 +27,6 @@ https://github.com/firebase/firebase-js-sdk | --- | --- | | [Telemetry](./telemetry.telemetry.md#telemetry_interface) | An instance of the Firebase Telemetry SDK.Do not create this instance directly. Instead, use [getTelemetry()](./telemetry.md#gettelemetry_cf608e1). | -## Namespaces - -| Namespace | Description | -| --- | --- | -| [Instrumentation](./telemetry.instrumentation.md#instrumentation_namespace) | | - ## Variables | Variable | Description | diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json index c7ec595b57c..12e2ecdc56b 100644 --- a/packages/telemetry/api-extractor.json +++ b/packages/telemetry/api-extractor.json @@ -7,5 +7,5 @@ "untrimmedFilePath": "/dist/.d.ts", "betaTrimmedFilePath": "/dist/-public.d.ts" }, - "bundledPackages": ["react"] + "bundledPackages": ["next"] } From f834a96d26b88c187cbb5417f3fdf66b9b64f611 Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 09:18:29 -0400 Subject: [PATCH 06/12] Refactor to use React component function --- common/api-review/telemetry-react.api.md | 17 +++++ common/api-review/telemetry.api.md | 9 +-- docs-devsite/telemetry.instrumentation.md | 31 +++++++++ docs-devsite/telemetry.md | 6 ++ packages/telemetry/api-extractor.json | 6 ++ packages/telemetry/api-extractor.react.json | 20 +++--- packages/telemetry/package.json | 12 ++-- packages/telemetry/rollup.config.js | 41 +----------- packages/telemetry/src/react/index.test.tsx | 21 ++---- packages/telemetry/src/react/index.ts | 72 +++++++++++++-------- 10 files changed, 132 insertions(+), 103 deletions(-) create mode 100644 common/api-review/telemetry-react.api.md create mode 100644 docs-devsite/telemetry.instrumentation.md diff --git a/common/api-review/telemetry-react.api.md b/common/api-review/telemetry-react.api.md new file mode 100644 index 00000000000..d7eeb9b53ea --- /dev/null +++ b/common/api-review/telemetry-react.api.md @@ -0,0 +1,17 @@ +## API Report File for "@firebase/telemetry-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { FirebaseOptions } from '@firebase/app'; + +// @public +export function FirebaseTelemetry({ firebaseOptions }: { + firebaseOptions?: FirebaseOptions; +}): null; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 066c7c9e4e2..623299b1ee8 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,6 +6,7 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; +import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -17,13 +18,7 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -// @public (undocumented) -export namespace Instrumentation { - // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts - // - // (undocumented) - export type onRequestError = InstrumentationOnRequestError; -} +export { Instrumentation } // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/docs-devsite/telemetry.instrumentation.md b/docs-devsite/telemetry.instrumentation.md new file mode 100644 index 00000000000..2e2be64711e --- /dev/null +++ b/docs-devsite/telemetry.instrumentation.md @@ -0,0 +1,31 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# Instrumentation namespace +Signature: + +```typescript +export declare namespace Instrumentation +``` + +## Type Aliases + +| Type Alias | Description | +| --- | --- | +| [onRequestError](./telemetry.instrumentation.md#instrumentationonrequesterror) | | + +## Instrumentation.onRequestError + +Signature: + +```typescript +type onRequestError = InstrumentationOnRequestError; +``` diff --git a/docs-devsite/telemetry.md b/docs-devsite/telemetry.md index c06f7365457..fa62b62e7b8 100644 --- a/docs-devsite/telemetry.md +++ b/docs-devsite/telemetry.md @@ -27,6 +27,12 @@ https://github.com/firebase/firebase-js-sdk | --- | --- | | [Telemetry](./telemetry.telemetry.md#telemetry_interface) | An instance of the Firebase Telemetry SDK.Do not create this instance directly. Instead, use [getTelemetry()](./telemetry.md#gettelemetry_cf608e1). | +## Namespaces + +| Namespace | Description | +| --- | --- | +| [Instrumentation](./telemetry.instrumentation.md#instrumentation_namespace) | | + ## Variables | Variable | Description | diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json index 12e2ecdc56b..3f246a76f68 100644 --- a/packages/telemetry/api-extractor.json +++ b/packages/telemetry/api-extractor.json @@ -7,5 +7,11 @@ "untrimmedFilePath": "/dist/.d.ts", "betaTrimmedFilePath": "/dist/-public.d.ts" }, + // "additionalEntryPoints": [ + // { + // "modulePath": "react", + // "filePath": "/dist/react/index.d.ts" + // } + // ], "bundledPackages": ["next"] } diff --git a/packages/telemetry/api-extractor.react.json b/packages/telemetry/api-extractor.react.json index d3cb5d97e93..6f8ef25c891 100644 --- a/packages/telemetry/api-extractor.react.json +++ b/packages/telemetry/api-extractor.react.json @@ -4,14 +4,14 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "/dist/react/index.d.ts" - }, - "apiReport": { - "enabled": false - }, - "docModel": { - "enabled": false - }, - "tsdocMetadata": { - "enabled": false - } + }//, + // "apiReport": { + // "enabled": false + // }, + // "docModel": { + // "enabled": false + // }, + // "tsdocMetadata": { + // "enabled": false + // } } diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 524f1e9a454..47e9fdf16a0 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -22,8 +22,8 @@ "./react": { "types": "./dist/react/index.d.ts", "node": { - "import": "./dist/react/index.node.esm.js", - "default": "./dist/react/index.node.cjs.js" + "import": "./dist/react/index.esm.js", + "default": "./dist/react/index.cjs.js" }, "browser": { "require": "./dist/react/index.cjs.js", @@ -48,9 +48,11 @@ "test:browser": "karma start", "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", - "api-report": "yarn api-report:main && yarn api-report:react", - "api-report:main": "api-extractor run --local --verbose", - "api-report:react": "api-extractor run --config api-extractor.react.json --local --verbose", + "api-report": "yarn api-report:react && yarn api-report:main", + "api-report:main": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' ts-node ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry --packageRoot . --typescriptDts ./dist/index.d.ts --rollupDts ./dist/index.d.ts --untrimmedRollupDts ./dist/index.d.ts --publicDts ./dist/index.d.ts", + "api-report:main1": "api-extractor run --local --verbose", + "api-report:react": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' ts-node ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry-react --packageRoot . --typescriptDts ./dist/src/react/index.d.ts --rollupDts ./dist/src/react/index.d.ts --untrimmedRollupDts ./dist/src/react/index.d.ts --publicDts ./dist/src/react/index.d.ts", + "api-report:react1": "api-extractor run --config api-extractor.react.json --local --verbose", "typings:public": "node ../../scripts/build/use_typings.js ./dist/telemetry-public.d.ts" }, "peerDependencies": { diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js index 0453c0160a5..c40b4800cf9 100644 --- a/packages/telemetry/rollup.config.js +++ b/packages/telemetry/rollup.config.js @@ -110,47 +110,8 @@ const reactBuilds = [ } ]; -const reactNodeBuilds = [ - { - input: 'src/react/index.ts', - output: { - file: pkg.exports['./react'].node.default, - format: 'cjs', - sourcemap: true, - banner: `'use client';` - }, - plugins: [ - typescriptPlugin({ - typescript, - tsconfig: 'tsconfig.react.json' - }), - json() - ], - external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) - }, - { - input: 'src/react/index.ts', - output: { - file: pkg.exports['./react'].node.import, - format: 'es', - sourcemap: true, - banner: `'use client';` - }, - plugins: [ - typescriptPlugin({ - typescript, - tsconfig: 'tsconfig.react.json' - }), - json(), - emitModulePackageFile() - ], - external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) - } -]; - export default [ ...browserBuilds, ...nodeBuilds, - ...reactBuilds, - ...reactNodeBuilds + ...reactBuilds ]; diff --git a/packages/telemetry/src/react/index.test.tsx b/packages/telemetry/src/react/index.test.tsx index 4f5d4325150..29643393133 100644 --- a/packages/telemetry/src/react/index.test.tsx +++ b/packages/telemetry/src/react/index.test.tsx @@ -30,10 +30,11 @@ import { render } from '@testing-library/react'; use(sinonChai); use(chaiAsPromised); -describe('FirebaseTelemetry', () => { +describe.only('FirebaseTelemetry', () => { let getTelemetryStub: sinon.SinonStub; let captureErrorStub: sinon.SinonStub; let initializeAppStub: sinon.SinonStub; + let getAppStub: sinon.SinonStub; let fakeApp: FirebaseApp; let fakeTelemetry: Telemetry; @@ -44,6 +45,7 @@ describe('FirebaseTelemetry', () => { initializeAppStub = stub(app, 'initializeApp').returns(fakeApp); getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry); captureErrorStub = stub(telemetry, 'captureError'); + getAppStub = stub(app, 'getApp').returns(fakeApp); }); afterEach(() => { @@ -52,7 +54,6 @@ describe('FirebaseTelemetry', () => { it('gets telemetry with the default app if no firebaseOptions are provided', () => { render(); - expect(getTelemetryStub).to.have.been.called; expect(initializeAppStub).not.to.have.been.called; }); @@ -60,7 +61,6 @@ describe('FirebaseTelemetry', () => { const firebaseOptions = { apiKey: 'test' }; render(); expect(initializeAppStub).to.have.been.calledWith(firebaseOptions); - expect(getTelemetryStub).to.have.been.calledWith(fakeApp); }); it('captures window errors', done => { @@ -71,6 +71,7 @@ describe('FirebaseTelemetry', () => { }; window.addEventListener('error', (event: ErrorEvent) => { // Registers another listener (sequential) to confirm behaviour. + expect(getTelemetryStub).to.have.been.called; expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, error); done(); }); @@ -85,24 +86,16 @@ describe('FirebaseTelemetry', () => { window.dispatchEvent( new PromiseRejectionEvent('unhandledrejection', { reason, promise }) ); + expect(getTelemetryStub).to.have.been.called; expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, reason); }); - it('renders children', () => { - const { getByText } = render( - - here are my children - - ); - expect(getByText('here are my children')).to.exist; - }); - it('fails silently when getTelemetry fails', () => { const error = new Error('getTelemetry failed'); - getTelemetryStub.throws(error); + initializeAppStub.throws(error); const consoleWarnStub = stub(console, 'warn'); - expect(() => render()).not.to.throw(); + expect(() => render()).not.to.throw(); expect(consoleWarnStub).to.have.been.calledWith( 'Firebase Telemetry was not initialized:\n', error diff --git a/packages/telemetry/src/react/index.ts b/packages/telemetry/src/react/index.ts index cae643fb655..f1fde0d7525 100644 --- a/packages/telemetry/src/react/index.ts +++ b/packages/telemetry/src/react/index.ts @@ -18,21 +18,43 @@ import { FirebaseOptions, initializeApp } from '@firebase/app'; import { registerTelemetry } from '../register'; import { captureError, getTelemetry } from '../api'; -import { Component, ReactNode } from 'react'; +import { useEffect } from 'react'; registerTelemetry(); -export interface FirebaseTelemetryProps { - firebaseOptions?: FirebaseOptions; - children?: ReactNode; +function errorListener(event: ErrorEvent): void { + captureError(getTelemetry(), event.error, {}); } -export class FirebaseTelemetry extends Component { - constructor(public props: FirebaseTelemetryProps) { - super(props); - } +function unhandledRejectionListener(event: PromiseRejectionEvent): void { + captureError(getTelemetry(), event.reason, {}); +} - componentDidMount(): void { +/** + * Registers event listeners for uncaught errors. + * + * This should be installed near the root of your application. Caught errors, including those + * implicitly caught by Error Boundaries, will not be captured by this component. + * + * @example + * ```html + * + * + * ... my app ... + * + * ``` + * + * @param firebaseOptions - Options to run {@link @firebase/app#initializeApp}. If this is not provided, initializeApp needs to be called explicitly elsewhere in your application. + * @returns The default {@link Telemetry} instance for the given {@link @firebase/app#FirebaseApp}. + * + * @public + */ +export function FirebaseTelemetry({ + firebaseOptions +}: { + firebaseOptions?: FirebaseOptions; +}): null { + useEffect(() => { if (typeof window === 'undefined') { return; } @@ -41,27 +63,23 @@ export class FirebaseTelemetry extends Component { process.env.OTEL_ENDPOINT = window.location.origin; try { - const telemetry = this.props.firebaseOptions - ? getTelemetry(initializeApp(this.props.firebaseOptions)) - : getTelemetry(); - - window.addEventListener('error', (event: ErrorEvent) => { - captureError(telemetry, event.error, {}); - }); - - window.addEventListener( - 'unhandledrejection', - (event: PromiseRejectionEvent) => { - captureError(telemetry, event.reason, {}); - } - ); + if (firebaseOptions) { + initializeApp(firebaseOptions); + } + window.addEventListener('error', errorListener); + window.addEventListener('unhandledrejection', unhandledRejectionListener); } catch (error) { // Log the error here, but don't die. console.warn(`Firebase Telemetry was not initialized:\n`, error); } - } + return () => { + window.removeEventListener('error', errorListener); + window.removeEventListener( + 'unhandledrejection', + unhandledRejectionListener + ); + }; + }, []); - render(): ReactNode { - return this.props.children; - } + return null; } From a3583c9ad0dfdcbc02d7adda9b0a823498cd07f2 Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 09:46:48 -0400 Subject: [PATCH 07/12] Fixed API extraction for subpath --- common/api-review/telemetry.api.md | 9 +- ...ry-react.api.md => telemetry.react.api.md} | 2 +- docs-devsite/_toc.yaml | 7 +- docs-devsite/telemetry.md | 126 +--------------- ...ation.md => telemetry_.instrumentation.md} | 2 +- docs-devsite/telemetry_.md | 138 ++++++++++++++++++ ...y.telemetry.md => telemetry_.telemetry.md} | 10 +- docs-devsite/telemetry_react.md | 58 ++++++++ packages/telemetry/api-extractor.json | 17 +-- packages/telemetry/api-extractor.react.json | 17 --- packages/telemetry/package.json | 6 +- 11 files changed, 225 insertions(+), 167 deletions(-) rename common/api-review/{telemetry-react.api.md => telemetry.react.api.md} (86%) rename docs-devsite/{telemetry.instrumentation.md => telemetry_.instrumentation.md} (87%) create mode 100644 docs-devsite/telemetry_.md rename docs-devsite/{telemetry.telemetry.md => telemetry_.telemetry.md} (55%) create mode 100644 docs-devsite/telemetry_react.md delete mode 100644 packages/telemetry/api-extractor.react.json diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 623299b1ee8..066c7c9e4e2 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,7 +6,6 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; -import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -18,7 +17,13 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -export { Instrumentation } +// @public (undocumented) +export namespace Instrumentation { + // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts + // + // (undocumented) + export type onRequestError = InstrumentationOnRequestError; +} // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/common/api-review/telemetry-react.api.md b/common/api-review/telemetry.react.api.md similarity index 86% rename from common/api-review/telemetry-react.api.md rename to common/api-review/telemetry.react.api.md index d7eeb9b53ea..560a395ca7f 100644 --- a/common/api-review/telemetry-react.api.md +++ b/common/api-review/telemetry.react.api.md @@ -1,4 +1,4 @@ -## API Report File for "@firebase/telemetry-react" +## API Report File for "@firebase/telemetry/react" > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml index 1b5243a1d11..b814910c792 100644 --- a/docs-devsite/_toc.yaml +++ b/docs-devsite/_toc.yaml @@ -687,7 +687,10 @@ toc: - title: UploadTaskSnapshot path: /docs/reference/js/storage.uploadtasksnapshot.md - title: telemetry - path: /docs/reference/js/telemetry.md + path: /docs/reference/js/telemetry_.md section: - title: Telemetry - path: /docs/reference/js/telemetry.telemetry.md + path: /docs/reference/js/telemetry_.telemetry.md +- title: telemetry/react + path: /docs/reference/js/telemetry_react.md + section: [] diff --git a/docs-devsite/telemetry.md b/docs-devsite/telemetry.md index fa62b62e7b8..c533e886f4f 100644 --- a/docs-devsite/telemetry.md +++ b/docs-devsite/telemetry.md @@ -11,128 +11,8 @@ https://github.com/firebase/firebase-js-sdk # telemetry package -## Functions - -| Function | Description | -| --- | --- | -| function(app, ...) | -| [getTelemetry(app)](./telemetry.md#gettelemetry_cf608e1) | Returns the default [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance that is associated with the provided [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). If no instance exists, initializes a new instance with the default settings. | -| function(telemetry, ...) | -| [captureError(telemetry, error, attributes)](./telemetry.md#captureerror_862e6b3) | Enqueues an error to be uploaded to the Firebase Telemetry API. | -| [flush(telemetry)](./telemetry.md#flush_8975134) | Flushes all enqueued telemetry data immediately, instead of waiting for default batching. | - -## Interfaces - -| Interface | Description | -| --- | --- | -| [Telemetry](./telemetry.telemetry.md#telemetry_interface) | An instance of the Firebase Telemetry SDK.Do not create this instance directly. Instead, use [getTelemetry()](./telemetry.md#gettelemetry_cf608e1). | - -## Namespaces - -| Namespace | Description | +| Entry Point | Description | | --- | --- | -| [Instrumentation](./telemetry.instrumentation.md#instrumentation_namespace) | | - -## Variables - -| Variable | Description | -| --- | --- | -| [nextOnRequestError](./telemetry.md#nextonrequesterror) | Automatically report uncaught errors from server routes to Firebase Telemetry. | - -## function(app, ...) - -### getTelemetry(app) {:#gettelemetry_cf608e1} - -Returns the default [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance that is associated with the provided [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). If no instance exists, initializes a new instance with the default settings. - -Signature: - -```typescript -export declare function getTelemetry(app?: FirebaseApp): Telemetry; -``` - -#### Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| app | [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) to use. | - -Returns: - -[Telemetry](./telemetry.telemetry.md#telemetry_interface) - -The default [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance for the given [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). - -### Example - - -```javascript -const telemetry = getTelemetry(app); - -``` - -## function(telemetry, ...) - -### captureError(telemetry, error, attributes) {:#captureerror_862e6b3} - -Enqueues an error to be uploaded to the Firebase Telemetry API. - -Signature: - -```typescript -export declare function captureError(telemetry: Telemetry, error: unknown, attributes?: AnyValueMap): void; -``` - -#### Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| telemetry | [Telemetry](./telemetry.telemetry.md#telemetry_interface) | The [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance. | -| error | unknown | The caught exception, typically an | -| attributes | AnyValueMap | = Optional, arbitrary attributes to attach to the error log | - -Returns: - -void - -### flush(telemetry) {:#flush_8975134} - -Flushes all enqueued telemetry data immediately, instead of waiting for default batching. - -Signature: - -```typescript -export declare function flush(telemetry: Telemetry): Promise; -``` - -#### Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| telemetry | [Telemetry](./telemetry.telemetry.md#telemetry_interface) | The [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance. | - -Returns: - -Promise<void> - -a promise which is resolved when all flushes are complete - -## nextOnRequestError - -Automatically report uncaught errors from server routes to Firebase Telemetry. - -Signature: - -```typescript -nextOnRequestError: Instrumentation.onRequestError -``` - -### Example - - -```javascript -// In instrumentation.ts (https://nextjs.org/docs/app/guides/instrumentation): -export { nextOnRequestError as onRequestError } from 'firebase/telemetry' - -``` +| [/](./telemetry_.md#@firebase/telemetry) | | +| [/react](./telemetry_react.md#@firebase/telemetry/react) | | diff --git a/docs-devsite/telemetry.instrumentation.md b/docs-devsite/telemetry_.instrumentation.md similarity index 87% rename from docs-devsite/telemetry.instrumentation.md rename to docs-devsite/telemetry_.instrumentation.md index 2e2be64711e..d1e2855f188 100644 --- a/docs-devsite/telemetry.instrumentation.md +++ b/docs-devsite/telemetry_.instrumentation.md @@ -20,7 +20,7 @@ export declare namespace Instrumentation | Type Alias | Description | | --- | --- | -| [onRequestError](./telemetry.instrumentation.md#instrumentationonrequesterror) | | +| [onRequestError](./telemetry_.instrumentation.md#instrumentationonrequesterror) | | ## Instrumentation.onRequestError diff --git a/docs-devsite/telemetry_.md b/docs-devsite/telemetry_.md new file mode 100644 index 00000000000..07e5c629012 --- /dev/null +++ b/docs-devsite/telemetry_.md @@ -0,0 +1,138 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# @firebase/telemetry + +## Functions + +| Function | Description | +| --- | --- | +| function(app, ...) | +| [getTelemetry(app)](./telemetry_.md#gettelemetry_cf608e1) | Returns the default [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance that is associated with the provided [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). If no instance exists, initializes a new instance with the default settings. | +| function(telemetry, ...) | +| [captureError(telemetry, error, attributes)](./telemetry_.md#captureerror_862e6b3) | Enqueues an error to be uploaded to the Firebase Telemetry API. | +| [flush(telemetry)](./telemetry_.md#flush_8975134) | Flushes all enqueued telemetry data immediately, instead of waiting for default batching. | + +## Interfaces + +| Interface | Description | +| --- | --- | +| [Telemetry](./telemetry_.telemetry.md#telemetry_interface) | An instance of the Firebase Telemetry SDK.Do not create this instance directly. Instead, use [getTelemetry()](./telemetry_.md#gettelemetry_cf608e1). | + +## Namespaces + +| Namespace | Description | +| --- | --- | +| [Instrumentation](./telemetry_.instrumentation.md#instrumentation_namespace) | | + +## Variables + +| Variable | Description | +| --- | --- | +| [nextOnRequestError](./telemetry_.md#nextonrequesterror) | Automatically report uncaught errors from server routes to Firebase Telemetry. | + +## function(app, ...) + +### getTelemetry(app) {:#gettelemetry_cf608e1} + +Returns the default [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance that is associated with the provided [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). If no instance exists, initializes a new instance with the default settings. + +Signature: + +```typescript +export declare function getTelemetry(app?: FirebaseApp): Telemetry; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| app | [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) to use. | + +Returns: + +[Telemetry](./telemetry_.telemetry.md#telemetry_interface) + +The default [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance for the given [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). + +### Example + + +```javascript +const telemetry = getTelemetry(app); + +``` + +## function(telemetry, ...) + +### captureError(telemetry, error, attributes) {:#captureerror_862e6b3} + +Enqueues an error to be uploaded to the Firebase Telemetry API. + +Signature: + +```typescript +export declare function captureError(telemetry: Telemetry, error: unknown, attributes?: AnyValueMap): void; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| telemetry | [Telemetry](./telemetry_.telemetry.md#telemetry_interface) | The [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance. | +| error | unknown | The caught exception, typically an | +| attributes | AnyValueMap | = Optional, arbitrary attributes to attach to the error log | + +Returns: + +void + +### flush(telemetry) {:#flush_8975134} + +Flushes all enqueued telemetry data immediately, instead of waiting for default batching. + +Signature: + +```typescript +export declare function flush(telemetry: Telemetry): Promise; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| telemetry | [Telemetry](./telemetry_.telemetry.md#telemetry_interface) | The [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance. | + +Returns: + +Promise<void> + +a promise which is resolved when all flushes are complete + +## nextOnRequestError + +Automatically report uncaught errors from server routes to Firebase Telemetry. + +Signature: + +```typescript +nextOnRequestError: Instrumentation.onRequestError +``` + +### Example + + +```javascript +// In instrumentation.ts (https://nextjs.org/docs/app/guides/instrumentation): +export { nextOnRequestError as onRequestError } from 'firebase/telemetry' + +``` + diff --git a/docs-devsite/telemetry.telemetry.md b/docs-devsite/telemetry_.telemetry.md similarity index 55% rename from docs-devsite/telemetry.telemetry.md rename to docs-devsite/telemetry_.telemetry.md index 3e7396f79d6..6ac8337e178 100644 --- a/docs-devsite/telemetry.telemetry.md +++ b/docs-devsite/telemetry_.telemetry.md @@ -12,7 +12,7 @@ https://github.com/firebase/firebase-js-sdk # Telemetry interface An instance of the Firebase Telemetry SDK. -Do not create this instance directly. Instead, use [getTelemetry()](./telemetry.md#gettelemetry_cf608e1). +Do not create this instance directly. Instead, use [getTelemetry()](./telemetry_.md#gettelemetry_cf608e1). Signature: @@ -24,12 +24,12 @@ export interface Telemetry | Property | Type | Description | | --- | --- | --- | -| [app](./telemetry.telemetry.md#telemetryapp) | [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance is associated with. | -| [loggerProvider](./telemetry.telemetry.md#telemetryloggerprovider) | LoggerProvider | The this [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance uses. | +| [app](./telemetry_.telemetry.md#telemetryapp) | [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance is associated with. | +| [loggerProvider](./telemetry_.telemetry.md#telemetryloggerprovider) | LoggerProvider | The this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance uses. | ## Telemetry.app -The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance is associated with. +The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance is associated with. Signature: @@ -39,7 +39,7 @@ app: FirebaseApp; ## Telemetry.loggerProvider -The this [Telemetry](./telemetry.telemetry.md#telemetry_interface) instance uses. +The this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance uses. Signature: diff --git a/docs-devsite/telemetry_react.md b/docs-devsite/telemetry_react.md new file mode 100644 index 00000000000..8857f508a6f --- /dev/null +++ b/docs-devsite/telemetry_react.md @@ -0,0 +1,58 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# @firebase/telemetry/react + +## Functions + +| Function | Description | +| --- | --- | +| [FirebaseTelemetry({ firebaseOptions })](./telemetry_react.md#firebasetelemetry_537af3f) | Registers event listeners for uncaught errors.This should be installed near the root of your application. Caught errors, including those implicitly caught by Error Boundaries, will not be captured by this component. | + +## function({ firebaseOptions }, ...) + +### FirebaseTelemetry({ firebaseOptions }) {:#firebasetelemetry_537af3f} + +Registers event listeners for uncaught errors. + +This should be installed near the root of your application. Caught errors, including those implicitly caught by Error Boundaries, will not be captured by this component. + +Signature: + +```typescript +export declare function FirebaseTelemetry({ firebaseOptions }: { + firebaseOptions?: FirebaseOptions; +}): null; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { firebaseOptions } | { firebaseOptions?: [FirebaseOptions](./app.firebaseoptions.md#firebaseoptions_interface); } | | + +Returns: + +null + +The default [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance for the given [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). + +### Example + + +```html + + + ... my app ... + + +``` + diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json index 3f246a76f68..691bd33faf9 100644 --- a/packages/telemetry/api-extractor.json +++ b/packages/telemetry/api-extractor.json @@ -2,16 +2,11 @@ "extends": "../../config/api-extractor.json", // Point it to your entry point d.ts file. "mainEntryPointFilePath": "/dist/index.d.ts", - "dtsRollup": { - "enabled": true, - "untrimmedFilePath": "/dist/.d.ts", - "betaTrimmedFilePath": "/dist/-public.d.ts" - }, - // "additionalEntryPoints": [ - // { - // "modulePath": "react", - // "filePath": "/dist/react/index.d.ts" - // } - // ], + "additionalEntryPoints": [ + { + "modulePath": "react", + "filePath": "/dist/src/react/index.d.ts" + } + ], "bundledPackages": ["next"] } diff --git a/packages/telemetry/api-extractor.react.json b/packages/telemetry/api-extractor.react.json deleted file mode 100644 index 6f8ef25c891..00000000000 --- a/packages/telemetry/api-extractor.react.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../config/api-extractor.json", - "mainEntryPointFilePath": "/dist/react/src/react/index.d.ts", - "dtsRollup": { - "enabled": true, - "untrimmedFilePath": "/dist/react/index.d.ts" - }//, - // "apiReport": { - // "enabled": false - // }, - // "docModel": { - // "enabled": false - // }, - // "tsdocMetadata": { - // "enabled": false - // } -} diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 47e9fdf16a0..2a58437e30b 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -48,11 +48,7 @@ "test:browser": "karma start", "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", - "api-report": "yarn api-report:react && yarn api-report:main", - "api-report:main": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' ts-node ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry --packageRoot . --typescriptDts ./dist/index.d.ts --rollupDts ./dist/index.d.ts --untrimmedRollupDts ./dist/index.d.ts --publicDts ./dist/index.d.ts", - "api-report:main1": "api-extractor run --local --verbose", - "api-report:react": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' ts-node ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry-react --packageRoot . --typescriptDts ./dist/src/react/index.d.ts --rollupDts ./dist/src/react/index.d.ts --untrimmedRollupDts ./dist/src/react/index.d.ts --publicDts ./dist/src/react/index.d.ts", - "api-report:react1": "api-extractor run --config api-extractor.react.json --local --verbose", + "api-report": "api-extractor run --local --verbose", "typings:public": "node ../../scripts/build/use_typings.js ./dist/telemetry-public.d.ts" }, "peerDependencies": { From 08d4de966c74d09a9e63eae79cebc57bf1e5de1f Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 09:51:54 -0400 Subject: [PATCH 08/12] Format --- packages/telemetry/rollup.config.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js index c40b4800cf9..e722e227f0c 100644 --- a/packages/telemetry/rollup.config.js +++ b/packages/telemetry/rollup.config.js @@ -110,8 +110,4 @@ const reactBuilds = [ } ]; -export default [ - ...browserBuilds, - ...nodeBuilds, - ...reactBuilds -]; +export default [...browserBuilds, ...nodeBuilds, ...reactBuilds]; From 2067d790af7db60dc593bd332df14e11bb452728 Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 10:11:15 -0400 Subject: [PATCH 09/12] Fix declaration file --- packages/telemetry/api-extractor.json | 2 +- packages/telemetry/package.json | 1 + packages/telemetry/rollup.config.js | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json index 691bd33faf9..da9f97ce0a2 100644 --- a/packages/telemetry/api-extractor.json +++ b/packages/telemetry/api-extractor.json @@ -5,7 +5,7 @@ "additionalEntryPoints": [ { "modulePath": "react", - "filePath": "/dist/src/react/index.d.ts" + "filePath": "/dist/react/index.d.ts" } ], "bundledPackages": ["next"] diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 2a58437e30b..0293c29cfdd 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -89,6 +89,7 @@ "react": "19.1.1", "react-dom": "19.1.1", "rollup": "2.79.2", + "rollup-plugin-copy": "3.5.0", "rollup-plugin-replace": "2.2.0", "rollup-plugin-typescript2": "0.36.0", "typescript": "5.5.4" diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js index e722e227f0c..fbeb28a5bd8 100644 --- a/packages/telemetry/rollup.config.js +++ b/packages/telemetry/rollup.config.js @@ -16,6 +16,7 @@ */ import json from '@rollup/plugin-json'; +import copy from 'rollup-plugin-copy'; import typescriptPlugin from 'rollup-plugin-typescript2'; import typescript from 'typescript'; import pkg from './package.json'; @@ -87,7 +88,15 @@ const reactBuilds = [ typescript, tsconfig: 'tsconfig.react.json' }), - json() + json(), + copy({ + targets: [ + { + src: 'dist/src/react/index.d.ts', + dest: 'dist/react' + } + ] + }) ], external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) }, From d40fa1c4e2c81b4648d2b28ac9ab4782d46780e8 Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 11:17:34 -0400 Subject: [PATCH 10/12] Fix public typings --- common/api-review/telemetry.api.md | 9 ++------- packages/telemetry/package.json | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 066c7c9e4e2..623299b1ee8 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,6 +6,7 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; +import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -17,13 +18,7 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -// @public (undocumented) -export namespace Instrumentation { - // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts - // - // (undocumented) - export type onRequestError = InstrumentationOnRequestError; -} +export { Instrumentation } // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 0293c29cfdd..7aa8eeae848 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -48,7 +48,7 @@ "test:browser": "karma start", "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", - "api-report": "api-extractor run --local --verbose", + "api-report": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry --packageRoot . --typescriptDts ./dist/index.d.ts --rollupDts ./dist/private.d.ts --untrimmedRollupDts ./dist/internal.d.ts --publicDts ./dist/telemetry-public.d.ts", "typings:public": "node ../../scripts/build/use_typings.js ./dist/telemetry-public.d.ts" }, "peerDependencies": { From 157cf6bb6755971b37c0c018f31bceaf504699f0 Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 12:49:38 -0400 Subject: [PATCH 11/12] Fix public typings --- common/api-review/telemetry.api.md | 9 +++++++-- packages/telemetry/package.json | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 623299b1ee8..066c7c9e4e2 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,7 +6,6 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; -import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -18,7 +17,13 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -export { Instrumentation } +// @public (undocumented) +export namespace Instrumentation { + // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts + // + // (undocumented) + export type onRequestError = InstrumentationOnRequestError; +} // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 7aa8eeae848..e8941488f1f 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -48,8 +48,8 @@ "test:browser": "karma start", "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", - "api-report": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry --packageRoot . --typescriptDts ./dist/index.d.ts --rollupDts ./dist/private.d.ts --untrimmedRollupDts ./dist/internal.d.ts --publicDts ./dist/telemetry-public.d.ts", - "typings:public": "node ../../scripts/build/use_typings.js ./dist/telemetry-public.d.ts" + "api-report": "api-extractor run --local --verbose", + "typings:public": "node ../../scripts/build/use_typings.js ./dist/index.d.ts" }, "peerDependencies": { "@firebase/app": "0.x", @@ -102,7 +102,7 @@ "bugs": { "url": "https://github.com/firebase/firebase-js-sdk/issues" }, - "typings": "./dist/telemetry-public.d.ts", + "typings": "./dist/index.d.ts", "nyc": { "extension": [ ".ts" From 04b7f7f359fde8853cf2d363d2d3704af75175e0 Mon Sep 17 00:00:00 2001 From: abrook Date: Mon, 29 Sep 2025 13:49:05 -0400 Subject: [PATCH 12/12] Fix public typings --- common/api-review/telemetry-react.api.md | 17 +++++++++++++++++ common/api-review/telemetry.api.md | 9 ++------- packages/telemetry/api-extractor.json | 10 +++++++++- packages/telemetry/package.json | 11 +++++++---- 4 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 common/api-review/telemetry-react.api.md diff --git a/common/api-review/telemetry-react.api.md b/common/api-review/telemetry-react.api.md new file mode 100644 index 00000000000..d7eeb9b53ea --- /dev/null +++ b/common/api-review/telemetry-react.api.md @@ -0,0 +1,17 @@ +## API Report File for "@firebase/telemetry-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { FirebaseOptions } from '@firebase/app'; + +// @public +export function FirebaseTelemetry({ firebaseOptions }: { + firebaseOptions?: FirebaseOptions; +}): null; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 066c7c9e4e2..623299b1ee8 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -6,6 +6,7 @@ import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; +import { Instrumentation } from 'next'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public @@ -17,13 +18,7 @@ export function flush(telemetry: Telemetry): Promise; // @public export function getTelemetry(app?: FirebaseApp): Telemetry; -// @public (undocumented) -export namespace Instrumentation { - // Warning: (ae-forgotten-export) The symbol "InstrumentationOnRequestError" needs to be exported by the entry point index.d.ts - // - // (undocumented) - export type onRequestError = InstrumentationOnRequestError; -} +export { Instrumentation } // @public export const nextOnRequestError: Instrumentation.onRequestError; diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json index da9f97ce0a2..7bc55b00d75 100644 --- a/packages/telemetry/api-extractor.json +++ b/packages/telemetry/api-extractor.json @@ -1,6 +1,5 @@ { "extends": "../../config/api-extractor.json", - // Point it to your entry point d.ts file. "mainEntryPointFilePath": "/dist/index.d.ts", "additionalEntryPoints": [ { @@ -8,5 +7,14 @@ "filePath": "/dist/react/index.d.ts" } ], + "dtsRollup": { + // rollup is not supported when multiple entry points are present. + // npm script api-report:* is used to generate dts rollup. + "enabled": false + }, + "apiReport": { + // apiReport is handled by npm script api-report:* + "enabled": false + }, "bundledPackages": ["next"] } diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index e8941488f1f..d1c6a9c8ab2 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -8,7 +8,7 @@ "browser": "dist/index.esm.js", "exports": { ".": { - "types": "./dist/index.d.ts", + "types": "./dist/index-public.d.ts", "node": { "import": "./dist/node-esm/index.node.esm.js", "default": "./dist/index.node.cjs.js" @@ -20,7 +20,7 @@ "default": "./dist/index.esm.js" }, "./react": { - "types": "./dist/react/index.d.ts", + "types": "./dist/react/index-public.d.ts", "node": { "import": "./dist/react/index.esm.js", "default": "./dist/react/index.cjs.js" @@ -48,8 +48,11 @@ "test:browser": "karma start", "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", - "api-report": "api-extractor run --local --verbose", - "typings:public": "node ../../scripts/build/use_typings.js ./dist/index.d.ts" + "api-report": "yarn api-report:main && yarn api-report:react && yarn api-report:api-json", + "api-report:main": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry --packageRoot . --typescriptDts ./dist/index.d.ts --rollupDts ./dist/private.d.ts --untrimmedRollupDts ./dist/internal.d.ts --publicDts ./dist/index-public.d.ts", + "api-report:react": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry-react --packageRoot . --typescriptDts ./dist/react/index.d.ts --rollupDts ./dist/react/private.d.ts --untrimmedRollupDts ./dist/react/internal.d.ts --publicDts ./dist/react/index-public.d.ts", + "api-report:api-json": "api-extractor run --local --verbose", + "typings:public": "node ../../scripts/build/use_typings.js ./dist/index-public.d.ts" }, "peerDependencies": { "@firebase/app": "0.x",