reactfire 4.2.3-exp.9754f86 → 4.2.3-exp.a1d5930

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk.d.ts CHANGED
@@ -20,34 +20,34 @@ export declare const FunctionsSdkContext: React.Context<Functions | undefined>;
20
20
  export declare const StorageSdkContext: React.Context<FirebaseStorage | undefined>;
21
21
  export declare const PerformanceSdkContext: React.Context<FirebasePerformance | undefined>;
22
22
  export declare const RemoteConfigSdkContext: React.Context<RemoteConfig | undefined>;
23
- declare type FirebaseSdks = Analytics | AppCheck | Auth | Database | Firestore | FirebasePerformance | FirebaseStorage | Functions | RemoteConfig;
23
+ type FirebaseSdks = Analytics | AppCheck | Auth | Database | Firestore | FirebasePerformance | FirebaseStorage | Functions | RemoteConfig;
24
24
  export declare const AppCheckProvider: (props: React.PropsWithChildren<{
25
25
  sdk: AppCheck;
26
- }>) => JSX.Element;
26
+ }>) => React.JSX.Element;
27
27
  export declare const AuthProvider: (props: React.PropsWithChildren<{
28
28
  sdk: Auth;
29
- }>) => JSX.Element;
29
+ }>) => React.JSX.Element;
30
30
  export declare const AnalyticsProvider: (props: React.PropsWithChildren<{
31
31
  sdk: Analytics;
32
- }>) => JSX.Element;
32
+ }>) => React.JSX.Element;
33
33
  export declare const DatabaseProvider: (props: React.PropsWithChildren<{
34
34
  sdk: Database;
35
- }>) => JSX.Element;
35
+ }>) => React.JSX.Element;
36
36
  export declare const FirestoreProvider: (props: React.PropsWithChildren<{
37
37
  sdk: Firestore;
38
- }>) => JSX.Element;
38
+ }>) => React.JSX.Element;
39
39
  export declare const FunctionsProvider: (props: React.PropsWithChildren<{
40
40
  sdk: Functions;
41
- }>) => JSX.Element;
41
+ }>) => React.JSX.Element;
42
42
  export declare const PerformanceProvider: (props: React.PropsWithChildren<{
43
43
  sdk: FirebasePerformance;
44
- }>) => JSX.Element;
44
+ }>) => React.JSX.Element;
45
45
  export declare const StorageProvider: (props: React.PropsWithChildren<{
46
46
  sdk: FirebaseStorage;
47
- }>) => JSX.Element;
47
+ }>) => React.JSX.Element;
48
48
  export declare const RemoteConfigProvider: (props: React.PropsWithChildren<{
49
49
  sdk: RemoteConfig;
50
- }>) => JSX.Element;
50
+ }>) => React.JSX.Element;
51
51
  export declare const useAppCheck: () => AppCheck;
52
52
  export declare const useAuth: () => Auth;
53
53
  export declare const useAnalytics: () => Analytics;
@@ -57,7 +57,7 @@ export declare const useFunctions: () => Functions;
57
57
  export declare const usePerformance: () => FirebasePerformance;
58
58
  export declare const useStorage: () => FirebaseStorage;
59
59
  export declare const useRemoteConfig: () => RemoteConfig;
60
- declare type InitSdkHook<Sdk extends FirebaseSdks> = (initializer: (firebaseApp: FirebaseApp) => Promise<Sdk>, options?: ReactFireOptions<Sdk>) => ObservableStatus<Sdk>;
60
+ type InitSdkHook<Sdk extends FirebaseSdks> = (initializer: (firebaseApp: FirebaseApp) => Promise<Sdk>, options?: ReactFireOptions<Sdk>) => ObservableStatus<Sdk>;
61
61
  export declare const useInitAppCheck: InitSdkHook<AppCheck>;
62
62
  export declare const useInitAuth: InitSdkHook<Auth>;
63
63
  export declare const useInitAnalytics: InitSdkHook<Analytics>;
