diff --git a/.gitignore b/.gitignore index ee1f43847..daecd1092 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,4 @@ publish.sh # auto-gen files src/compat/**/base.ts -src/**/rxfire.ts \ No newline at end of file +src/**/rxfire.ts diff --git a/package.json b/package.json index cf8758e7e..4fc14574e 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "inquirer-autocomplete-prompt": "^1.0.1", "lodash.isequal": "^4.5.0", "open": "^7.0.3", - "rxfire": "6.0.0-canary.cee1afe", + "rxfire": "6.0.0-canary.92c6c26", "rxjs": "~6.6.0", "semver": "^7.1.3", "tslib": "^2.1.0", diff --git a/sample/package.json b/sample/package.json index aeb95d1f0..6045dc00f 100644 --- a/sample/package.json +++ b/sample/package.json @@ -24,7 +24,7 @@ "@angular/router": "^12.0.0", "firebase": "9.0.0-beta.7", "lodash.isequal": "^4.5.0", - "rxfire": "6.0.0-canary.cee1afe", + "rxfire": "6.0.0-canary.92c6c26", "rxjs": "~6.6.0", "tslib": "^2.1.0", "zone.js": "~0.11.4" diff --git a/sample/src/app/app.component.ts b/sample/src/app/app.component.ts index 0ea4b917d..bd0661e52 100644 --- a/sample/src/app/app.component.ts +++ b/sample/src/app/app.component.ts @@ -1,7 +1,8 @@ import { ApplicationRef, Component, NgZone, Optional } from '@angular/core'; import { FirebaseApp, FirebaseApps } from '@angular/fire/app'; import { Auth, AuthInstances, authState } from '@angular/fire/auth'; -import { Firestore, FirestoreInstances, firestoreInstance$ } from '@angular/fire/firestore'; +import { Firestore, FirestoreInstances } from '@angular/fire/firestore/lite'; +import { firestoreInstance$ } from '@angular/fire/firestore'; import { debounceTime } from 'rxjs/operators'; import { initializeFirestore$ } from './firestore'; @@ -39,8 +40,8 @@ export class AppComponent { public auth: Auth, // default Firbase Auth public apps: FirebaseApps, // all initialized App instances public authInstances: AuthInstances, // all initialized Auth instances - @Optional() public firestore: Firestore, - @Optional() public firestoreInstances: FirestoreInstances, + public firestore: Firestore, + public firestoreInstances: FirestoreInstances, appRef: ApplicationRef, zone: NgZone, ) { @@ -49,7 +50,7 @@ export class AppComponent { // onAuthStateChanged(auth, it => console.log('onAuthStateChanged', it)); authState(auth).subscribe(it => console.log('authState', it)); appRef.isStable.pipe(debounceTime(200)).subscribe(it => console.log('isStable', it)); - console.log((app as any).container.providers.keys()); + console.log((app as any).container.providers); firestoreInstance$.subscribe(it => console.log('$', it)); initializeFirestore$.subscribe(it => console.log('init', it)); } diff --git a/sample/src/app/app.module.ts b/sample/src/app/app.module.ts index 9fea5499f..88945a59a 100644 --- a/sample/src/app/app.module.ts +++ b/sample/src/app/app.module.ts @@ -7,6 +7,8 @@ import { initializeAuth } from 'firebase/auth'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { environment } from '../environments/environment'; +import { provideFirestore } from '@angular/fire/firestore/lite'; +import { getFirestore } from 'firebase/firestore/lite'; @NgModule({ declarations: [ @@ -22,6 +24,7 @@ import { environment } from '../environments/environment'; return app; }), provideAuth(() => initializeAuth(getApp())), + provideFirestore(() => getFirestore()), ], providers: [ ], bootstrap: [AppComponent] diff --git a/sample/yarn.lock b/sample/yarn.lock index 1d632651c..a7a451379 100644 --- a/sample/yarn.lock +++ b/sample/yarn.lock @@ -9162,10 +9162,10 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxfire@6.0.0-canary.cee1afe: - version "6.0.0-canary.cee1afe" - resolved "https://registry.yarnpkg.com/rxfire/-/rxfire-6.0.0-canary.cee1afe.tgz#212318f2ccc034c25581f079c51f0d952164b4db" - integrity sha512-PySJryeUfnuMuYlC8U+X83PIe53G1s+OpQuzjjaMUQ3gc1z6aD4ZEWc/O3LzVQ3ywwO/X4AAO9hv4F0Q3+y79A== +rxfire@6.0.0-canary.92c6c26: + version "6.0.0-canary.92c6c26" + resolved "https://registry.yarnpkg.com/rxfire/-/rxfire-6.0.0-canary.92c6c26.tgz#de888ac0ec975eb7860b4cee54aa15df90b9fec0" + integrity sha512-zqZZFTCFXqGNRIN/zciPVzylSw3drlkM3mojTZj4GALeUBtMI59/hmAEevbAxBQjNk4eiWj/4vFsPFJtzgT5qA== dependencies: tslib "^1.9.0 || ~2.1.0" diff --git a/src/firestore/lite/lite.module.ts b/src/firestore/lite/lite.module.ts new file mode 100644 index 000000000..1f4b9a26e --- /dev/null +++ b/src/firestore/lite/lite.module.ts @@ -0,0 +1,63 @@ +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { FirebaseFirestore } from 'firebase/firestore/lite'; +import { AuthInstances } from '@angular/fire/auth'; +import { ɵmemoizeInstance, ɵgetDefaultInstanceOf, ɵAngularFireSchedulers } from '@angular/fire'; +import { Firestore, FirestoreInstances, FIRESTORE_PROVIDER_NAME } from './lite'; +import { FirebaseApps } from '@angular/fire/app'; + +export const PROVIDED_FIRESTORE_INSTANCES = new InjectionToken('angularfire2.firestore-lite-instances'); + +export function defaultFirestoreInstanceFactory(_: Firestore[]) { + const defaultFirestore = ɵgetDefaultInstanceOf(FIRESTORE_PROVIDER_NAME); + return new Firestore(defaultFirestore); +} + +export function firestoreInstanceFactory(fn: () => FirebaseFirestore) { + return (zone: NgZone) => { + const firestore = ɵmemoizeInstance(fn, zone); + return new Firestore(firestore); + }; +} + +const FIRESTORE_INSTANCES_PROVIDER = { + provide: FirestoreInstances, + deps: [ + [new Optional(), PROVIDED_FIRESTORE_INSTANCES ], + ] +}; + +const DEFAULT_FIRESTORE_INSTANCE_PROVIDER = { + provide: Firestore, + useFactory: defaultFirestoreInstanceFactory, + deps: [ + NgZone, + [new Optional(), PROVIDED_FIRESTORE_INSTANCES ], + ] +}; + +@NgModule({ + providers: [ + DEFAULT_FIRESTORE_INSTANCE_PROVIDER, + FIRESTORE_INSTANCES_PROVIDER, + ] +}) +export class FirestoreModule { +} + +export function provideFirestore(fn: () => FirebaseFirestore): ModuleWithProviders { + return { + ngModule: FirestoreModule, + providers: [{ + provide: PROVIDED_FIRESTORE_INSTANCES, + useFactory: firestoreInstanceFactory(fn), + multi: true, + deps: [ + NgZone, + ɵAngularFireSchedulers, + FirebaseApps, + // Firestore+Auth work better if Auth is loaded first + [new Optional(), AuthInstances ], + ] + }] + }; +} diff --git a/src/firestore/lite/lite.ts b/src/firestore/lite/lite.ts new file mode 100644 index 000000000..fbe529cb1 --- /dev/null +++ b/src/firestore/lite/lite.ts @@ -0,0 +1,30 @@ +import { FirebaseFirestore } from 'firebase/firestore/lite'; +import { ɵgetAllInstancesOf } from '@angular/fire'; +import { from, timer } from 'rxjs'; +import { concatMap, distinct } from 'rxjs/operators'; + +// see notes in core/firebase.app.module.ts for why we're building the class like this +// tslint:disable-next-line:no-empty-interface +export interface Firestore extends FirebaseFirestore {} + +export class Firestore { + constructor(firestore: FirebaseFirestore) { + return firestore; + } +} + +export const FIRESTORE_PROVIDER_NAME = 'firestore/lite'; + +// tslint:disable-next-line:no-empty-interface +export interface FirestoreInstances extends Array {} + +export class FirestoreInstances { + constructor() { + return ɵgetAllInstancesOf(FIRESTORE_PROVIDER_NAME); + } +} + +export const firestoreInstance$ = timer(0, 300).pipe( + concatMap(() => from(ɵgetAllInstancesOf(FIRESTORE_PROVIDER_NAME))), + distinct(), +); diff --git a/src/firestore/lite/package.json b/src/firestore/lite/package.json new file mode 100644 index 000000000..e13e605d7 --- /dev/null +++ b/src/firestore/lite/package.json @@ -0,0 +1,11 @@ +{ + "$schema": "../../../node_modules/ng-packagr/package.schema.json", + "ngPackage": { + "lib": { + "umdModuleIds": { + "rxfire/firestore-lite": "rxfire-firestore-lite" + }, + "entryFile": "public_api.ts" + } + } +} \ No newline at end of file diff --git a/src/firestore/lite/public_api.ts b/src/firestore/lite/public_api.ts new file mode 100644 index 000000000..ad23523fd --- /dev/null +++ b/src/firestore/lite/public_api.ts @@ -0,0 +1,3 @@ +export { Firestore, FirestoreInstances, firestoreInstance$ } from './lite'; +export { FirestoreModule, provideFirestore } from './lite.module'; +export * from './rxfire'; diff --git a/tools/build.ts b/tools/build.ts index be48f9b1c..91ea82332 100644 --- a/tools/build.ts +++ b/tools/build.ts @@ -6,16 +6,13 @@ import { dirname, join } from 'path'; import { keys as tsKeys } from 'ts-transformer-keys'; import firebase from 'firebase/compat/app'; -const yada = tsKeys(); -const yada2 = tsKeys(); - // TODO infer these from the package.json const MODULES = [ 'core', 'app', 'compat', 'analytics', 'auth', 'database', 'firestore', 'functions', 'remote-config', 'storage', 'messaging', 'performance', 'compat/analytics', 'compat/auth-guard', 'compat/auth', 'compat/database', 'compat/firestore', 'compat/functions', 'compat/remote-config', 'compat/storage', 'compat/messaging', - 'compat/performance' + 'compat/performance', 'firestore/lite', ]; const LAZY_MODULES = ['compat/analytics', 'compat/auth', 'compat/functions', 'compat/messaging', 'compat/remote-config']; const UMD_NAMES = MODULES.map(m => m === 'core' ? 'angular-fire' : `angular-fire-${m.replace('/', '-')}`); @@ -45,6 +42,7 @@ export function ${exportName}(..._: Parameters) { reexport('remote-config', 'rxfire', 'rxfire/remote-config', tsKeys()), reexport('storage', 'rxfire', 'rxfire/storage', tsKeys()), reexport('performance', 'rxfire', 'rxfire/performance', tsKeys()), + reexport('firestore/lite', 'rxfire', 'rxfire/firestore/lite', tsKeys()), ]); } diff --git a/yarn.lock b/yarn.lock index eebbd276e..aa1f2cb1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11678,10 +11678,10 @@ rx@2.3.24: resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" integrity sha1-FPlQpCF9fjXapxu8vljv9o6ksrc= -rxfire@6.0.0-canary.cee1afe: - version "6.0.0-canary.cee1afe" - resolved "https://registry.yarnpkg.com/rxfire/-/rxfire-6.0.0-canary.cee1afe.tgz#212318f2ccc034c25581f079c51f0d952164b4db" - integrity sha512-PySJryeUfnuMuYlC8U+X83PIe53G1s+OpQuzjjaMUQ3gc1z6aD4ZEWc/O3LzVQ3ywwO/X4AAO9hv4F0Q3+y79A== +rxfire@6.0.0-canary.92c6c26: + version "6.0.0-canary.92c6c26" + resolved "https://registry.yarnpkg.com/rxfire/-/rxfire-6.0.0-canary.92c6c26.tgz#de888ac0ec975eb7860b4cee54aa15df90b9fec0" + integrity sha512-zqZZFTCFXqGNRIN/zciPVzylSw3drlkM3mojTZj4GALeUBtMI59/hmAEevbAxBQjNk4eiWj/4vFsPFJtzgT5qA== dependencies: tslib "^1.9.0 || ~2.1.0"