Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions .eslintrc.js

This file was deleted.

3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"prettier.tabWidth": 2
}
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# rxfire

## 7.0.0

### Changes

- Updated the peer dependencies to support Firebase v12 due to the renaming of
`firebase/vertexai` to `firebase/ai`. This is important to provide compatible
support at other packages like `@angular/fire` in its version 20.

### Misc Changes

- Updated the ESLint to version 9 and migrated to Flat config.
- Updated several packages used for building (rollup plugins) but one of them (`@rollup/plugin-typescript`) has issues resolving the output declaration files in version 12.x.x, whereas the v11 works!


## 4.0.0
### Patch Changes

Expand Down
39 changes: 39 additions & 0 deletions ai/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @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 {
startAudioConversation as vanillaStartAudioConversation,
type AudioConversationController,
type LiveSession,
type StartAudioConversationOptions,
} from 'firebase/ai';
import { Observable, from } from 'rxjs';

/**
* Create an observable of the original `startAudioConversation` promise just in
* case it breaks again due to imports.
*
* @param liveSession
* @param options
* @returns
*/
export function startAudioConversation(
liveSession: LiveSession,
options?: StartAudioConversationOptions
): Observable<AudioConversationController> {
return from(vanillaStartAudioConversation(liveSession, options));
}
8 changes: 8 additions & 0 deletions ai/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "rxfire/ai",
"browser": "../dist/ai/index.esm.js",
"main": "../dist/ai/index.cjs.js",
"module": "../dist/ai/index.esm.js",
"typings": "../dist/ai/index.d.ts",
"sideEffects": false
}
40 changes: 22 additions & 18 deletions auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
*/

// auth is used as a namespace to access types
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import {Auth} from 'firebase/auth';
import {onAuthStateChanged, onIdTokenChanged, getIdToken} from 'firebase/auth';
import {Observable, from, of} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import { Auth } from 'firebase/auth';
import {
onAuthStateChanged,
onIdTokenChanged,
getIdToken,
} from 'firebase/auth';
import { Observable, from, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

type User = import('firebase/auth').User;

Expand All @@ -29,15 +32,15 @@ type User = import('firebase/auth').User;
* triggered on sign-in or sign-out.
* @param auth firebase.auth.Auth
*/
export function authState(auth: Auth): Observable<User|null> {
export function authState(auth: Auth): Observable<User | null> {
return new Observable((subscriber) => {
const unsubscribe = onAuthStateChanged(
auth,
subscriber.next.bind(subscriber),
subscriber.error.bind(subscriber),
subscriber.complete.bind(subscriber),
auth,
subscriber.next.bind(subscriber),
subscriber.error.bind(subscriber),
subscriber.complete.bind(subscriber)
);
return {unsubscribe};
return { unsubscribe };
});
}

Expand All @@ -46,14 +49,15 @@ export function authState(auth: Auth): Observable<User|null> {
* sign-out, and token refresh events
* @param auth firebase.auth.Auth
*/
export function user(auth: Auth): Observable<User|null> {
export function user(auth: Auth): Observable<User | null> {
return new Observable((subscriber) => {
const unsubscribe = onIdTokenChanged(auth,
subscriber.next.bind(subscriber),
subscriber.error.bind(subscriber),
subscriber.complete.bind(subscriber),
const unsubscribe = onIdTokenChanged(
auth,
subscriber.next.bind(subscriber),
subscriber.error.bind(subscriber),
subscriber.complete.bind(subscriber)
);
return {unsubscribe};
return { unsubscribe };
});
}

Expand All @@ -64,6 +68,6 @@ export function user(auth: Auth): Observable<User|null> {
*/
export function idToken(auth: Auth): Observable<string | null> {
return user(auth).pipe(
switchMap((user) => (user ? from(getIdToken(user)) : of(null))),
switchMap((user) => (user ? from(getIdToken(user)) : of(null)))
);
}
16 changes: 8 additions & 8 deletions database/object/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
* limitations under the License.
*/

import {QueryChange, ListenEvent, Query} from '../interfaces';
import {fromRef} from '../fromRef';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import { QueryChange, ListenEvent, Query } from '../interfaces';
import { fromRef } from '../fromRef';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

/**
* Get the snapshot changes of an object
Expand All @@ -33,13 +33,13 @@ export function object(query: Query): Observable<QueryChange> {
* @param query object ref or query
* @param keyField map the object key to a specific field
*/
export function objectVal<T>(query: Query, options: { keyField?: string }={}): Observable<T> {
export function objectVal<T>(query: Query, options: { keyField?: string } = {}): Observable<T> {
return fromRef(query, ListenEvent.value).pipe(
map((change) => changeToData(change, options) as T),
map((change) => changeToData(change, options) as T),
);
}

export function changeToData(change: QueryChange, options: { keyField?: string}={}): {} {
export function changeToData(change: QueryChange, options: { keyField?: string } = {}): object {
const val = change.snapshot.val();

// match the behavior of the JS SDK when the snapshot doesn't exist
Expand All @@ -54,6 +54,6 @@ export function changeToData(change: QueryChange, options: { keyField?: string}=

return {
...val,
...(options.keyField ? {[options.keyField]: change.snapshot.key} : null),
...(options.keyField ? { [options.keyField]: change.snapshot.key } : null),
};
}
2 changes: 2 additions & 0 deletions docs/ai.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RxFire AI

44 changes: 44 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// @ts-check

/** Check out https://typescript-eslint.io/getting-started/ */

import js from '@eslint/js';
import { defineConfig } from 'eslint/config';
import globals from 'globals';
import tseslint from 'typescript-eslint';

export default [
...defineConfig([
{
name: 'ESLint JS - Recommended',
...js.configs.recommended
},
tseslint.configs.recommended,
{
name: 'typescript-eslint - config parser',
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
parser: tseslint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
ecmaVersion: 12,
sourceType: 'module',
},
},
},
]),
{
name: 'Ignore folder and files',
ignores: ['**/dist', '**/eslint.config.mjs'],
},
{
name: 'typescript-eslint plugin - Custom rules',
rules: {
'@typescript-eslint/no-deprecated': 'error',
},
},
];
Loading