reactfire 4.0.0 → 4.0.1-exp.f6d2351
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/README.md +12 -3
- package/dist/SuspenseSubject.d.ts +21 -21
- package/dist/auth.d.ts +104 -104
- package/dist/database.d.ts +23 -23
- package/dist/firebaseApp.d.ts +14 -14
- package/dist/firestore.d.ts +35 -35
- package/dist/functions.d.ts +12 -0
- package/dist/index.d.ts +36 -35
- package/dist/index.js +2337 -5
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +122 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/performance.d.ts +7 -7
- package/dist/{remote-config/index.d.ts → remote-config.d.ts} +30 -35
- package/dist/sdk.d.ts +70 -43
- package/dist/storage.d.ts +26 -26
- package/dist/useObservable.d.ts +41 -41
- package/package.json +56 -54
- package/src/SuspenseSubject.ts +6 -4
- package/src/auth.tsx +6 -6
- package/src/firebaseApp.tsx +2 -2
- package/src/functions.tsx +26 -0
- package/src/index.ts +1 -0
- package/src/{remote-config/index.tsx → remote-config.tsx} +4 -16
- package/src/sdk.tsx +26 -27
- package/src/storage.tsx +2 -24
- package/src/useObservable.ts +48 -28
- package/dist/reactfire.cjs.development.js +0 -2147
- package/dist/reactfire.cjs.development.js.map +0 -1
- package/dist/reactfire.cjs.production.min.js +0 -2
- package/dist/reactfire.cjs.production.min.js.map +0 -1
- package/dist/reactfire.esm.js +0 -2089
- package/dist/reactfire.esm.js.map +0 -1
- package/dist/remote-config/getValue.d.ts +0 -10
- package/src/remote-config/getValue.tsx +0 -58
package/src/sdk.tsx
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
+
import type { AppCheck } from 'firebase/app-check';
|
|
3
4
|
import type { Auth } from 'firebase/auth';
|
|
5
|
+
import type { Analytics } from 'firebase/analytics';
|
|
4
6
|
import type { Database } from 'firebase/database';
|
|
5
7
|
import type { Firestore } from 'firebase/firestore';
|
|
8
|
+
import type { Functions } from 'firebase/functions';
|
|
6
9
|
import type { FirebasePerformance } from 'firebase/performance';
|
|
7
10
|
import type { FirebaseStorage } from 'firebase/storage';
|
|
8
11
|
import type { RemoteConfig } from 'firebase/remote-config';
|
|
@@ -12,38 +15,25 @@ import { ObservableStatus, useObservable } from './useObservable';
|
|
|
12
15
|
import { from } from 'rxjs';
|
|
13
16
|
import { ReactFireOptions } from '.';
|
|
14
17
|
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
18
|
+
export const AppCheckSdkContext = React.createContext<AppCheck | undefined>(undefined);
|
|
19
|
+
export const AuthSdkContext = React.createContext<Auth | undefined>(undefined);
|
|
20
|
+
export const AnalyticsSdkContext = React.createContext<Analytics | undefined>(undefined);
|
|
21
|
+
export const DatabaseSdkContext = React.createContext<Database | undefined>(undefined);
|
|
22
|
+
export const FirestoreSdkContext = React.createContext<Firestore | undefined>(undefined);
|
|
23
|
+
export const FunctionsSdkContext = React.createContext<Functions | undefined>(undefined);
|
|
24
|
+
export const StorageSdkContext = React.createContext<FirebaseStorage | undefined>(undefined);
|
|
25
|
+
export const PerformanceSdkContext = React.createContext<FirebasePerformance | undefined>(undefined);
|
|
26
|
+
export const RemoteConfigSdkContext = React.createContext<RemoteConfig | undefined>(undefined);
|
|
21
27
|
|
|
22
|
-
type FirebaseSdks = Auth | Database | Firestore | FirebasePerformance | FirebaseStorage | RemoteConfig;
|
|
28
|
+
type FirebaseSdks = Analytics | AppCheck | Auth | Database | Firestore | FirebasePerformance | FirebaseStorage | Functions | RemoteConfig;
|
|
23
29
|
|
|
24
30
|
function getSdkProvider<Sdk extends FirebaseSdks>(SdkContext: React.Context<Sdk | undefined>) {
|
|
25
31
|
return function SdkProvider(props: React.PropsWithChildren<{ sdk: Sdk }>) {
|
|
26
|
-
|
|
27
|
-
let sdkAppName;
|
|
28
|
-
|
|
29
|
-
// @ts-ignore Auth doesn't have field 'app'
|
|
30
|
-
if (props.sdk.app) {
|
|
31
|
-
// @ts-ignore Auth doesn't have field 'app'
|
|
32
|
-
sdkAppName = props.sdk.app.name;
|
|
33
|
-
|
|
34
|
-
// @ts-ignore only Auth has field 'name'
|
|
35
|
-
} else if (props.sdk.name) {
|
|
36
|
-
// @ts-ignore only Auth has field 'name'
|
|
37
|
-
sdkAppName = props.sdk.name;
|
|
38
|
-
}
|
|
32
|
+
if (!props.sdk) throw new Error('no sdk provided');
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!props.sdk) {
|
|
45
|
-
throw new Error('no sdk provided');
|
|
46
|
-
}
|
|
34
|
+
const contextualAppName = useFirebaseApp().name;
|
|
35
|
+
const sdkAppName = props?.sdk?.app?.name;
|
|
36
|
+
if (sdkAppName !== contextualAppName) throw new Error('sdk was initialized with a different firebase app');
|
|
47
37
|
|
|
48
38
|
return <SdkContext.Provider value={props.sdk} {...props} />;
|
|
49
39
|
};
|
|
@@ -79,16 +69,22 @@ function useInitSdk<Sdk extends FirebaseSdks>(
|
|
|
79
69
|
return useObservable<Sdk>(`firebase-sdk:${sdkName}:${firebaseApp.name}`, from(initializeSdk), options);
|
|
80
70
|
}
|
|
81
71
|
|
|
72
|
+
export const AppCheckProvider = getSdkProvider<AppCheck>(AppCheckSdkContext);
|
|
82
73
|
export const AuthProvider = getSdkProvider<Auth>(AuthSdkContext);
|
|
74
|
+
export const AnalyticsProvider = getSdkProvider<Analytics>(AnalyticsSdkContext);
|
|
83
75
|
export const DatabaseProvider = getSdkProvider<Database>(DatabaseSdkContext);
|
|
84
76
|
export const FirestoreProvider = getSdkProvider<Firestore>(FirestoreSdkContext);
|
|
77
|
+
export const FunctionsProvider = getSdkProvider<Functions>(FunctionsSdkContext);
|
|
85
78
|
export const PerformanceProvider = getSdkProvider<FirebasePerformance>(PerformanceSdkContext);
|
|
86
79
|
export const StorageProvider = getSdkProvider<FirebaseStorage>(StorageSdkContext);
|
|
87
80
|
export const RemoteConfigProvider = getSdkProvider<RemoteConfig>(RemoteConfigSdkContext);
|
|
88
81
|
|
|
82
|
+
export const useAppCheck = () => useSdk<AppCheck>(AppCheckSdkContext);
|
|
89
83
|
export const useAuth = () => useSdk<Auth>(AuthSdkContext);
|
|
84
|
+
export const useAnalytics = () => useSdk<Analytics>(AnalyticsSdkContext);
|
|
90
85
|
export const useDatabase = () => useSdk<Database>(DatabaseSdkContext);
|
|
91
86
|
export const useFirestore = () => useSdk<Firestore>(FirestoreSdkContext);
|
|
87
|
+
export const useFunctions = () => useSdk<Functions>(FunctionsSdkContext);
|
|
92
88
|
export const usePerformance = () => useSdk<FirebasePerformance>(PerformanceSdkContext);
|
|
93
89
|
export const useStorage = () => useSdk<FirebaseStorage>(StorageSdkContext);
|
|
94
90
|
export const useRemoteConfig = () => useSdk<RemoteConfig>(RemoteConfigSdkContext);
|
|
@@ -98,9 +94,12 @@ type InitSdkHook<Sdk extends FirebaseSdks> = (
|
|
|
98
94
|
options?: ReactFireOptions<Sdk>
|
|
99
95
|
) => ObservableStatus<Sdk>;
|
|
100
96
|
|
|
97
|
+
export const useInitAppCheck: InitSdkHook<AppCheck> = (initializer, options) => useInitSdk<AppCheck>('appcheck', AppCheckSdkContext, initializer, options);
|
|
101
98
|
export const useInitAuth: InitSdkHook<Auth> = (initializer, options) => useInitSdk<Auth>('auth', AuthSdkContext, initializer, options);
|
|
99
|
+
export const useInitAnalytics: InitSdkHook<Analytics> = (initializer, options) => useInitSdk<Analytics>('analytics', AnalyticsSdkContext, initializer, options);
|
|
102
100
|
export const useInitDatabase: InitSdkHook<Database> = (initializer, options) => useInitSdk<Database>('database', DatabaseSdkContext, initializer, options);
|
|
103
101
|
export const useInitFirestore: InitSdkHook<Firestore> = (initializer, options) => useInitSdk<Firestore>('firestore', FirestoreSdkContext, initializer, options);
|
|
102
|
+
export const useInitFunctions: InitSdkHook<Functions> = (initializer, options) => useInitSdk<Functions>('functions', FunctionsSdkContext, initializer, options);
|
|
104
103
|
export const useInitPerformance: InitSdkHook<FirebasePerformance> = (initializer, options) =>
|
|
105
104
|
useInitSdk<FirebasePerformance>('performance', PerformanceSdkContext, initializer, options);
|
|
106
105
|
export const useInitRemoteConfig: InitSdkHook<RemoteConfig> = (initializer, options) =>
|
package/src/storage.tsx
CHANGED
|
@@ -1,33 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { getDownloadURL } from 'rxfire/storage';
|
|
3
|
-
import { Observable } from 'rxjs';
|
|
2
|
+
import { getDownloadURL, fromTask } from 'rxfire/storage';
|
|
4
3
|
import { ReactFireOptions, useObservable, ObservableStatus, useStorage } from './';
|
|
5
4
|
import { useSuspenseEnabledFromConfigAndContext } from './firebaseApp';
|
|
6
5
|
import { ref } from 'firebase/storage';
|
|
7
6
|
|
|
8
7
|
import type { UploadTask, UploadTaskSnapshot, StorageReference, FirebaseStorage } from 'firebase/storage';
|
|
9
8
|
|
|
10
|
-
/**
|
|
11
|
-
* modified version of rxFire's _fromTask
|
|
12
|
-
*
|
|
13
|
-
* @param task
|
|
14
|
-
*/
|
|
15
|
-
function _fromTask(task: UploadTask) {
|
|
16
|
-
return new Observable<UploadTaskSnapshot>((subscriber) => {
|
|
17
|
-
const progress = (snap: UploadTaskSnapshot) => {
|
|
18
|
-
return subscriber.next(snap);
|
|
19
|
-
};
|
|
20
|
-
const error = (e: any) => subscriber.error(e);
|
|
21
|
-
const complete = () => {
|
|
22
|
-
return subscriber.complete();
|
|
23
|
-
};
|
|
24
|
-
task.on('state_changed', progress, error, complete);
|
|
25
|
-
|
|
26
|
-
// I REMOVED THE UNSUBSCRIBE RETURN BECAUSE IT CANCELS THE UPLOAD
|
|
27
|
-
// https://github.com/firebase/firebase-js-sdk/issues/1659
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
9
|
/**
|
|
32
10
|
* Subscribe to the progress of a storage task
|
|
33
11
|
*
|
|
@@ -37,7 +15,7 @@ function _fromTask(task: UploadTask) {
|
|
|
37
15
|
*/
|
|
38
16
|
export function useStorageTask<T = unknown>(task: UploadTask, ref: StorageReference, options?: ReactFireOptions<T>): ObservableStatus<UploadTaskSnapshot | T> {
|
|
39
17
|
const observableId = `storage:task:${ref.toString()}`;
|
|
40
|
-
const observable$ =
|
|
18
|
+
const observable$ = fromTask(task);
|
|
41
19
|
|
|
42
20
|
return useObservable(observableId, observable$, options);
|
|
43
21
|
}
|
package/src/useObservable.ts
CHANGED
|
@@ -63,55 +63,75 @@ export interface ObservableStatus<T> {
|
|
|
63
63
|
firstValuePromise: Promise<void>;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function reducerFactory<T>(observable: SuspenseSubject<T>) {
|
|
67
|
+
return function reducer(state: ObservableStatus<T>, action: 'value' | 'error' | 'complete'): ObservableStatus<T> {
|
|
68
|
+
// always make sure these values are in sync with the observable
|
|
69
|
+
const newState = {
|
|
70
|
+
...state,
|
|
71
|
+
hasEmitted: state.hasEmitted || observable.hasValue,
|
|
72
|
+
error: observable.ourError,
|
|
73
|
+
firstValuePromise: observable.firstEmission,
|
|
74
|
+
};
|
|
75
|
+
if (observable.hasValue) {
|
|
76
|
+
newState.data = observable.value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
switch (action) {
|
|
80
|
+
case 'value':
|
|
81
|
+
newState.status = 'success';
|
|
82
|
+
return newState;
|
|
83
|
+
case 'error':
|
|
84
|
+
newState.status = 'error';
|
|
85
|
+
return newState;
|
|
86
|
+
case 'complete':
|
|
87
|
+
newState.isComplete = true;
|
|
88
|
+
return newState;
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`invalid action "${action}"`);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
66
95
|
export function useObservable<T = unknown>(observableId: string, source: Observable<T>, config: ReactFireOptions = {}): ObservableStatus<T> {
|
|
96
|
+
// Register the observable with the cache
|
|
67
97
|
if (!observableId) {
|
|
68
98
|
throw new Error('cannot call useObservable without an observableId');
|
|
69
99
|
}
|
|
70
100
|
const observable = preloadObservable(source, observableId);
|
|
71
101
|
|
|
102
|
+
// Suspend if suspense is enabled and no initial data exists
|
|
72
103
|
const hasInitialData = config.hasOwnProperty('initialData') || config.hasOwnProperty('startWithValue');
|
|
73
|
-
|
|
104
|
+
const hasData = observable.hasValue || hasInitialData;
|
|
74
105
|
const suspenseEnabled = useSuspenseEnabledFromConfigAndContext(config.suspense);
|
|
75
|
-
|
|
76
|
-
if (suspenseEnabled === true && !observable.hasValue && (!config?.initialData ?? !config?.startWithValue)) {
|
|
106
|
+
if (suspenseEnabled === true && !hasData) {
|
|
77
107
|
throw observable.firstEmission;
|
|
78
108
|
}
|
|
79
109
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
110
|
+
const initialState: ObservableStatus<T> = {
|
|
111
|
+
status: hasData ? 'success' : 'loading',
|
|
112
|
+
hasEmitted: hasData,
|
|
113
|
+
isComplete: false,
|
|
114
|
+
data: observable.hasValue ? observable.value : config?.initialData ?? config?.startWithValue,
|
|
115
|
+
error: observable.ourError,
|
|
116
|
+
firstValuePromise: observable.firstEmission,
|
|
117
|
+
};
|
|
118
|
+
const [status, dispatch] = React.useReducer<React.Reducer<ObservableStatus<T>, 'value' | 'error' | 'complete'>>(reducerFactory<T>(observable), initialState);
|
|
119
|
+
|
|
83
120
|
React.useEffect(() => {
|
|
84
121
|
const subscription = observable.subscribe({
|
|
85
|
-
next: (
|
|
86
|
-
|
|
122
|
+
next: () => {
|
|
123
|
+
dispatch('value');
|
|
87
124
|
},
|
|
88
125
|
error: (e) => {
|
|
89
|
-
|
|
126
|
+
dispatch('error');
|
|
90
127
|
throw e;
|
|
91
128
|
},
|
|
92
129
|
complete: () => {
|
|
93
|
-
|
|
130
|
+
dispatch('complete');
|
|
94
131
|
},
|
|
95
132
|
});
|
|
96
133
|
return () => subscription.unsubscribe();
|
|
97
134
|
}, [observable]);
|
|
98
135
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (hasError) {
|
|
102
|
-
status = 'error';
|
|
103
|
-
} else if (observable.hasValue || hasInitialData) {
|
|
104
|
-
status = 'success';
|
|
105
|
-
} else {
|
|
106
|
-
status = 'loading';
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
status,
|
|
111
|
-
hasEmitted: observable.hasValue || hasInitialData,
|
|
112
|
-
isComplete: isComplete,
|
|
113
|
-
data: latest,
|
|
114
|
-
error: observable.ourError,
|
|
115
|
-
firstValuePromise: observable.firstEmission,
|
|
116
|
-
};
|
|
136
|
+
return status;
|
|
117
137
|
}
|