@@ -2,17 +2,16 @@ import { writable } from 'svelte/store';
22import { assertApp } from './helpers' ;
33import { startTrace , stopTrace } from './perf' ;
44
5-
6- // Note. Doc without data flows from undefined -> null,
7-
85// Svelte Store for Firestore Document
96export function docStore ( path , opts ) {
107 const firestore = assertApp ( 'firestore' ) ;
118
12- const { startWith, log, traceId, maxWait } = { maxWait : 10000 , ...opts } ;
13-
9+ const { startWith, log, traceId, maxWait, once } = { maxWait : 10000 , ...opts } ;
1410
11+ // Create the Firestore Reference
1512 const ref = typeof path === 'string' ? firestore . doc ( path ) : path ;
13+
14+ // Performance trace
1615 const trace = traceId && startTrace ( traceId ) ;
1716
1817 // Internal state
@@ -38,18 +37,27 @@ export function docStore(path, opts) {
3837 // Timout for fallback slot
3938 _waitForIt = maxWait && setTimeout ( ( ) => _loading && next ( null , new Error ( `Timeout at ${ maxWait } . Using fallback slot.` ) ) , maxWait )
4039
40+ // Realtime firebase subscription
4141 _teardown = ref . onSnapshot (
4242 snapshot => {
4343 const data = snapshot . data ( ) || startWith || null ;
44+
45+ // Optional logging
4446 if ( log ) {
4547 console . groupCollapsed ( `Doc ${ snapshot . id } ` ) ;
4648 console . log ( `Path: ${ ref . path } ` ) ;
4749 console . log ( 'Snapshot:' , snapshot ) ;
4850 console . groupEnd ( ) ;
4951 }
5052
53+ // Emit next value
5154 next ( data ) ;
55+
56+ // Teardown after first emitted value if once
57+ once && _teardown ( ) ;
5258 } ,
59+
60+ // Handle firebase thrown errors
5361 error => {
5462 console . error ( error ) ;
5563 next ( null , error ) ;
@@ -60,6 +68,7 @@ export function docStore(path, opts) {
6068 return ( ) => _teardown ( ) ;
6169 } ;
6270
71+ // Svelte store
6372 const store = writable ( startWith , start ) ;
6473
6574 const { subscribe, set } = store ;
@@ -81,10 +90,10 @@ export function docStore(path, opts) {
8190export function collectionStore ( path , queryFn , opts ) {
8291 const firestore = assertApp ( 'firestore' ) ;
8392
84- const { startWith, log, traceId, idField , refField , maxWait } = {
93+ const { startWith, log, traceId, maxWait , once , idField , refField } = {
8594 idField : 'id' ,
8695 refField : 'ref' ,
87- maxWait : 10000 ,
96+ maxWait : 10000 ,
8897 ...opts
8998 } ;
9099
@@ -94,13 +103,21 @@ export function collectionStore(path, queryFn, opts) {
94103
95104 let _loading = typeof startWith !== undefined ;
96105 let _error = null ;
106+ let _meta = { } ;
97107 let _teardown ;
98108 let _waitForIt ;
99109
110+ // Metadata for result
111+ const calcMeta = ( val ) => {
112+ return val && val . length ?
113+ { first : val [ 0 ] , last : val [ val . length - 1 ] } : { }
114+ }
115+
100116 const next = ( val , err ) => {
101117 _loading = false ;
102118 _waitForIt && clearTimeout ( _waitForIt ) ;
103119 _error = err || null ;
120+ _meta = calcMeta ( val ) ;
104121 set ( val ) ;
105122 trace && stopTrace ( trace ) ;
106123 } ;
@@ -127,6 +144,7 @@ export function collectionStore(path, queryFn, opts) {
127144 console . groupEnd ( ) ;
128145 }
129146 next ( data ) ;
147+ once && _teardown ( ) ;
130148 } ,
131149
132150 error => {
@@ -150,6 +168,9 @@ export function collectionStore(path, queryFn, opts) {
150168 } ,
151169 get error ( ) {
152170 return _error ;
171+ } ,
172+ get meta ( ) {
173+ return _meta ;
153174 }
154175 } ;
155176}
0 commit comments