1- import {
2- Ref ,
3- ref ,
4- getCurrentScope ,
5- onScopeDispose ,
6- shallowRef ,
7- ShallowRef ,
8- unref ,
9- watch ,
10- isRef ,
11- getCurrentInstance ,
12- onServerPrefetch ,
13- } from 'vue-demi'
1+ import { Ref , ref } from 'vue-demi'
142import { DatabaseReference , getDatabase , Query } from 'firebase/database'
15- import {
16- checkWrittenTarget ,
17- isSSR ,
18- noop ,
19- OperationsType ,
20- ResetOption ,
21- UnbindWithReset ,
22- walkSet ,
23- _MaybeRef ,
24- _Nullable ,
25- _RefWithState ,
26- } from '../shared'
27- import { databaseUnbinds } from './optionsApi'
28- import {
29- bindAsArray ,
30- bindAsObject ,
31- databaseOptionsDefaults ,
32- _DatabaseRefOptions ,
33- } from './subscribe'
3+ import { _MaybeRef , _Nullable , _RefWithState } from '../shared'
4+ import { _DatabaseRefOptions } from './bind'
345import {
356 VueDatabaseDocumentData ,
367 VueDatabaseQueryData ,
378 _RefDatabase ,
389} from './utils'
39- import { addPendingPromise } from '../ssr/plugin'
4010import { useFirebaseApp } from '../app'
41- import { getInitialValue } from '../ssr/initialState '
11+ import { UseDatabaseRefOptions , _useDatabaseRef } from './useDatabaseRef '
4212
4313export { databasePlugin } from './optionsApi'
44-
45- export interface UseDatabaseRefOptions extends _DatabaseRefOptions { }
46-
47- export function _useDatabaseRef (
48- reference : _MaybeRef < _Nullable < DatabaseReference | Query > > ,
49- localOptions : UseDatabaseRefOptions = { }
50- ) : _RefDatabase < unknown > {
51- let unbind ! : UnbindWithReset
52- const options = Object . assign ( { } , databaseOptionsDefaults , localOptions )
53- const initialSourceValue = unref ( reference )
54- const data = options . target || ref < unknown | null > ( )
55-
56- // dev only warning
57- if ( process . env . NODE_ENV !== 'production' ) {
58- // is the target a ref that has already been passed to useDocument() and therefore can't be extended anymore
59- if ( options . target && checkWrittenTarget ( data , 'useObject()/useList()' ) ) {
60- return data as _RefDatabase < unknown >
61- }
62- }
63-
64- // During SSR, we should only get data once
65- if ( isSSR ( ) ) {
66- options . once = true
67- }
68-
69- // set the initial value from SSR even if the ref comes from outside
70- data . value = getInitialValue ( initialSourceValue , options . ssrKey , data . value )
71-
72- const error = ref < Error > ( )
73- const pending = ref ( true )
74- // force the type since its value is set right after and undefined isn't possible
75- const promise = shallowRef ( ) as ShallowRef < Promise < unknown | null > >
76- const hasCurrentScope = getCurrentScope ( )
77- let removePendingPromise = noop
78-
79- function bindDatabaseRef ( ) {
80- let referenceValue = unref ( reference )
81-
82- const p = new Promise < unknown | null > ( ( resolve , reject ) => {
83- if ( ! referenceValue ) {
84- unbind = noop
85- // resolve to avoid an ever pending promise
86- return resolve ( null )
87- }
88-
89- if ( Array . isArray ( data . value ) ) {
90- unbind = bindAsArray (
91- data as Ref < any > ,
92- referenceValue ,
93- resolve ,
94- reject ,
95- options
96- )
97- } else {
98- unbind = bindAsObject ( data , referenceValue , resolve , reject , options )
99- }
100- } )
101-
102- promise . value = p
103-
104- p . catch ( ( reason ) => {
105- error . value = reason
106- } ) . finally ( ( ) => {
107- pending . value = false
108- } )
109- }
110-
111- let stopWatcher = noop
112- if ( isRef ( reference ) ) {
113- stopWatcher = watch ( reference , bindDatabaseRef , { immediate : true } )
114- } else {
115- bindDatabaseRef ( )
116- }
117-
118- // only add the first promise to the pending ones
119- if ( initialSourceValue ) {
120- removePendingPromise = addPendingPromise ( promise . value , initialSourceValue )
121- }
122-
123- if ( hasCurrentScope ) {
124- onScopeDispose ( stop )
125-
126- // wait for the promise on SSR
127- if ( getCurrentInstance ( ) ) {
128- onServerPrefetch ( ( ) => promise . value )
129- }
130- }
131-
132- function stop ( reset : ResetOption = options . reset ) {
133- stopWatcher ( )
134- removePendingPromise ( )
135- unbind ( reset )
136- }
137-
138- return Object . defineProperties ( data as _RefDatabase < unknown > , {
139- // allow destructuring without interfering with the ref itself
140- data : { get : ( ) => data } ,
141- error : { get : ( ) => error } ,
142- pending : { get : ( ) => pending } ,
143- promise : { get : ( ) => promise } ,
144- stop : { get : ( ) => stop } ,
145- } )
146- }
147-
148- export function internalUnbind (
149- key : string ,
150- unbinds : Record < string , UnbindWithReset > | undefined ,
151- reset ?: ResetOption
152- ) {
153- if ( unbinds && unbinds [ key ] ) {
154- unbinds [ key ] ( reset )
155- delete unbinds [ key ]
156- }
157- }
14+ export { globalDatabaseOptions } from './bind'
15+ export type { UseDatabaseRefOptions }
15816
15917export type UseListOptions = UseDatabaseRefOptions
160- export type UseObjectOptions = UseDatabaseRefOptions
16118
16219/**
16320 * Creates a reactive variable connected to the database as an array. Each element in the array will contain an `id`
@@ -178,6 +35,8 @@ export function useList<T = unknown>(
17835 } ) as _RefDatabase < VueDatabaseQueryData < T > >
17936}
18037
38+ export type UseObjectOptions = UseDatabaseRefOptions
39+
18140/**
18241 * Creates a reactive variable connected to the database as an object. If the reference is a primitive, it will be
18342 * converted to an object containing a `$value` property with the primitive value and an `id` property with the
@@ -197,9 +56,6 @@ export function useObject<T = unknown>(
19756 } ) as _RefDatabase < VueDatabaseDocumentData < T > >
19857}
19958
200- export const unbind = ( target : Ref , reset ?: ResetOption ) =>
201- internalUnbind ( '' , databaseUnbinds . get ( target ) , reset )
202-
20359/**
20460 * Retrieves the Database instance.
20561 *
0 commit comments