@@ -2,190 +2,22 @@ import {
22 CollectionReference ,
33 DocumentReference ,
44 Query ,
5- FirestoreError ,
6- DocumentData ,
7- FirestoreDataConverter ,
85 getFirestore ,
96} from 'firebase/firestore'
10- import {
11- getCurrentInstance ,
12- getCurrentScope ,
13- isRef ,
14- onScopeDispose ,
15- onServerPrefetch ,
16- ref ,
17- Ref ,
18- ShallowRef ,
19- shallowRef ,
20- unref ,
21- watch ,
22- } from 'vue-demi'
7+ import { ref } from 'vue-demi'
238import { useFirebaseApp } from '../app'
9+ import type { _MaybeRef , _Nullable , _RefWithState } from '../shared'
2410import {
25- checkWrittenTarget ,
26- isDocumentRef ,
27- isSSR ,
28- noop ,
29- OperationsType ,
30- ResetOption ,
31- UnbindWithReset ,
32- walkSet ,
33- _MaybeRef ,
34- _Nullable ,
35- _RefWithState ,
36- } from '../shared'
37- import { getInitialValue } from '../ssr/initialState'
38- import { addPendingPromise } from '../ssr/plugin'
39- import { firestoreUnbinds } from './optionsApi'
40- import {
41- bindCollection ,
42- bindDocument ,
43- firestoreOptionsDefaults ,
44- FirestoreRefOptions ,
45- } from './subscribe'
46-
47- export const ops : OperationsType = {
48- set : ( target , key , value ) => walkSet ( target , key , value ) ,
49- add : ( array , index , data ) => array . splice ( index , 0 , data ) ,
50- remove : ( array , index ) => array . splice ( index , 1 ) ,
51- }
52-
53- export interface _UseFirestoreRefOptions extends FirestoreRefOptions {
54- /**
55- * @deprecated : use `.withConverter()` instead
56- */
57- converter ?: any
58- }
59-
60- /**
61- * Internal version of `useDocument()` and `useCollection()`.
62- *
63- * @internal
64- */
65- export function _useFirestoreRef (
66- docOrCollectionRef : _MaybeRef <
67- _Nullable <
68- DocumentReference < unknown > | Query < unknown > | CollectionReference < unknown >
69- >
70- > ,
71- localOptions ?: _UseFirestoreRefOptions
72- ) : _RefFirestore < unknown > {
73- let unbind : UnbindWithReset = noop
74- const options = Object . assign ( { } , firestoreOptionsDefaults , localOptions )
75- const initialSourceValue = unref ( docOrCollectionRef )
76- const data = options . target || ref < unknown | null > ( )
77-
78- // dev only warning
79- if ( process . env . NODE_ENV !== 'production' ) {
80- // is the target a ref that has already been passed to useDocument() and therefore can't be extended anymore
81- if (
82- options . target &&
83- checkWrittenTarget ( data , 'useDocument()/useCollection()' )
84- ) {
85- return data as _RefFirestore < unknown >
86- }
87- }
88-
89- if ( isSSR ( ) ) {
90- options . once = true
91- }
92-
93- // set the initial value from SSR even if the ref comes from outside
94- data . value = getInitialValue ( initialSourceValue , options . ssrKey , data . value )
95-
96- const pending = ref ( true )
97- const error = ref < FirestoreError > ( )
98- // force the type since its value is set right after and undefined isn't possible
99- const promise = shallowRef ( ) as ShallowRef < Promise < unknown | null > >
100- const hasCurrentScope = getCurrentScope ( )
101- let removePendingPromise = noop
102-
103- function bindFirestoreRef ( ) {
104- let docRefValue = unref ( docOrCollectionRef )
105-
106- const p = new Promise < unknown | null > ( ( resolve , reject ) => {
107- // stop the previous subscription
108- unbind ( options . reset )
109- // skip if the ref is null or undefined
110- // we still want to create the new promise
111- if ( ! docRefValue ) {
112- unbind = noop
113- // resolve to avoid an ever pending promise
114- return resolve ( null )
115- }
116-
117- if ( ! docRefValue . converter ) {
118- docRefValue = docRefValue . withConverter (
119- // @ts -expect-error: seems like a ts error
120- options . converter as FirestoreDataConverter < T >
121- )
122- }
123-
124- // FIXME: force once on server
125- unbind = ( isDocumentRef ( docRefValue ) ? bindDocument : bindCollection ) (
126- // @ts -expect-error: cannot type with the ternary
127- data ,
128- docRefValue ,
129- ops ,
130- resolve ,
131- reject ,
132- options
133- )
134- } )
135-
136- promise . value = p
137-
138- p . catch ( ( reason : FirestoreError ) => {
139- error . value = reason
140- } ) . finally ( ( ) => {
141- pending . value = false
142- } )
143- }
144-
145- let stopWatcher = noop
146- if ( isRef ( docOrCollectionRef ) ) {
147- stopWatcher = watch ( docOrCollectionRef , bindFirestoreRef , {
148- immediate : true ,
149- } )
150- } else {
151- bindFirestoreRef ( )
152- }
153-
154- // only add the first promise to the pending ones
155- if ( initialSourceValue ) {
156- removePendingPromise = addPendingPromise (
157- promise . value ,
158- initialSourceValue ,
159- options . ssrKey
160- )
161- }
162- if ( getCurrentInstance ( ) ) {
163- // wait for the promise during SSR
164- // TODO: configurable ssrKey: false to disable this
165- onServerPrefetch ( ( ) => promise . value )
166- }
167-
168- if ( hasCurrentScope ) {
169- onScopeDispose ( stop )
170- }
171-
172- function stop ( reset : ResetOption = options . reset ) {
173- stopWatcher ( )
174- removePendingPromise ( )
175- unbind ( reset )
176- }
177-
178- // allow to destructure the returned value
179- return Object . defineProperties ( data as _RefFirestore < unknown > , {
180- error : { get : ( ) => error } ,
181- data : { get : ( ) => data } ,
182- pending : { get : ( ) => pending } ,
183- promise : { get : ( ) => promise } ,
184- stop : { get : ( ) => stop } ,
185- } )
186- }
11+ VueFirestoreDocumentData ,
12+ VueFirestoreQueryData ,
13+ _InferReferenceType ,
14+ _RefFirestore ,
15+ _useFirestoreRef ,
16+ _UseFirestoreRefOptions ,
17+ } from './useFirestoreRef'
18718
18819export interface UseCollectionOptions extends _UseFirestoreRefOptions { }
20+ export type { _RefFirestore , VueFirestoreDocumentData , VueFirestoreQueryData }
18921
19022/**
19123 * Creates a reactive collection (usually an array) of documents from a collection ref or a query from Firestore. Extracts the the type of the
@@ -227,8 +59,6 @@ export function useCollection<T>(
22759 } ) as _RefFirestore < VueFirestoreQueryData < T > >
22860}
22961
230- // TODO: split document and collection into two different files
231-
23262export interface UseDocumentOptions extends _UseFirestoreRefOptions { }
23363
23464/**
@@ -268,52 +98,6 @@ export function useDocument<T>(
26898 >
26999}
270100
271- // TODO: move to an unsubscribe file
272-
273- export function internalUnbind (
274- key : string ,
275- unbinds : Record < string , UnbindWithReset > | undefined ,
276- reset ?: FirestoreRefOptions [ 'reset' ]
277- ) {
278- if ( unbinds && unbinds [ key ] ) {
279- unbinds [ key ] ( reset )
280- delete unbinds [ key ]
281- }
282- }
283-
284- export const unbind = ( target : Ref , reset ?: FirestoreRefOptions [ 'reset' ] ) =>
285- internalUnbind ( '' , firestoreUnbinds . get ( target ) , reset )
286-
287- /**
288- * Infers the type from a firestore reference. If it is not a reference, it returns the type as is.
289- *
290- * @internal
291- */
292- export type _InferReferenceType < R > = R extends
293- | CollectionReference < infer T >
294- | Query < infer T >
295- | DocumentReference < infer T >
296- ? T
297- : R
298-
299- /**
300- * Type used by default by the `firestoreDefaultConverter`.
301- */
302- export type VueFirestoreDocumentData < T = DocumentData > =
303- | null
304- | ( T & {
305- /**
306- * id of the document
307- */
308- readonly id : string
309- } )
310-
311- export type VueFirestoreQueryData < T = DocumentData > = Array <
312- Exclude < VueFirestoreDocumentData < T > , null >
313- >
314-
315- export interface _RefFirestore < T > extends _RefWithState < T , FirestoreError > { }
316-
317101/**
318102 * Retrieves the Firestore instance.
319103 *
0 commit comments