package/dist/storage.d.ts CHANGED
@@ -16,11 +16,11 @@ export declare function useStorageTask<T = unknown>(task: UploadTask, ref: Stora
16
16
  * @param options
17
17
  */
18
18
  export declare function useStorageDownloadURL<T = string>(ref: StorageReference, options?: ReactFireOptions<T>): ObservableStatus<string | T>;
19
- declare type StorageImageProps = {
19
+ type StorageImageProps = {
20
20
  storagePath: string;
21
21
  storage?: FirebaseStorage;
22
22
  suspense?: boolean;
23
23
  placeHolder?: JSX.Element;
24
24
  };
25
- export declare function StorageImage(props: StorageImageProps & React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>): JSX.Element;
25
+ export declare function StorageImage(props: StorageImageProps & React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>): React.JSX.Element;
26
26
  export {};
@@ -1,7 +1,7 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { SuspenseSubject } from './SuspenseSubject';
3
3
  import { ReactFireOptions } from './';
4
- export declare function preloadObservable<T>(source: Observable<T>, id: string): SuspenseSubject<T>;
4
+ export declare function preloadObservable<T>(source: Observable<T>, id: string, suspenseEnabled?: boolean): SuspenseSubject<T>;
5
5
  export interface ObservableStatus<T> {
6
6
  /**
7
7
  * The loading status.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.2.3-exp.9754f86",
2
+ "version": "4.2.3-exp.a1d5930",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
5
  "main": "dist/index.umd.cjs",
@@ -36,7 +36,7 @@
36
36
  "docs:fork": "typedoc --options typedoc.json --gitRemote upstream && markdown-toc -i docs/use.md"
37
37
  },
38
38
  "peerDependencies": {
39
- "firebase": "^9.0.0",
39
+ "firebase": "^9.0.0 || next",
40
40
  "react": ">=16 || experimental"
41
41
  },
42
42
  "husky": {
@@ -71,40 +71,39 @@
71
71
  }
72
72
  ],
73
73
  "devDependencies": {
74
- "@rollup/plugin-typescript": "^8.3.4",
75
- "@size-limit/preset-small-lib": "^7.0.8",
76
- "@testing-library/jest-dom": "^5.16.4",
77
- "@testing-library/react": "^12.1.5",
78
- "@testing-library/react-hooks": "^8.0.1",
79
- "@types/react": "^17.0.2",
80
- "@types/react-dom": "^17.0.2",
81
- "@typescript-eslint/eslint-plugin": "^5.32.0",
82
- "@typescript-eslint/parser": "^5.32.0",
83
- "@vitejs/plugin-react": "^2.0.0",
84
- "@vitest/ui": "^0.20.3",
85
- "cross-fetch": "^3.1.5",
86
- "eslint": "^8.20.0",
87
- "eslint-plugin-no-only-tests": "^2.6.0",
88
- "eslint-plugin-react": "^7.30.1",
74
+ "@rollup/plugin-typescript": "^11.1.1",
75
+ "@size-limit/preset-small-lib": "^8.2.6",
76
+ "@testing-library/jest-dom": "^5.16.5",
77
+ "@testing-library/react": "^14.0.0",
78
+ "@types/react": "^18.2.0",
79
+ "@types/react-dom": "^18.2.0",
80
+ "@typescript-eslint/eslint-plugin": "^5.60.1",
81
+ "@typescript-eslint/parser": "^5.60.1",
82
+ "@vitejs/plugin-react": "^4.0.1",
83
+ "@vitest/ui": "^0.32.2",
84
+ "cross-fetch": "^3.1.6",
85
+ "eslint": "^8.43.0",
86
+ "eslint-plugin-no-only-tests": "^3.1.0",
87
+ "eslint-plugin-react": "^7.32.2",
89
88
  "eslint-plugin-react-hooks": "^4.6.0",
90
89
  "firebase": "^9.9.0",
91
- "firebase-tools": "^11.3.0",
90
+ "firebase-tools": "^12.4.0",
92
91
  "globalthis": "^1.0.3",
93
- "husky": "^8.0.1",
94
- "jest-environment-jsdom": "^28.1.3",
95
- "jsdom": "^20.0.0",
92
+ "husky": "^8.0.3",
93
+ "jest-environment-jsdom": "^29.5.0",
94
+ "jsdom": "^22.1.0",
96
95
  "markdown-toc": "^1.2.0",
97
- "prettier": "^2.7.1",
98
- "react": "^17.0.2",
99
- "react-dom": "^17.0.2",
100
- "react-test-renderer": "^17.0.2",
101
- "rollup-plugin-visualizer": "^5.7.1",
102
- "size-limit": "^7.0.8",
103
- "typedoc": "^0.23.8",
104
- "typedoc-plugin-markdown": "^3.13.3",
105
- "typescript": "^4.7.4",
106
- "vite": "^3.0.2",
107
- "vitest": "^0.18.1"
96
+ "prettier": "^2.8.8",
97
+ "react": "^18.2.0",
98
+ "react-dom": "^18.2.0",
99
+ "react-test-renderer": "^18.2.0",
100
+ "rollup-plugin-visualizer": "^5.9.2",
101
+ "size-limit": "^8.2.6",
102
+ "typedoc": "^0.24.8",
103
+ "typedoc-plugin-markdown": "^3.15.3",
104
+ "typescript": "^5.1.3",
105
+ "vite": "^4.3.9",
106
+ "vitest": "^0.32.2"
108
107
  },
109
108
  "dependencies": {
110
109
  "rxfire": "^6.0.3",
@@ -15,7 +15,7 @@ export class SuspenseSubject<T> extends Subject<T> {
15
15
  // @ts-expect-error: TODO: double check to see if this is an RXJS thing or if we should listen to TS
16
16
  private _resolveFirstEmission: () => void;
17
17
 
18
- constructor(innerObservable: Observable<T>, private _timeoutWindow: number) {
18
+ constructor(innerObservable: Observable<T>, private _timeoutWindow: number, private _suspenseEnabled: boolean) {
19
19
  super();
20
20
  this._firstEmission = new Promise<void>((resolve) => (this._resolveFirstEmission = resolve));
21
21
  this._innerObservable = innerObservable.pipe(
@@ -38,7 +38,12 @@ export class SuspenseSubject<T> extends Subject<T> {
38
38
 
39
39
  // set a timeout for resetting the cache, subscriptions will cancel the timeout
40
40
  // and reschedule again on unsubscribe
41
- this._timeoutHandler = setTimeout(this._reset.bind(this), this._timeoutWindow);
41
+ if (this._suspenseEnabled) {
42
+ // Noop if suspense is enabled
43
+ this._timeoutHandler = setTimeout(() => {}, this._timeoutWindow);
44
+ } else {
45
+ this._timeoutHandler = setTimeout(this._reset.bind(this), this._timeoutWindow);
46
+ }
42
47
  }
43
48
 
44
49
  get hasValue(): boolean {
package/src/auth.tsx CHANGED
@@ -28,7 +28,7 @@ export function useUser<T = unknown>(options?: ReactFireOptions<T>): ObservableS
28
28
  return useObservable(observableId, observable$, options);
29
29
  }
30
30
 
31
- export function useIdTokenResult(user: User, forceRefresh: boolean = false, options?: ReactFireOptions<IdTokenResult>): ObservableStatus<IdTokenResult> {
31
+ export function useIdTokenResult(user: User, forceRefresh = false, options?: ReactFireOptions<IdTokenResult>): ObservableStatus<IdTokenResult> {
32
32
  if (!user) {
33
33
  throw new Error('you must provide a user');
34
34
  }
@@ -173,7 +173,7 @@ export function useSigninCheck(
173
173
  })
174
174
  );
175
175
 
176
- return useObservable(observableId, observable);
176
+ return useObservable(observableId, observable, options);
177
177
  }
178
178
 
179
179
  function getClaimsObjectValidator(requiredClaims: Claims): ClaimsValidator {
@@ -65,7 +65,7 @@ export function useIsSuspenseEnabled(): boolean {
65
65
  }
66
66
 
67
67
  export function useSuspenseEnabledFromConfigAndContext(suspenseFromConfig?: boolean): boolean {
68
- let suspenseFromContext = React.useContext(SuspenseEnabledContext);
68
+ const suspenseFromContext = React.useContext(SuspenseEnabledContext);
69
69
 
70
70
  // prioritize config over context
71
71
  if (suspenseFromConfig !== undefined) {
package/src/firestore.tsx CHANGED
@@ -6,13 +6,13 @@ import { first } from 'rxjs/operators';
6
6
  import { Query as FirestoreQuery, QuerySnapshot, DocumentReference, queryEqual, DocumentData, DocumentSnapshot } from 'firebase/firestore';
7
7
 
8
8
  // Since we're side-effect free, we need to ensure our observableId cache is global
9
- const cachedQueries: Array<FirestoreQuery> = (globalThis as any as ReactFireGlobals)._reactFireFirestoreQueryCache || [];
9
+ const cachedQueries: Array<FirestoreQuery<any>> = (globalThis as any as ReactFireGlobals)._reactFireFirestoreQueryCache || [];
10
10
 
11
11
  if (!(globalThis as any as ReactFireGlobals)._reactFireFirestoreQueryCache) {
12
12
  (globalThis as any as ReactFireGlobals)._reactFireFirestoreQueryCache = cachedQueries;
13
13
  }
14
14
 
15
- function getUniqueIdForFirestoreQuery(query: FirestoreQuery) {
15
+ function getUniqueIdForFirestoreQuery<T = DocumentData>(query: FirestoreQuery<T>) {
16
16
  const index = cachedQueries.findIndex((cachedQuery) => queryEqual(cachedQuery, query));
17
17
  if (index > -1) {
18
18
  return index;
@@ -30,12 +30,12 @@ export async function preloadFirestoreDoc(refProvider: () => Promise<DocumentRef
30
30
  return preloadObservable(doc(ref), getDocObservableId(ref));
31
31
  }
32
32
 
33
- function getDocObservableId(ref: DocumentReference) {
33
+ function getDocObservableId<T = DocumentData>(ref: DocumentReference<T>) {
34
34
  return `firestore:doc:${ref.firestore.app.name}:${ref.path}`;
35
35
  }
36
36
 
37
37
  /**
38
- * Suscribe to Firestore Document changes
38
+ * Subscribe to Firestore Document changes
39
39
  *
40
40
  * You can preload data for this hook by calling `preloadFirestoreDoc`
41
41
  */
@@ -57,7 +57,7 @@ export function useFirestoreDocOnce<T = DocumentData>(ref: DocumentReference<T>,
57
57
  }
58
58
 
59
59
  /**
60
- * Suscribe to Firestore Document changes and unwrap the document into a plain object
60
+ * Subscribe to Firestore Document changes and unwrap the document into a plain object
61
61
  */
62
62
  export function useFirestoreDocData<T = unknown>(ref: DocumentReference<T>, options?: ReactFireOptions<T>): ObservableStatus<T> {
63
63
  const idField = options ? checkIdField(options) : 'NO_ID_FIELD';
package/src/storage.tsx CHANGED
@@ -49,7 +49,7 @@ function StorageFromContext(props: StorageImageProps & React.DetailedHTMLProps<R
49
49
  }
50
50
 
51
51
  function INTERNALStorageImage(props: StorageImageProps & React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>): JSX.Element {
52
- let { storage, storagePath, suspense, placeHolder, ...imgProps } = props;
52
+ const { storage, storagePath, suspense, placeHolder, ...imgProps } = props;
53
53
 
54
54
  const reactfireOptions: ReactFireOptions<string> = {
55
55
  suspense: useSuspenseEnabledFromConfigAndContext(suspense),
@@ -76,7 +76,7 @@ function INTERNALStorageImage(props: StorageImageProps & React.DetailedHTMLProps
76
76
  }
77
77
 
78
78
  export function StorageImage(props: StorageImageProps & React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>) {
79
- let { storage } = props;
79
+ const { storage } = props;
80
80
 
81
81
  if (storage) {
82
82
  return <INTERNALStorageImage {...props} />;
@@ -16,11 +16,11 @@ if (!(globalThis as any as ReactFireGlobals)._reactFirePreloadedObservables) {
16
16
  // Starts listening to an Observable.
17
17
  // Call this once you know you're going to render a
18
18
  // child that will consume the observable
19
- export function preloadObservable<T>(source: Observable<T>, id: string) {
19
+ export function preloadObservable<T>(source: Observable<T>, id: string, suspenseEnabled = false) {
20
20
  if (preloadedObservables.has(id)) {
21
21
  return preloadedObservables.get(id) as SuspenseSubject<T>;
22
22
  } else {
23
- const observable = new SuspenseSubject(source, DEFAULT_TIMEOUT);
23
+ const observable = new SuspenseSubject(source, DEFAULT_TIMEOUT, suspenseEnabled);
24
24
  preloadedObservables.set(id, observable);
25
25
  return observable;
26
26
  }
@@ -97,12 +97,13 @@ export function useObservable<T = unknown>(observableId: string, source: Observa
97
97
  if (!observableId) {
98
98
  throw new Error('cannot call useObservable without an observableId');
99
99
  }
100
- const observable = preloadObservable(source, observableId);
100
+ const suspenseEnabled = useSuspenseEnabledFromConfigAndContext(config.suspense);
101
+
102
+ const observable = preloadObservable(source, observableId, suspenseEnabled);
101
103
 
102
104
  // Suspend if suspense is enabled and no initial data exists
103
105
  const hasInitialData = config.hasOwnProperty('initialData') || config.hasOwnProperty('startWithValue');
104
106
  const hasData = observable.hasValue || hasInitialData;
105
- const suspenseEnabled = useSuspenseEnabledFromConfigAndContext(config.suspense);
106
107
  if (suspenseEnabled === true && !hasData) {
107
108
  throw observable.firstEmission;
108
109
  }