diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d1cc2244..1d76cd68 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -100,6 +100,8 @@ jobs: run: npm install --no-save react@${{ matrix.react }} react-dom@${{ matrix.react }} @types/react@${{ matrix.react }} @types/react-dom@${{ matrix.react }} - name: Type check run: npx tsc --noEmit + - name: Type check tests + run: npx tsc --noEmit -p tsconfig.test.json publish: runs-on: ubuntu-latest name: Publish (NPM) diff --git a/docs/reference/README.md b/docs/reference/README.md index 452cbde8..52c83109 100644 --- a/docs/reference/README.md +++ b/docs/reference/README.md @@ -15,9 +15,7 @@ - [ClaimsCheckProps](interfaces/ClaimsCheckProps.md) - [ClaimsValidator](interfaces/ClaimsValidator.md) - [FirebaseAppProviderProps](interfaces/FirebaseAppProviderProps.md) -- [ObservableStatusError](interfaces/ObservableStatusError.md) -- [ObservableStatusLoading](interfaces/ObservableStatusLoading.md) -- [ObservableStatusSuccess](interfaces/ObservableStatusSuccess.md) +- [ObservableStatus](interfaces/ObservableStatus.md) - [ReactFireOptions](interfaces/ReactFireOptions.md) - [SignInCheckOptionsBasic](interfaces/SignInCheckOptionsBasic.md) - [SignInCheckOptionsClaimsObject](interfaces/SignInCheckOptionsClaimsObject.md) @@ -26,7 +24,6 @@ ## Type Aliases -- [ObservableStatus](type-aliases/ObservableStatus.md) - [ReactFireGlobals](type-aliases/ReactFireGlobals.md) - [SigninCheckResult](type-aliases/SigninCheckResult.md) - [StorageImageProps](type-aliases/StorageImageProps.md) diff --git a/docs/reference/functions/useCallableFunctionResponse.md b/docs/reference/functions/useCallableFunctionResponse.md index 04d98135..ddd4987c 100644 --- a/docs/reference/functions/useCallableFunctionResponse.md +++ b/docs/reference/functions/useCallableFunctionResponse.md @@ -6,7 +6,7 @@ # Function: useCallableFunctionResponse() -> **useCallableFunctionResponse**\<`RequestData`, `ResponseData`\>(`functionName`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`ResponseData`\> +> **useCallableFunctionResponse**\<`RequestData`, `ResponseData`\>(`functionName`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`ResponseData`\> Defined in: [src/functions.tsx:13](https://github.com/FirebaseExtended/reactfire/blob/main/src/functions.tsx#L13) @@ -36,4 +36,4 @@ The name of the function to call ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`ResponseData`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`ResponseData`\> diff --git a/docs/reference/functions/useDatabaseList.md b/docs/reference/functions/useDatabaseList.md index 80615cd5..4c501bf7 100644 --- a/docs/reference/functions/useDatabaseList.md +++ b/docs/reference/functions/useDatabaseList.md @@ -6,7 +6,7 @@ # Function: useDatabaseList() -> **useDatabaseList**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`[] \| `QueryChange`[]\> +> **useDatabaseList**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`[] \| `QueryChange`[]\> Defined in: [src/database.tsx:48](https://github.com/FirebaseExtended/reactfire/blob/main/src/database.tsx#L48) @@ -32,4 +32,4 @@ Reference to the DB List you want to listen to ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`[] \| `QueryChange`[]\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`[] \| `QueryChange`[]\> diff --git a/docs/reference/functions/useDatabaseListData.md b/docs/reference/functions/useDatabaseListData.md index 991381f3..41d5a441 100644 --- a/docs/reference/functions/useDatabaseListData.md +++ b/docs/reference/functions/useDatabaseListData.md @@ -6,7 +6,7 @@ # Function: useDatabaseListData() -> **useDatabaseListData**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`[] \| `null`\> +> **useDatabaseListData**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`[] \| `null`\> Defined in: [src/database.tsx:58](https://github.com/FirebaseExtended/reactfire/blob/main/src/database.tsx#L58) @@ -28,4 +28,4 @@ Defined in: [src/database.tsx:58](https://github.com/FirebaseExtended/reactfire/ ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`[] \| `null`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`[] \| `null`\> diff --git a/docs/reference/functions/useDatabaseObject.md b/docs/reference/functions/useDatabaseObject.md index 9ff176ff..632d5bf2 100644 --- a/docs/reference/functions/useDatabaseObject.md +++ b/docs/reference/functions/useDatabaseObject.md @@ -6,7 +6,7 @@ # Function: useDatabaseObject() -> **useDatabaseObject**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `QueryChange`\> +> **useDatabaseObject**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `QueryChange`\> Defined in: [src/database.tsx:27](https://github.com/FirebaseExtended/reactfire/blob/main/src/database.tsx#L27) @@ -32,4 +32,4 @@ Reference to the DB object you want to listen to ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `QueryChange`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `QueryChange`\> diff --git a/docs/reference/functions/useDatabaseObjectData.md b/docs/reference/functions/useDatabaseObjectData.md index 34fec029..ae86c498 100644 --- a/docs/reference/functions/useDatabaseObjectData.md +++ b/docs/reference/functions/useDatabaseObjectData.md @@ -6,7 +6,7 @@ # Function: useDatabaseObjectData() -> **useDatabaseObjectData**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`\> +> **useDatabaseObjectData**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`\> Defined in: [src/database.tsx:34](https://github.com/FirebaseExtended/reactfire/blob/main/src/database.tsx#L34) @@ -28,4 +28,4 @@ Defined in: [src/database.tsx:34](https://github.com/FirebaseExtended/reactfire/ ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`\> diff --git a/docs/reference/functions/useFirestoreCollection.md b/docs/reference/functions/useFirestoreCollection.md index a67b5de4..8cc2a2e4 100644 --- a/docs/reference/functions/useFirestoreCollection.md +++ b/docs/reference/functions/useFirestoreCollection.md @@ -6,7 +6,7 @@ # Function: useFirestoreCollection() -> **useFirestoreCollection**\<`T`\>(`query`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`QuerySnapshot`\<`T`, `DocumentData`\>\> +> **useFirestoreCollection**\<`T`\>(`query`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`QuerySnapshot`\<`T`, `DocumentData`\>\> Defined in: [src/firestore.tsx:86](https://github.com/FirebaseExtended/reactfire/blob/main/src/firestore.tsx#L86) @@ -30,4 +30,4 @@ Subscribe to a Firestore collection ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`QuerySnapshot`\<`T`, `DocumentData`\>\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`QuerySnapshot`\<`T`, `DocumentData`\>\> diff --git a/docs/reference/functions/useFirestoreCollectionData.md b/docs/reference/functions/useFirestoreCollectionData.md index 09f70b29..206f7132 100644 --- a/docs/reference/functions/useFirestoreCollectionData.md +++ b/docs/reference/functions/useFirestoreCollectionData.md @@ -6,7 +6,7 @@ # Function: useFirestoreCollectionData() -> **useFirestoreCollectionData**\<`T`\>(`query`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`[]\> +> **useFirestoreCollectionData**\<`T`\>(`query`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`[]\> Defined in: [src/firestore.tsx:96](https://github.com/FirebaseExtended/reactfire/blob/main/src/firestore.tsx#L96) @@ -30,4 +30,4 @@ Subscribe to a Firestore collection and unwrap the snapshot into an array. ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`[]\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`[]\> diff --git a/docs/reference/functions/useFirestoreDoc.md b/docs/reference/functions/useFirestoreDoc.md index 00add301..f14bb8b4 100644 --- a/docs/reference/functions/useFirestoreDoc.md +++ b/docs/reference/functions/useFirestoreDoc.md @@ -6,7 +6,7 @@ # Function: useFirestoreDoc() -> **useFirestoreDoc**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> +> **useFirestoreDoc**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> Defined in: [src/firestore.tsx:42](https://github.com/FirebaseExtended/reactfire/blob/main/src/firestore.tsx#L42) @@ -32,4 +32,4 @@ You can preload data for this hook by calling `preloadFirestoreDoc` ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> diff --git a/docs/reference/functions/useFirestoreDocData.md b/docs/reference/functions/useFirestoreDocData.md index 1267c3da..ffaaac8b 100644 --- a/docs/reference/functions/useFirestoreDocData.md +++ b/docs/reference/functions/useFirestoreDocData.md @@ -6,7 +6,7 @@ # Function: useFirestoreDocData() -> **useFirestoreDocData**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `undefined`\> +> **useFirestoreDocData**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `undefined`\> Defined in: [src/firestore.tsx:62](https://github.com/FirebaseExtended/reactfire/blob/main/src/firestore.tsx#L62) @@ -30,4 +30,4 @@ Subscribe to Firestore Document changes and unwrap the document into a plain obj ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `undefined`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `undefined`\> diff --git a/docs/reference/functions/useFirestoreDocDataOnce.md b/docs/reference/functions/useFirestoreDocDataOnce.md index db47124e..32da9e3e 100644 --- a/docs/reference/functions/useFirestoreDocDataOnce.md +++ b/docs/reference/functions/useFirestoreDocDataOnce.md @@ -6,7 +6,7 @@ # Function: useFirestoreDocDataOnce() -> **useFirestoreDocDataOnce**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `undefined`\> +> **useFirestoreDocDataOnce**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `undefined`\> Defined in: [src/firestore.tsx:74](https://github.com/FirebaseExtended/reactfire/blob/main/src/firestore.tsx#L74) @@ -30,4 +30,4 @@ Get a Firestore document, unwrap the document into a plain object, and don't sub ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `undefined`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `undefined`\> diff --git a/docs/reference/functions/useFirestoreDocOnce.md b/docs/reference/functions/useFirestoreDocOnce.md index bbe224d7..6280573d 100644 --- a/docs/reference/functions/useFirestoreDocOnce.md +++ b/docs/reference/functions/useFirestoreDocOnce.md @@ -6,7 +6,7 @@ # Function: useFirestoreDocOnce() -> **useFirestoreDocOnce**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> +> **useFirestoreDocOnce**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> Defined in: [src/firestore.tsx:52](https://github.com/FirebaseExtended/reactfire/blob/main/src/firestore.tsx#L52) @@ -30,4 +30,4 @@ Get a firestore document and don't subscribe to changes ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`DocumentSnapshot`\<`T`, `DocumentData`\>\> diff --git a/docs/reference/functions/useIdTokenResult.md b/docs/reference/functions/useIdTokenResult.md index a8e573dd..7293fc74 100644 --- a/docs/reference/functions/useIdTokenResult.md +++ b/docs/reference/functions/useIdTokenResult.md @@ -6,7 +6,7 @@ # Function: useIdTokenResult() -> **useIdTokenResult**(`user`, `forceRefresh?`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`IdTokenResult`\> +> **useIdTokenResult**(`user`, `forceRefresh?`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`IdTokenResult`\> Defined in: [src/auth.tsx:41](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L41) @@ -26,4 +26,4 @@ Defined in: [src/auth.tsx:41](https://github.com/FirebaseExtended/reactfire/blob ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`IdTokenResult`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`IdTokenResult`\> diff --git a/docs/reference/functions/useObservable.md b/docs/reference/functions/useObservable.md index e0e6db0c..4ca565df 100644 --- a/docs/reference/functions/useObservable.md +++ b/docs/reference/functions/useObservable.md @@ -6,9 +6,9 @@ # Function: useObservable() -> **useObservable**\<`T`\>(`observableId`, `source`, `config?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`\> +> **useObservable**\<`T`\>(`observableId`, `source`, `config?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`\> -Defined in: [src/useObservable.ts:86](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L86) +Defined in: [src/useObservable.ts:67](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L67) ## Type Parameters @@ -32,4 +32,4 @@ Defined in: [src/useObservable.ts:86](https://github.com/FirebaseExtended/reactf ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T`\> diff --git a/docs/reference/functions/useRemoteConfigAll.md b/docs/reference/functions/useRemoteConfigAll.md index 52553698..dcbdf075 100644 --- a/docs/reference/functions/useRemoteConfigAll.md +++ b/docs/reference/functions/useRemoteConfigAll.md @@ -6,7 +6,7 @@ # Function: useRemoteConfigAll() -> **useRemoteConfigAll**(`key`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`AllParameters`\> +> **useRemoteConfigAll**(`key`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`AllParameters`\> Defined in: [src/remote-config.tsx:66](https://github.com/FirebaseExtended/reactfire/blob/main/src/remote-config.tsx#L66) @@ -22,4 +22,4 @@ The parameter key in Remote Config ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`AllParameters`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`AllParameters`\> diff --git a/docs/reference/functions/useRemoteConfigBoolean.md b/docs/reference/functions/useRemoteConfigBoolean.md index 14c2e3c4..d696beb8 100644 --- a/docs/reference/functions/useRemoteConfigBoolean.md +++ b/docs/reference/functions/useRemoteConfigBoolean.md @@ -6,7 +6,7 @@ # Function: useRemoteConfigBoolean() -> **useRemoteConfigBoolean**(`key`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`boolean`\> +> **useRemoteConfigBoolean**(`key`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`boolean`\> Defined in: [src/remote-config.tsx:58](https://github.com/FirebaseExtended/reactfire/blob/main/src/remote-config.tsx#L58) @@ -22,4 +22,4 @@ The parameter key in Remote Config ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`boolean`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`boolean`\> diff --git a/docs/reference/functions/useRemoteConfigNumber.md b/docs/reference/functions/useRemoteConfigNumber.md index 337d8d66..7affc5bb 100644 --- a/docs/reference/functions/useRemoteConfigNumber.md +++ b/docs/reference/functions/useRemoteConfigNumber.md @@ -6,7 +6,7 @@ # Function: useRemoteConfigNumber() -> **useRemoteConfigNumber**(`key`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`number`\> +> **useRemoteConfigNumber**(`key`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`number`\> Defined in: [src/remote-config.tsx:50](https://github.com/FirebaseExtended/reactfire/blob/main/src/remote-config.tsx#L50) @@ -22,4 +22,4 @@ The parameter key in Remote Config ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`number`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`number`\> diff --git a/docs/reference/functions/useRemoteConfigString.md b/docs/reference/functions/useRemoteConfigString.md index 65e01bca..a16940fc 100644 --- a/docs/reference/functions/useRemoteConfigString.md +++ b/docs/reference/functions/useRemoteConfigString.md @@ -6,7 +6,7 @@ # Function: useRemoteConfigString() -> **useRemoteConfigString**(`key`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`string`\> +> **useRemoteConfigString**(`key`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`string`\> Defined in: [src/remote-config.tsx:42](https://github.com/FirebaseExtended/reactfire/blob/main/src/remote-config.tsx#L42) @@ -22,4 +22,4 @@ The parameter key in Remote Config ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`string`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`string`\> diff --git a/docs/reference/functions/useRemoteConfigValue.md b/docs/reference/functions/useRemoteConfigValue.md index d598191f..f8a9c115 100644 --- a/docs/reference/functions/useRemoteConfigValue.md +++ b/docs/reference/functions/useRemoteConfigValue.md @@ -6,7 +6,7 @@ # Function: useRemoteConfigValue() -> **useRemoteConfigValue**(`key`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`Value`\> +> **useRemoteConfigValue**(`key`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`Value`\> Defined in: [src/remote-config.tsx:34](https://github.com/FirebaseExtended/reactfire/blob/main/src/remote-config.tsx#L34) @@ -23,4 +23,4 @@ The parameter key in Remote Config ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`Value`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`Value`\> diff --git a/docs/reference/functions/useSigninCheck.md b/docs/reference/functions/useSigninCheck.md index 928d22e5..32e3e619 100644 --- a/docs/reference/functions/useSigninCheck.md +++ b/docs/reference/functions/useSigninCheck.md @@ -6,7 +6,7 @@ # Function: useSigninCheck() -> **useSigninCheck**(`options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<[`SigninCheckResult`](../type-aliases/SigninCheckResult.md)\> +> **useSigninCheck**(`options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<[`SigninCheckResult`](../type-aliases/SigninCheckResult.md)\> Defined in: [src/auth.tsx:134](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L134) @@ -48,4 +48,4 @@ const {status, data: signInCheckResult} = useSigninCheck({forceRefresh: true, re ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<[`SigninCheckResult`](../type-aliases/SigninCheckResult.md)\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<[`SigninCheckResult`](../type-aliases/SigninCheckResult.md)\> diff --git a/docs/reference/functions/useStorageDownloadURL.md b/docs/reference/functions/useStorageDownloadURL.md index 2ab6fb3d..898c4931 100644 --- a/docs/reference/functions/useStorageDownloadURL.md +++ b/docs/reference/functions/useStorageDownloadURL.md @@ -6,7 +6,7 @@ # Function: useStorageDownloadURL() -> **useStorageDownloadURL**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`string` \| `T`\> +> **useStorageDownloadURL**\<`T`\>(`ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`string` \| `T`\> Defined in: [src/storage.tsx:29](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L29) @@ -32,4 +32,4 @@ reference to the blob you want to download ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`string` \| `T`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`string` \| `T`\> diff --git a/docs/reference/functions/useStorageTask.md b/docs/reference/functions/useStorageTask.md index 2d462c71..ccda3ddf 100644 --- a/docs/reference/functions/useStorageTask.md +++ b/docs/reference/functions/useStorageTask.md @@ -6,7 +6,7 @@ # Function: useStorageTask() -> **useStorageTask**\<`T`\>(`task`, `ref`, `options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `UploadTaskSnapshot`\> +> **useStorageTask**\<`T`\>(`task`, `ref`, `options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `UploadTaskSnapshot`\> Defined in: [src/storage.tsx:16](https://github.com/FirebaseExtended/reactfire/blob/main/src/storage.tsx#L16) @@ -38,4 +38,4 @@ reference to the blob the task is acting on ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`T` \| `UploadTaskSnapshot`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`T` \| `UploadTaskSnapshot`\> diff --git a/docs/reference/functions/useUser.md b/docs/reference/functions/useUser.md index da91d45b..0f7277e6 100644 --- a/docs/reference/functions/useUser.md +++ b/docs/reference/functions/useUser.md @@ -6,7 +6,7 @@ # Function: useUser() -> **useUser**\<`T`\>(`options?`): [`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`User` \| `null`\> +> **useUser**\<`T`\>(`options?`): [`ObservableStatus`](../interfaces/ObservableStatus.md)\<`User` \| `null`\> Defined in: [src/auth.tsx:22](https://github.com/FirebaseExtended/reactfire/blob/main/src/auth.tsx#L22) @@ -26,4 +26,4 @@ Subscribe to Firebase auth state changes, including token refresh ## Returns -[`ObservableStatus`](../type-aliases/ObservableStatus.md)\<`User` \| `null`\> +[`ObservableStatus`](../interfaces/ObservableStatus.md)\<`User` \| `null`\> diff --git a/docs/reference/interfaces/ObservableStatusSuccess.md b/docs/reference/interfaces/ObservableStatus.md similarity index 66% rename from docs/reference/interfaces/ObservableStatusSuccess.md rename to docs/reference/interfaces/ObservableStatus.md index 8a5a4445..a1846ef9 100644 --- a/docs/reference/interfaces/ObservableStatusSuccess.md +++ b/docs/reference/interfaces/ObservableStatus.md @@ -2,15 +2,11 @@ *** -[ReactFire reference docs](../README.md) / ObservableStatusSuccess +[ReactFire reference docs](../README.md) / ObservableStatus -# Interface: ObservableStatusSuccess\ +# Interface: ObservableStatus\ -Defined in: [src/useObservable.ts:67](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L67) - -## Extends - -- `ObservableStatusBase`\<`T`\> +Defined in: [src/useObservable.ts:30](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L30) ## Type Parameters @@ -24,16 +20,12 @@ Defined in: [src/useObservable.ts:67](https://github.com/FirebaseExtended/reactf > **data**: `T` -Defined in: [src/useObservable.ts:69](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L69) +Defined in: [src/useObservable.ts:56](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L56) The most recent value. If `initialData` is passed in, the first value of `data` will be the valuea provided in `initialData` **UNLESS** the underlying observable is ready, in which case it will skip `initialData`. -#### Overrides - -`ObservableStatusBase.data` - *** ### error @@ -44,10 +36,6 @@ Defined in: [src/useObservable.ts:60](https://github.com/FirebaseExtended/reactf Any error that may have occurred in the underlying observable -#### Inherited from - -`ObservableStatusBase.error` - *** ### firstValuePromise @@ -58,10 +46,6 @@ Defined in: [src/useObservable.ts:64](https://github.com/FirebaseExtended/reactf Promise that resolves after first emit from observable -#### Inherited from - -`ObservableStatusBase.firstValuePromise` - *** ### hasEmitted @@ -74,10 +58,6 @@ Indicates whether the hook has emitted a value at some point If `initialData` is passed in, this will be `true`. -#### Inherited from - -`ObservableStatusBase.hasEmitted` - *** ### isComplete @@ -88,17 +68,13 @@ Defined in: [src/useObservable.ts:50](https://github.com/FirebaseExtended/reactf If this is `true`, the hook will be emitting no further items. -#### Inherited from - -`ObservableStatusBase.isComplete` - *** ### status -> **status**: `"success"` +> **status**: `"error"` \| `"loading"` \| `"success"` -Defined in: [src/useObservable.ts:68](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L68) +Defined in: [src/useObservable.ts:40](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L40) The loading status. @@ -107,7 +83,3 @@ The loading status. - `success`: The hook has emitted at least one value If `initialData` is passed in, this will skip `loading` and go straight to `success`. - -#### Overrides - -`ObservableStatusBase.status` diff --git a/docs/reference/interfaces/ObservableStatusError.md b/docs/reference/interfaces/ObservableStatusError.md deleted file mode 100644 index c6293b1d..00000000 --- a/docs/reference/interfaces/ObservableStatusError.md +++ /dev/null @@ -1,113 +0,0 @@ -[**ReactFire reference docs**](../README.md) - -*** - -[ReactFire reference docs](../README.md) / ObservableStatusError - -# Interface: ObservableStatusError\ - -Defined in: [src/useObservable.ts:72](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L72) - -## Extends - -- `ObservableStatusBase`\<`T`\> - -## Type Parameters - -### T - -`T` - -## Properties - -### data - -> **data**: `T` \| `undefined` - -Defined in: [src/useObservable.ts:56](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L56) - -The most recent value. - -If `initialData` is passed in, the first value of `data` will be the valuea provided in `initialData` **UNLESS** the underlying observable is ready, in which case it will skip `initialData`. - -#### Inherited from - -`ObservableStatusBase.data` - -*** - -### error - -> **error**: `Error` - -Defined in: [src/useObservable.ts:75](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L75) - -Any error that may have occurred in the underlying observable - -#### Overrides - -`ObservableStatusBase.error` - -*** - -### firstValuePromise - -> **firstValuePromise**: `Promise`\<`void`\> - -Defined in: [src/useObservable.ts:64](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L64) - -Promise that resolves after first emit from observable - -#### Inherited from - -`ObservableStatusBase.firstValuePromise` - -*** - -### hasEmitted - -> **hasEmitted**: `boolean` - -Defined in: [src/useObservable.ts:46](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L46) - -Indicates whether the hook has emitted a value at some point - -If `initialData` is passed in, this will be `true`. - -#### Inherited from - -`ObservableStatusBase.hasEmitted` - -*** - -### isComplete - -> **isComplete**: `true` - -Defined in: [src/useObservable.ts:74](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L74) - -If this is `true`, the hook will be emitting no further items. - -#### Overrides - -`ObservableStatusBase.isComplete` - -*** - -### status - -> **status**: `"error"` - -Defined in: [src/useObservable.ts:73](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L73) - -The loading status. - -- `loading`: Waiting for the first value from an observable -- `error`: Something went wrong. Check `ObservableStatus.error` for more details -- `success`: The hook has emitted at least one value - -If `initialData` is passed in, this will skip `loading` and go straight to `success`. - -#### Overrides - -`ObservableStatusBase.status` diff --git a/docs/reference/interfaces/ObservableStatusLoading.md b/docs/reference/interfaces/ObservableStatusLoading.md deleted file mode 100644 index f0bf2fcd..00000000 --- a/docs/reference/interfaces/ObservableStatusLoading.md +++ /dev/null @@ -1,113 +0,0 @@ -[**ReactFire reference docs**](../README.md) - -*** - -[ReactFire reference docs](../README.md) / ObservableStatusLoading - -# Interface: ObservableStatusLoading\ - -Defined in: [src/useObservable.ts:78](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L78) - -## Extends - -- `ObservableStatusBase`\<`T`\> - -## Type Parameters - -### T - -`T` - -## Properties - -### data - -> **data**: `undefined` - -Defined in: [src/useObservable.ts:80](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L80) - -The most recent value. - -If `initialData` is passed in, the first value of `data` will be the valuea provided in `initialData` **UNLESS** the underlying observable is ready, in which case it will skip `initialData`. - -#### Overrides - -`ObservableStatusBase.data` - -*** - -### error - -> **error**: `Error` \| `undefined` - -Defined in: [src/useObservable.ts:60](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L60) - -Any error that may have occurred in the underlying observable - -#### Inherited from - -`ObservableStatusBase.error` - -*** - -### firstValuePromise - -> **firstValuePromise**: `Promise`\<`void`\> - -Defined in: [src/useObservable.ts:64](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L64) - -Promise that resolves after first emit from observable - -#### Inherited from - -`ObservableStatusBase.firstValuePromise` - -*** - -### hasEmitted - -> **hasEmitted**: `false` - -Defined in: [src/useObservable.ts:81](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L81) - -Indicates whether the hook has emitted a value at some point - -If `initialData` is passed in, this will be `true`. - -#### Overrides - -`ObservableStatusBase.hasEmitted` - -*** - -### isComplete - -> **isComplete**: `boolean` - -Defined in: [src/useObservable.ts:50](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L50) - -If this is `true`, the hook will be emitting no further items. - -#### Inherited from - -`ObservableStatusBase.isComplete` - -*** - -### status - -> **status**: `"loading"` - -Defined in: [src/useObservable.ts:79](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L79) - -The loading status. - -- `loading`: Waiting for the first value from an observable -- `error`: Something went wrong. Check `ObservableStatus.error` for more details -- `success`: The hook has emitted at least one value - -If `initialData` is passed in, this will skip `loading` and go straight to `success`. - -#### Overrides - -`ObservableStatusBase.status` diff --git a/docs/reference/type-aliases/ObservableStatus.md b/docs/reference/type-aliases/ObservableStatus.md deleted file mode 100644 index bbf0276d..00000000 --- a/docs/reference/type-aliases/ObservableStatus.md +++ /dev/null @@ -1,17 +0,0 @@ -[**ReactFire reference docs**](../README.md) - -*** - -[ReactFire reference docs](../README.md) / ObservableStatus - -# Type Alias: ObservableStatus\ - -> **ObservableStatus**\<`T`\> = [`ObservableStatusLoading`](../interfaces/ObservableStatusLoading.md)\<`T`\> \| [`ObservableStatusError`](../interfaces/ObservableStatusError.md)\<`T`\> \| [`ObservableStatusSuccess`](../interfaces/ObservableStatusSuccess.md)\<`T`\> - -Defined in: [src/useObservable.ts:84](https://github.com/FirebaseExtended/reactfire/blob/main/src/useObservable.ts#L84) - -## Type Parameters - -### T - -`T` diff --git a/src/SuspenseSubject.ts b/src/SuspenseSubject.ts index f2372768..0c52b9b5 100644 --- a/src/SuspenseSubject.ts +++ b/src/SuspenseSubject.ts @@ -29,7 +29,7 @@ export class SuspenseSubject extends Subject { data: undefined, error: undefined, firstValuePromise: this._firstEmission - }; + } as ObservableStatus; this._innerObservable = innerObservable.pipe( tap({ @@ -88,11 +88,9 @@ export class SuspenseSubject extends Subject { } private _updateImmutableStatus() { - // @ts-expect-error - // TS fails here because ObservableStatus defines specific - // relationships between the fields. This is difficult to - // code for here, so the relationships between the ObservableStatus fields - // are mostly checked in tests instead + // Cast required because `data` is internally `T | undefined` while a value is + // still in flight, whereas ObservableStatus exposes `data: T` to consumers. + // The relationships between the status fields are verified in tests instead. this._immutableStatus = { status: this._error ? 'error' : (this._hasValue ? 'success' : 'loading'), hasEmitted: this._hasValue, @@ -100,7 +98,7 @@ export class SuspenseSubject extends Subject { data: this._value, error: this._error, firstValuePromise: this._firstEmission - }; + } as ObservableStatus; } private _next(value: T) { diff --git a/src/useObservable.ts b/src/useObservable.ts index fe05be5d..9e6173a8 100644 --- a/src/useObservable.ts +++ b/src/useObservable.ts @@ -27,7 +27,7 @@ export function preloadObservable(source: Observable, id: string, suspense } } -interface ObservableStatusBase { +export interface ObservableStatus { /** * The loading status. * @@ -53,7 +53,7 @@ interface ObservableStatusBase { * * If `initialData` is passed in, the first value of `data` will be the valuea provided in `initialData` **UNLESS** the underlying observable is ready, in which case it will skip `initialData`. */ - data: T | undefined; + data: T; /** * Any error that may have occurred in the underlying observable */ @@ -64,25 +64,6 @@ interface ObservableStatusBase { firstValuePromise: Promise; } -export interface ObservableStatusSuccess extends ObservableStatusBase { - status: 'success'; - data: T; -} - -export interface ObservableStatusError extends ObservableStatusBase { - status: 'error'; - isComplete: true; - error: Error; -} - -export interface ObservableStatusLoading extends ObservableStatusBase { - status: 'loading'; - data: undefined; - hasEmitted: false; -} - -export type ObservableStatus = ObservableStatusLoading | ObservableStatusError | ObservableStatusSuccess; - export function useObservable(observableId: string, source: Observable, config: ReactFireOptions = {}): ObservableStatus { if (!observableId) { throw new Error('cannot call useObservable without an observableId'); diff --git a/test/auth.test.tsx b/test/auth.test.tsx index c717754a..3a66784f 100644 --- a/test/auth.test.tsx +++ b/test/auth.test.tsx @@ -11,8 +11,6 @@ import { useSigninCheck, ClaimCheckErrors, ClaimsValidator, - ObservableStatus, - SigninCheckResult, } from '../src/index'; import { baseConfig } from './appConfig'; import { FirebaseApp, initializeApp } from 'firebase/app'; @@ -24,7 +22,7 @@ describe('Authentication', () => { let app: FirebaseApp; let signIn: () => Promise; - const Provider: React.FunctionComponent = ({ children }) => ( + const Provider: React.FunctionComponent = ({ children }) => ( {children} diff --git a/test/database.test.tsx b/test/database.test.tsx index a30b93a4..e1b63754 100644 --- a/test/database.test.tsx +++ b/test/database.test.tsx @@ -1,6 +1,6 @@ import { renderHook, act, cleanup, waitFor } from '@testing-library/react'; import * as React from 'react'; -import { useDatabaseObject, useDatabaseList, FirebaseAppProvider, DatabaseProvider, ObservableStatus } from '../src/index'; +import { useDatabaseObject, useDatabaseObjectData, useDatabaseList, FirebaseAppProvider, DatabaseProvider } from '../src/index'; import { baseConfig } from './appConfig'; import { initializeApp } from 'firebase/app'; import { getDatabase, connectDatabaseEmulator, ref, set, push, query, orderByChild, equalTo, get } from 'firebase/database'; @@ -72,6 +72,22 @@ describe('Realtime Database (RTDB)', () => { }); }); + describe('useDatabaseObjectData', () => { + it('unwraps an object to a concretely-typed value', async () => { + const mockData = { a: 'hello' }; + const objectRef = ref(database, randomString()); + await set(objectRef, mockData); + + const { result } = renderHook(() => useDatabaseObjectData<{ a: string }>(objectRef), { wrapper: Provider }); + + await waitFor(() => expect(result.current.status).toEqual('success')); + + // `data` is `{ a: string }` (not a union), so this both exercises the hook and + // guards against ObservableStatus regressing to a `data: T | undefined` union. + expect(result.current.data.a).toEqual(mockData.a); + }); + }); + describe('useDatabaseList', () => { it('can get a list', async () => { const mockData1 = { a: 'hello' }; diff --git a/test/firestore.test.tsx b/test/firestore.test.tsx index f83aee19..2ad49e62 100644 --- a/test/firestore.test.tsx +++ b/test/firestore.test.tsx @@ -16,7 +16,7 @@ import { initializeApp } from 'firebase/app'; import { baseConfig } from './appConfig'; import { randomString } from './test-utils'; -import { addDoc, collection, doc, getFirestore, query, setDoc, connectFirestoreEmulator, where, getDoc } from 'firebase/firestore'; +import { addDoc, collection, doc, getFirestore, query, setDoc, connectFirestoreEmulator, where } from 'firebase/firestore'; import type { DocumentReference } from 'firebase/firestore'; describe('Firestore', () => { @@ -84,6 +84,19 @@ describe('Firestore', () => { expect(data.id).toBeDefined(); }); + it('reads concretely-typed document data', async () => { + const mockData = { a: 'hello' }; + const ref = doc(collection(db, randomString()), randomString()) as DocumentReference<{ a: string }>; + await setDoc(ref, mockData); + + const { result } = renderHook(() => useFirestoreDocData<{ a: string }>(ref), { wrapper: Provider }); + await waitFor(() => expect(result.current.status).toEqual('success')); + + // Concretely-typed read (not ``): `data` is `{ a: string } | undefined`, so a + // regression of ObservableStatus back to a union would be caught here at compile time. + expect(result.current.data?.a).toEqual(mockData.a); + }); + it('returns undefined if document does not exist', async () => { const collectionRef = collection(db, randomString()); const docIdThatExists = randomString(); diff --git a/test/storage.test.tsx b/test/storage.test.tsx index bfea2297..043457b4 100644 --- a/test/storage.test.tsx +++ b/test/storage.test.tsx @@ -1,9 +1,9 @@ import { initializeApp } from 'firebase/app'; import { getDownloadURL, getStorage, ref, uploadBytesResumable, UploadTaskSnapshot, connectStorageEmulator } from 'firebase/storage'; import { FunctionComponent } from 'react'; -import { FirebaseAppProvider, ObservableStatus, StorageProvider, useStorageDownloadURL, useStorageTask } from '../src/index'; +import { FirebaseAppProvider, StorageProvider, useStorageDownloadURL, useStorageTask } from '../src/index'; import { baseConfig } from './appConfig'; -import { renderHook, act, waitFor } from '@testing-library/react'; +import { renderHook, waitFor } from '@testing-library/react'; import * as React from 'react'; import { randomString } from './test-utils'; diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 00000000..9de4dd68 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,14 @@ +{ + // Type-check the test suite against the library's public types. + // This is intentionally separate from tsconfig.json (which emits dist/) so that + // consumer-facing usage in tests (e.g. reading `.data` off a hook result) is + // type-checked and would fail CI on a breaking type regression. + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "declaration": false, + "noEmit": true, + "types": ["vitest/globals", "node"] + }, + "include": ["src", "types", "test"] +}