From 1796d06992bf4f1a9ca702631455a094511a5daf Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 1 May 2026 12:25:12 +0100 Subject: [PATCH 1/8] refactor(ml): convert package sources to TypeScript --- packages/ml/lib/index.js | 57 ----------------------- packages/ml/lib/{index.d.ts => index.ts} | 58 +++++++++++++++++++----- packages/ml/lib/modular/index.d.ts | 14 ------ packages/ml/lib/modular/index.js | 17 ------- packages/ml/lib/modular/index.ts | 20 ++++++++ packages/ml/package.json | 44 ++++++++++++++++-- packages/ml/tsconfig.json | 13 ++++++ 7 files changed, 119 insertions(+), 104 deletions(-) delete mode 100644 packages/ml/lib/index.js rename packages/ml/lib/{index.d.ts => index.ts} (63%) delete mode 100644 packages/ml/lib/modular/index.d.ts delete mode 100644 packages/ml/lib/modular/index.js create mode 100644 packages/ml/lib/modular/index.ts create mode 100644 packages/ml/tsconfig.json diff --git a/packages/ml/lib/index.js b/packages/ml/lib/index.js deleted file mode 100644 index e0da7630e9..0000000000 --- a/packages/ml/lib/index.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016-present Invertase Limited & Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this library 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 { - createModuleNamespace, - FirebaseModule, - getFirebaseRoot, -} from '@react-native-firebase/app/dist/module/internal'; -import version from './version'; - -const statics = {}; - -const namespace = 'ml'; - -const nativeModuleName = 'RNFBMLModule'; - -class FirebaseMLModule extends FirebaseModule {} - -// import { SDK_VERSION } from '@react-native-firebase/ml'; -export const SDK_VERSION = version; - -export * from './modular'; - -// import ML from '@react-native-firebase/ml'; -// ml().X(...); -export default createModuleNamespace({ - statics, - version, - namespace, - nativeModuleName, - nativeEvents: false, - hasMultiAppSupport: true, - hasCustomUrlOrRegionSupport: false, - ModuleClass: FirebaseMLModule, -}); - -// import ml, { firebase } from '@react-native-firebase/ml'; -// ml().X(...); -// firebase.ml().X(...); -export const firebase = getFirebaseRoot(); - -// e.g. -// // import { MLCloudTextRecognizerModelType } from '@react-native-firebase/ml'; diff --git a/packages/ml/lib/index.d.ts b/packages/ml/lib/index.ts similarity index 63% rename from packages/ml/lib/index.d.ts rename to packages/ml/lib/index.ts index 127437634e..5e7f9978ae 100644 --- a/packages/ml/lib/index.d.ts +++ b/packages/ml/lib/index.ts @@ -15,7 +15,14 @@ * */ -import { ReactNativeFirebase } from '@react-native-firebase/app'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import { + createModuleNamespace, + FirebaseModule, + getFirebaseRoot, +} from '@react-native-firebase/app/dist/module/internal'; +import { version } from './version'; + /** * Firebase ML package for React Native. * @@ -53,13 +60,13 @@ import { ReactNativeFirebase } from '@react-native-firebase/app'; * @firebase ml */ export namespace FirebaseMLTypes { - import FirebaseModule = ReactNativeFirebase.FirebaseModule; + type FirebaseModule = ReactNativeFirebase.FirebaseModule; export interface Statics { SDK_VERSION: string; } - export class Module extends FirebaseModule { + export interface Module extends FirebaseModule { /** * The current `FirebaseApp` instance for this Firebase service. */ @@ -75,25 +82,54 @@ type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< app(name?: string): ReactNativeFirebase.FirebaseApp; }; -declare const defaultExport: MLNamespace; - -export const firebase: ReactNativeFirebase.Module & { - ml: typeof defaultExport; - app(name?: string): ReactNativeFirebase.FirebaseApp & { ml(): FirebaseMLTypes.Module }; +const statics = { + SDK_VERSION, }; -export default defaultExport; +const namespace = 'ml'; + +const nativeModuleName = 'RNFBMLModule'; + +class FirebaseMLModule extends FirebaseModule {} + +// import { SDK_VERSION } from '@react-native-firebase/ml'; +export const SDK_VERSION = version; export * from './modular'; +// import ML from '@react-native-firebase/ml'; +// ml().X(...); +const defaultExport = createModuleNamespace({ + statics, + version, + namespace, + nativeModuleName, + nativeEvents: false, + hasMultiAppSupport: true, + hasCustomUrlOrRegionSupport: false, + ModuleClass: FirebaseMLModule, +}) as MLNamespace; + +export default defaultExport; + +// import ml, { firebase } from '@react-native-firebase/ml'; +// ml().X(...); +// firebase.ml().X(...); +export const firebase = getFirebaseRoot() as ReactNativeFirebase.Module & { + ml: typeof defaultExport; + app(name?: string): ReactNativeFirebase.FirebaseApp & { ml(): FirebaseMLTypes.Module }; +}; + /** * Attach namespace to `firebase.` and `FirebaseApp.`. */ declare module '@react-native-firebase/app' { namespace ReactNativeFirebase { - import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; interface Module { - ml: FirebaseModuleWithStaticsAndApp; + ml: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseMLTypes.Module, + FirebaseMLTypes.Statics + >; } interface FirebaseApp { diff --git a/packages/ml/lib/modular/index.d.ts b/packages/ml/lib/modular/index.d.ts deleted file mode 100644 index d5569800c8..0000000000 --- a/packages/ml/lib/modular/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ReactNativeFirebase } from '@react-native-firebase/app'; -import { FirebaseMLTypes } from '..'; - -type FirebaseML = FirebaseMLTypes.Module; -import FirebaseApp = ReactNativeFirebase.FirebaseApp; - -/** - * Returns the existing default {@link FirebaseML} instance that is associated with the - * default {@link @firebase/app!FirebaseApp}. If no instance exists, initializes a new - * instance with default settings. - * - * @returns The {@link FirebaseML} instance of the provided app. - */ -export declare function getML(app?: FirebaseApp): FirebaseML; diff --git a/packages/ml/lib/modular/index.js b/packages/ml/lib/modular/index.js deleted file mode 100644 index 8000bc832d..0000000000 --- a/packages/ml/lib/modular/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { getApp } from '@react-native-firebase/app'; - -/** - * @typedef {import('@firebase/app').FirebaseApp} FirebaseApp - * @typedef {import('..').FirebaseMLTypes.Module} FirebaseML - */ - -/** - * @param {FirebaseApp | undefined} app - * @returns {FirebaseML} - */ -export function getML(app) { - if (app) { - return getApp(app.name).ml(); - } - return getApp().ml(); -} diff --git a/packages/ml/lib/modular/index.ts b/packages/ml/lib/modular/index.ts new file mode 100644 index 0000000000..a58070a307 --- /dev/null +++ b/packages/ml/lib/modular/index.ts @@ -0,0 +1,20 @@ +import { getApp } from '@react-native-firebase/app'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import type { FirebaseMLTypes } from '..'; + +type FirebaseApp = ReactNativeFirebase.FirebaseApp; +type FirebaseML = FirebaseMLTypes.Module; + +/** + * Returns the existing default {@link FirebaseML} instance that is associated with the + * default {@link @firebase/app!FirebaseApp}. If no instance exists, initializes a new + * instance with default settings. + * + * @returns The {@link FirebaseML} instance of the provided app. + */ +export function getML(app?: FirebaseApp): FirebaseML { + if (app) { + return getApp(app.name).ml(); + } + return getApp().ml(); +} diff --git a/packages/ml/package.json b/packages/ml/package.json index d43a1fd358..8b9e34c7a6 100644 --- a/packages/ml/package.json +++ b/packages/ml/package.json @@ -3,12 +3,13 @@ "version": "24.1.0", "author": "Invertase (http://invertase.io)", "description": "React Native Firebase - Firebase ML brings the power of machine learning vision to your React Native application, supporting both Android & iOS.", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "main": "./dist/module/index.js", + "types": "./dist/typescript/lib/index.d.ts", "scripts": { - "build": "genversion --semi lib/version.js", + "build": "genversion --esm --semi lib/version.ts", "build:clean": "rimraf android/build && rimraf ios/build", - "prepare": "yarn run build" + "compile": "bob build", + "prepare": "yarn run build && yarn compile" }, "repository": { "type": "git", @@ -31,5 +32,38 @@ "publishConfig": { "access": "public", "provenance": true - } + }, + "devDependencies": { + "react-native-builder-bob": "^0.40.13" + }, + "exports": { + ".": { + "source": "./lib/index.ts", + "types": "./dist/typescript/lib/index.d.ts", + "default": "./dist/module/index.js" + }, + "./package.json": "./package.json" + }, + "react-native-builder-bob": { + "source": "lib", + "output": "dist", + "targets": [ + [ + "module", + { + "esm": true + } + ], + [ + "typescript", + { + "tsc": "../../node_modules/.bin/tsc" + } + ] + ] + }, + "eslintIgnore": [ + "node_modules/", + "dist/" + ] } diff --git a/packages/ml/tsconfig.json b/packages/ml/tsconfig.json new file mode 100644 index 0000000000..bfa760de4a --- /dev/null +++ b/packages/ml/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.packages.base.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": ".", + "paths": { + "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"], + "@react-native-firebase/app": ["../app/dist/typescript/lib"] + } + }, + "include": ["lib/**/*"], + "exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"] +} From 5dee7c3e780f6abcc1104811ff482b9bfd0cc7da Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 1 May 2026 12:29:53 +0100 Subject: [PATCH 2/8] refactor(ml): split modular and namespaced TypeScript surfaces --- packages/ml/lib/index.ts | 122 +--------------------------- packages/ml/lib/modular.ts | 34 ++++++++ packages/ml/lib/modular/index.ts | 20 ----- packages/ml/lib/namespaced.ts | 67 +++++++++++++++ packages/ml/lib/types/internal.ts | 22 +++++ packages/ml/lib/types/ml.ts | 26 ++++++ packages/ml/lib/types/namespaced.ts | 99 ++++++++++++++++++++++ 7 files changed, 252 insertions(+), 138 deletions(-) create mode 100644 packages/ml/lib/modular.ts delete mode 100644 packages/ml/lib/modular/index.ts create mode 100644 packages/ml/lib/namespaced.ts create mode 100644 packages/ml/lib/types/internal.ts create mode 100644 packages/ml/lib/types/ml.ts create mode 100644 packages/ml/lib/types/namespaced.ts diff --git a/packages/ml/lib/index.ts b/packages/ml/lib/index.ts index 5e7f9978ae..ce3149cd21 100644 --- a/packages/ml/lib/index.ts +++ b/packages/ml/lib/index.ts @@ -15,125 +15,11 @@ * */ -import type { ReactNativeFirebase } from '@react-native-firebase/app'; -import { - createModuleNamespace, - FirebaseModule, - getFirebaseRoot, -} from '@react-native-firebase/app/dist/module/internal'; -import { version } from './version'; +export type { FirebaseML } from './types/ml'; -/** - * Firebase ML package for React Native. - * - * #### Example 1 - * - * Access the firebase export from the `ml` package: - * - * ```js - * import { firebase } from '@react-native-firebase/ml'; - * - * // firebase.ml().X - * ``` - * - * #### Example 2 - * - * Using the default export from the `ml` package: - * - * ```js - * import ml from '@react-native-firebase/ml'; - * - * // ml().X - * ``` - * - * #### Example 3 - * - * Using the default export from the `app` package: - * - * ```js - * import firebase from '@react-native-firebase/app'; - * import '@react-native-firebase/ml'; - * - * // firebase.ml().X - * ``` - * - * @firebase ml - */ -export namespace FirebaseMLTypes { - type FirebaseModule = ReactNativeFirebase.FirebaseModule; - - export interface Statics { - SDK_VERSION: string; - } - - export interface Module extends FirebaseModule { - /** - * The current `FirebaseApp` instance for this Firebase service. - */ - app: ReactNativeFirebase.FirebaseApp; - } -} - -type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< - FirebaseMLTypes.Module, - FirebaseMLTypes.Statics -> & { - firebase: ReactNativeFirebase.Module; - app(name?: string): ReactNativeFirebase.FirebaseApp; -}; - -const statics = { - SDK_VERSION, -}; - -const namespace = 'ml'; - -const nativeModuleName = 'RNFBMLModule'; - -class FirebaseMLModule extends FirebaseModule {} - -// import { SDK_VERSION } from '@react-native-firebase/ml'; -export const SDK_VERSION = version; +export type { FirebaseMLTypes } from './types/namespaced'; export * from './modular'; -// import ML from '@react-native-firebase/ml'; -// ml().X(...); -const defaultExport = createModuleNamespace({ - statics, - version, - namespace, - nativeModuleName, - nativeEvents: false, - hasMultiAppSupport: true, - hasCustomUrlOrRegionSupport: false, - ModuleClass: FirebaseMLModule, -}) as MLNamespace; - -export default defaultExport; - -// import ml, { firebase } from '@react-native-firebase/ml'; -// ml().X(...); -// firebase.ml().X(...); -export const firebase = getFirebaseRoot() as ReactNativeFirebase.Module & { - ml: typeof defaultExport; - app(name?: string): ReactNativeFirebase.FirebaseApp & { ml(): FirebaseMLTypes.Module }; -}; - -/** - * Attach namespace to `firebase.` and `FirebaseApp.`. - */ -declare module '@react-native-firebase/app' { - namespace ReactNativeFirebase { - interface Module { - ml: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< - FirebaseMLTypes.Module, - FirebaseMLTypes.Statics - >; - } - - interface FirebaseApp { - ml(): FirebaseMLTypes.Module; - } - } -} +export * from './namespaced'; +export { default } from './namespaced'; diff --git a/packages/ml/lib/modular.ts b/packages/ml/lib/modular.ts new file mode 100644 index 0000000000..4b49b61283 --- /dev/null +++ b/packages/ml/lib/modular.ts @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library 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 { getApp } from '@react-native-firebase/app'; +import type { FirebaseApp } from '@react-native-firebase/app'; +import type { FirebaseML } from './types/ml'; + +/** + * Returns the existing default {@link FirebaseML} instance that is associated with the + * default {@link @firebase/app!FirebaseApp}. If no instance exists, initializes a new + * instance with default settings. + * + * @returns The {@link FirebaseML} instance of the provided app. + */ +export function getML(app?: FirebaseApp): FirebaseML { + if (app) { + return getApp(app.name).ml(); + } + return getApp().ml(); +} diff --git a/packages/ml/lib/modular/index.ts b/packages/ml/lib/modular/index.ts deleted file mode 100644 index a58070a307..0000000000 --- a/packages/ml/lib/modular/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getApp } from '@react-native-firebase/app'; -import type { ReactNativeFirebase } from '@react-native-firebase/app'; -import type { FirebaseMLTypes } from '..'; - -type FirebaseApp = ReactNativeFirebase.FirebaseApp; -type FirebaseML = FirebaseMLTypes.Module; - -/** - * Returns the existing default {@link FirebaseML} instance that is associated with the - * default {@link @firebase/app!FirebaseApp}. If no instance exists, initializes a new - * instance with default settings. - * - * @returns The {@link FirebaseML} instance of the provided app. - */ -export function getML(app?: FirebaseApp): FirebaseML { - if (app) { - return getApp(app.name).ml(); - } - return getApp().ml(); -} diff --git a/packages/ml/lib/namespaced.ts b/packages/ml/lib/namespaced.ts new file mode 100644 index 0000000000..5665f6dc23 --- /dev/null +++ b/packages/ml/lib/namespaced.ts @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library 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 type { ReactNativeFirebase } from '@react-native-firebase/app'; +import { + createModuleNamespace, + FirebaseModule, + getFirebaseRoot, +} from '@react-native-firebase/app/dist/module/internal'; +import type { FirebaseMLTypes } from './types/namespaced'; +import { version } from './version'; + +const statics = { + SDK_VERSION: version, +}; + +const namespace = 'ml'; + +const nativeModuleName = 'RNFBMLModule'; + +class FirebaseMLModule extends FirebaseModule {} + +type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseMLTypes.Module, + FirebaseMLTypes.Statics +> & { + firebase: ReactNativeFirebase.Module; + app(name?: string): ReactNativeFirebase.FirebaseApp; +}; + +// import { SDK_VERSION } from '@react-native-firebase/ml'; +export const SDK_VERSION = version; + +const defaultExport = createModuleNamespace({ + statics, + version, + namespace, + nativeModuleName, + nativeEvents: false, + hasMultiAppSupport: true, + hasCustomUrlOrRegionSupport: false, + ModuleClass: FirebaseMLModule, +}) as unknown as MLNamespace; + +export default defaultExport; + +// import ml, { firebase } from '@react-native-firebase/ml'; +// ml().X(...); +// firebase.ml().X(...); +export const firebase = getFirebaseRoot() as unknown as ReactNativeFirebase.Module & { + ml: typeof defaultExport; + app(name?: string): ReactNativeFirebase.FirebaseApp & { ml(): FirebaseMLTypes.Module }; +}; diff --git a/packages/ml/lib/types/internal.ts b/packages/ml/lib/types/internal.ts new file mode 100644 index 0000000000..eff478b8cc --- /dev/null +++ b/packages/ml/lib/types/internal.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library 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. + * + */ + +/** + * Internal bridge types for `@react-native-firebase/ml`. + * Native module contracts are expanded in later migration stages. + */ +export {}; diff --git a/packages/ml/lib/types/ml.ts b/packages/ml/lib/types/ml.ts new file mode 100644 index 0000000000..8f7d0a850b --- /dev/null +++ b/packages/ml/lib/types/ml.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library 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 type { FirebaseApp } from '@react-native-firebase/app'; + +/** + * Firebase ML module instance for the modular API. + */ +export interface FirebaseML { + /** The FirebaseApp this module is associated with */ + app: FirebaseApp; +} diff --git a/packages/ml/lib/types/namespaced.ts b/packages/ml/lib/types/namespaced.ts new file mode 100644 index 0000000000..4a59240e74 --- /dev/null +++ b/packages/ml/lib/types/namespaced.ts @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library 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 type { ReactNativeFirebase } from '@react-native-firebase/app'; + +/** + * Firebase ML package for React Native. + * + * #### Example 1 + * + * Access the firebase export from the `ml` package: + * + * ```js + * import { firebase } from '@react-native-firebase/ml'; + * + * // firebase.ml().X + * ``` + * + * #### Example 2 + * + * Using the default export from the `ml` package: + * + * ```js + * import ml from '@react-native-firebase/ml'; + * + * // ml().X + * ``` + * + * #### Example 3 + * + * Using the default export from the `app` package: + * + * ```js + * import firebase from '@react-native-firebase/app'; + * import '@react-native-firebase/ml'; + * + * // firebase.ml().X + * ``` + * + * @firebase ml + */ +/** + * @deprecated Use the exported types directly instead. + * FirebaseMLTypes namespace is kept for backwards compatibility. + */ +/* eslint-disable @typescript-eslint/no-namespace */ +export namespace FirebaseMLTypes { + /** + * @deprecated Use the exported types directly instead. FirebaseMLTypes namespace is kept for backwards compatibility. + */ + type FirebaseModule = ReactNativeFirebase.FirebaseModule; + + /** + * @deprecated Use the default export statics instead. + */ + export interface Statics { + /** @deprecated Use the default export statics instead. */ + SDK_VERSION: string; + } + + /** + * @deprecated Use the exported `FirebaseML` type instead. + */ + export interface Module extends FirebaseModule { + /** + * @deprecated Use the exported `FirebaseML` type instead. + * + * The current `FirebaseApp` instance for this Firebase service. + */ + app: ReactNativeFirebase.FirebaseApp; + } +} + +declare module '@react-native-firebase/app' { + namespace ReactNativeFirebase { + interface Module { + ml: FirebaseModuleWithStaticsAndApp; + } + + interface FirebaseApp { + ml(): FirebaseMLTypes.Module; + } + } +} +/* eslint-enable @typescript-eslint/no-namespace */ From 90b73a29b596ee6f4bd9b50931bcd62c646164e4 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 1 May 2026 12:34:11 +0100 Subject: [PATCH 3/8] refactor(ml): type namespaced module and native bridge --- packages/ml/lib/namespaced.ts | 3 ++- packages/ml/lib/types/internal.ts | 13 ++++++++++--- packages/ml/tsconfig.json | 3 +++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/ml/lib/namespaced.ts b/packages/ml/lib/namespaced.ts index 5665f6dc23..dc838e65c9 100644 --- a/packages/ml/lib/namespaced.ts +++ b/packages/ml/lib/namespaced.ts @@ -21,6 +21,7 @@ import { FirebaseModule, getFirebaseRoot, } from '@react-native-firebase/app/dist/module/internal'; +import './types/internal'; import type { FirebaseMLTypes } from './types/namespaced'; import { version } from './version'; @@ -32,7 +33,7 @@ const namespace = 'ml'; const nativeModuleName = 'RNFBMLModule'; -class FirebaseMLModule extends FirebaseModule {} +class FirebaseMLModule extends FirebaseModule {} type MLNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< FirebaseMLTypes.Module, diff --git a/packages/ml/lib/types/internal.ts b/packages/ml/lib/types/internal.ts index eff478b8cc..a8e2529eed 100644 --- a/packages/ml/lib/types/internal.ts +++ b/packages/ml/lib/types/internal.ts @@ -16,7 +16,14 @@ */ /** - * Internal bridge types for `@react-native-firebase/ml`. - * Native module contracts are expanded in later migration stages. + * Wrapped native module contract for `RNFBMLModule`. + * The namespaced `FirebaseMLModule` implementation does not call into native from JS; + * this type anchors `FirebaseModule` and documents the bridge key. */ -export {}; +export interface RNFBMLModule {} + +declare module '@react-native-firebase/app/dist/module/internal/NativeModules' { + interface ReactNativeFirebaseNativeModules { + RNFBMLModule: RNFBMLModule; + } +} diff --git a/packages/ml/tsconfig.json b/packages/ml/tsconfig.json index bfa760de4a..995ff9f3f0 100644 --- a/packages/ml/tsconfig.json +++ b/packages/ml/tsconfig.json @@ -5,6 +5,9 @@ "rootDir": ".", "paths": { "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"], + "@react-native-firebase/app/dist/module/internal/NativeModules": [ + "../app/dist/typescript/lib/internal/NativeModules" + ], "@react-native-firebase/app": ["../app/dist/typescript/lib"] } }, From d275a3e7c2a15935345c319353508d8e1db05b97 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 1 May 2026 12:38:16 +0100 Subject: [PATCH 4/8] refactor(ml): align modular API with firebase-js-sdk --- packages/ml/lib/index.ts | 6 +++--- packages/ml/lib/modular.ts | 10 ++++------ packages/ml/lib/types/ml.ts | 12 +++++++++--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/ml/lib/index.ts b/packages/ml/lib/index.ts index ce3149cd21..ed29b146ff 100644 --- a/packages/ml/lib/index.ts +++ b/packages/ml/lib/index.ts @@ -15,11 +15,11 @@ * */ -export type { FirebaseML } from './types/ml'; +export * from './modular'; -export type { FirebaseMLTypes } from './types/namespaced'; +export type { FirebaseApp, FirebaseML } from './types/ml'; -export * from './modular'; +export type { FirebaseMLTypes } from './types/namespaced'; export * from './namespaced'; export { default } from './namespaced'; diff --git a/packages/ml/lib/modular.ts b/packages/ml/lib/modular.ts index 4b49b61283..c43abef6a1 100644 --- a/packages/ml/lib/modular.ts +++ b/packages/ml/lib/modular.ts @@ -16,15 +16,13 @@ */ import { getApp } from '@react-native-firebase/app'; -import type { FirebaseApp } from '@react-native-firebase/app'; -import type { FirebaseML } from './types/ml'; +import type { FirebaseApp, FirebaseML } from './types/ml'; /** - * Returns the existing default {@link FirebaseML} instance that is associated with the - * default {@link @firebase/app!FirebaseApp}. If no instance exists, initializes a new - * instance with default settings. + * Returns the {@link FirebaseML} instance for the default or given {@link FirebaseApp}. * - * @returns The {@link FirebaseML} instance of the provided app. + * @param app - The Firebase `FirebaseApp` to use. When omitted, the default app is used. + * @returns The ML service instance for that app. */ export function getML(app?: FirebaseApp): FirebaseML { if (app) { diff --git a/packages/ml/lib/types/ml.ts b/packages/ml/lib/types/ml.ts index 8f7d0a850b..1963b13d37 100644 --- a/packages/ml/lib/types/ml.ts +++ b/packages/ml/lib/types/ml.ts @@ -15,12 +15,18 @@ * */ -import type { FirebaseApp } from '@react-native-firebase/app'; +import type { ReactNativeFirebase } from '@react-native-firebase/app'; + +export type FirebaseApp = ReactNativeFirebase.FirebaseApp; /** - * Firebase ML module instance for the modular API. + * Firebase ML service instance for the modular API. + * + * Current Firebase JS SDK releases do not ship a `firebase/ml` modular entry point; this interface + * follows the same modular service-instance pattern used elsewhere in React Native Firebase (see e.g. + * the Firestore package's `Firestore` type). */ -export interface FirebaseML { +export interface FirebaseML extends ReactNativeFirebase.FirebaseModule { /** The FirebaseApp this module is associated with */ app: FirebaseApp; } From dbedaee3883d4f3ce3b314367e1bed96e92d31ef Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 1 May 2026 13:14:42 +0100 Subject: [PATCH 5/8] test: update type test --- packages/ml/type-test.ts | 28 +++++++++++++++++++++++++++- tsconfig.json | 2 -- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/ml/type-test.ts b/packages/ml/type-test.ts index 2ea028badb..dd6ff54bea 100644 --- a/packages/ml/type-test.ts +++ b/packages/ml/type-test.ts @@ -1,4 +1,11 @@ -import ml, { firebase, getML } from '.'; +import ml, { + firebase, + getML, + SDK_VERSION, + type FirebaseApp, + type FirebaseML, + type FirebaseMLTypes, +} from '.'; console.log(ml().app); @@ -33,3 +40,22 @@ console.log(modularML1.app.name); const modularML2 = getML(firebase.app()); console.log(modularML2.app.name); + +// modular public types +const modularInstance: FirebaseML = getML(); +const modularWithNamedApp: FirebaseML = getML(firebase.app()); +console.log(modularInstance.app.name); +console.log(modularWithNamedApp.app.name); + +const namedApp: FirebaseApp = firebase.app(); +console.log(getML(namedApp).app.name); + +// named SDK_VERSION export +const sdkVersion: string = SDK_VERSION; +console.log(sdkVersion); + +// deprecated namespace types remain assignable from runtime values +const namespaceModule: FirebaseMLTypes.Module = firebase.ml(); +const namespaceStatics: FirebaseMLTypes.Statics = firebase.ml; +console.log(namespaceModule.app.name); +console.log(namespaceStatics.SDK_VERSION); diff --git a/tsconfig.json b/tsconfig.json index f340a813d9..a0296fb984 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,8 +17,6 @@ "packages/firestore/lib/modular/VectorValue.d.ts", "packages/in-app-messaging/lib/index.d.ts", "packages/in-app-messaging/lib/modular/index.d.ts", - "packages/ml/lib/index.d.ts", - "packages/ml/lib/modular/index.d.ts", "packages/functions/type-test.ts", "packages/app/type-test.ts", "packages/app-check/type-test.ts", From e62ebfc2f7143e9fbd6f7b9474bdf1ba85cce49b Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sat, 6 Jun 2026 11:09:26 -0500 Subject: [PATCH 6/8] build(deps): bump react-native-builder-bob to version on main --- packages/ml/package.json | 2 +- yarn.lock | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ml/package.json b/packages/ml/package.json index 8b9e34c7a6..f7af598454 100644 --- a/packages/ml/package.json +++ b/packages/ml/package.json @@ -34,7 +34,7 @@ "provenance": true }, "devDependencies": { - "react-native-builder-bob": "^0.40.13" + "react-native-builder-bob": "^0.41.0" }, "exports": { ".": { diff --git a/yarn.lock b/yarn.lock index 0e75b531a9..7cb1323f3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6145,6 +6145,8 @@ __metadata: "@react-native-firebase/ml@npm:24.1.0, @react-native-firebase/ml@workspace:packages/ml": version: 0.0.0-use.local resolution: "@react-native-firebase/ml@workspace:packages/ml" + dependencies: + react-native-builder-bob: "npm:^0.41.0" peerDependencies: "@react-native-firebase/app": 24.1.0 languageName: unknown From 2f3e2e6d687a43d1f2c88b5c9041a5dd7ebd11b4 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sat, 6 Jun 2026 11:09:47 -0500 Subject: [PATCH 7/8] build: forward-port to typescript v6+ as on main --- packages/ml/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ml/tsconfig.json b/packages/ml/tsconfig.json index 995ff9f3f0..27b4050934 100644 --- a/packages/ml/tsconfig.json +++ b/packages/ml/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.packages.base.json", "compilerOptions": { - "baseUrl": ".", "rootDir": ".", "paths": { "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"], From 060d32691b5f4b29cad0deaeadbaa8267ef776e6 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sat, 6 Jun 2026 21:02:36 -0500 Subject: [PATCH 8/8] docs(ml): update reference docs entrypoint --- packages/ml/typedoc.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/ml/typedoc.json b/packages/ml/typedoc.json index ac150fc6a6..2568573821 100644 --- a/packages/ml/typedoc.json +++ b/packages/ml/typedoc.json @@ -1,6 +1,4 @@ { "$schema": "https://typedoc.org/schema.json", - "entryPoints": ["lib/index.d.ts"], - "intentionallyNotExported": ["MLNamespace"] - + "entryPoints": ["lib/modular.ts", "lib/types/ml.ts"] }