svelte-firekit 0.1.3 → 0.1.5

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.
@@ -57,7 +57,7 @@
57
57
  count: startWith?.length ?? 0
58
58
  });
59
59
 
60
- // Subscribe to collection changes only if in browser and collection service exists
60
+ // Initialize Firestore and collection service
61
61
  $effect(() => {
62
62
  if (!browser) {
63
63
  collectionState = {
@@ -69,7 +69,7 @@
69
69
  return;
70
70
  }
71
71
 
72
- // Initialize Firestore and collection service
72
+ // Initialize Firestore
73
73
  firestore = firebaseService.getDbInstance();
74
74
  if (!firestore) {
75
75
  collectionState = {
@@ -86,18 +86,8 @@
86
86
  typeof ref === 'string' ? collection(firestore, ref) : (ref as CollectionReference | Query);
87
87
 
88
88
  // Create collection service
89
- collectionService = firekitCollection(
90
- typeof ref === 'string' ? ref : (ref as CollectionReference).path,
91
- queryConstraints
92
- );
93
-
94
- // Update state based on collection service state
95
- collectionState = {
96
- loading: collectionService.loading,
97
- data: collectionService.data,
98
- error: collectionService.error,
99
- count: collectionService.size
100
- };
89
+ const path = typeof ref === 'string' ? ref : (ref as CollectionReference).path;
90
+ collectionService = firekitCollection(path, queryConstraints);
101
91
 
102
92
  // Set up event listener for real-time updates
103
93
  const unsubscribe = collectionService.addEventListener((event) => {
@@ -128,6 +118,14 @@
128
118
  }
129
119
  });
130
120
 
121
+ // Set initial state from service
122
+ collectionState = {
123
+ loading: collectionService.loading,
124
+ data: collectionService.data,
125
+ error: collectionService.error,
126
+ count: collectionService.size
127
+ };
128
+
131
129
  return () => {
132
130
  unsubscribe();
133
131
  collectionService?.dispose();
@@ -45,48 +45,21 @@
45
45
  let docRef: DocumentReference | null = $state(null);
46
46
  let documentService: any = $state(null);
47
47
 
48
- // Reactive document state
49
- let componentState = $state({
50
- loading: true,
51
- data: null as DocumentData | null,
52
- error: null as Error | null,
53
- exists: false
54
- });
55
-
56
- // Initialize in browser environment
48
+ // Initialize document service
57
49
  $effect(() => {
58
50
  if (!browser) return;
59
51
 
60
52
  firestore = firebaseService.getDbInstance();
61
- if (!firestore) {
62
- throw new Error('Firestore instance not available');
63
- }
53
+ if (!firestore) return;
64
54
 
65
55
  // Create document reference if path string is provided
66
56
  docRef = typeof ref === 'string' ? doc(firestore, ref) : ref;
67
57
 
68
58
  // Create document service
69
59
  documentService = firekitDoc(docRef.path, startWith ?? undefined, options);
70
- });
71
-
72
- // Subscribe to document changes only if in browser and document service exists
73
- $effect(() => {
74
- if (!browser || !documentService) {
75
- componentState = {
76
- loading: false,
77
- data: startWith ?? null,
78
- error: null,
79
- exists: !!startWith
80
- };
81
- return;
82
- }
83
60
 
84
- // Update component state based on document service state
85
- componentState = {
86
- loading: documentService.loading,
87
- data: documentService.data,
88
- error: documentService.error,
89
- exists: documentService.exists
61
+ return () => {
62
+ documentService?.dispose();
90
63
  };
91
64
  });
92
65
 
@@ -100,7 +73,25 @@
100
73
 
101
74
  {#if !browser}
102
75
  {@render children(startWith ?? null, null as any, null as any)}
103
- {:else if componentState.loading}
76
+ {:else if !firestore}
77
+ <div class="flex items-center justify-center min-h-screen">
78
+ <div class="text-center">
79
+ <div class="text-red-500 text-lg font-semibold mb-2">Firestore Not Available</div>
80
+ <p class="text-gray-600">Firestore instance is not available.</p>
81
+ </div>
82
+ </div>
83
+ {:else if !documentService}
84
+ {#if loading}
85
+ {@render loading()}
86
+ {:else}
87
+ <div class="flex items-center justify-center min-h-screen">
88
+ <div class="text-center">
89
+ <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto"></div>
90
+ <p class="mt-2 text-gray-600">Initializing document...</p>
91
+ </div>
92
+ </div>
93
+ {/if}
94
+ {:else if documentService.loading}
104
95
  {#if loading}
105
96
  {@render loading()}
106
97
  {:else}
@@ -111,15 +102,15 @@
111
102
  </div>
112
103
  </div>
113
104
  {/if}
114
- {:else if componentState.error}
105
+ {:else if documentService.error}
115
106
  <div class="flex items-center justify-center min-h-screen">
116
107
  <div class="text-center">
117
108
  <div class="text-red-500 text-lg font-semibold mb-2">Error Loading Document</div>
118
- <p class="text-gray-600 mb-4">{componentState.error.message}</p>
119
- {#if documentService?.canRefresh}
109
+ <p class="text-gray-600 mb-4">{documentService.error.message}</p>
110
+ {#if documentService.canRefresh}
120
111
  <button
121
112
  class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
122
- onclick={() => documentService?.refresh()}
113
+ onclick={() => documentService.refresh()}
123
114
  >
124
115
  Retry
125
116
  </button>
@@ -127,5 +118,5 @@
127
118
  </div>
128
119
  </div>
129
120
  {:else}
130
- {@render children(componentState.data ?? null, docRef!, firestore!)}
121
+ {@render children(documentService.data ?? null, docRef!, firestore!)}
131
122
  {/if}
@@ -23,6 +23,6 @@ type $$ComponentProps = {
23
23
  */
24
24
  options?: DocumentOptions;
25
25
  };
26
- declare const Ddoc: import("svelte").Component<$$ComponentProps, {}, "">;
27
- type Ddoc = ReturnType<typeof Ddoc>;
28
- export default Ddoc;
26
+ declare const Doc: import("svelte").Component<$$ComponentProps, {}, "">;
27
+ type Doc = ReturnType<typeof Doc>;
28
+ export default Doc;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { ref, type StorageReference, type UploadTaskSnapshot } from 'firebase/storage';
2
+ import { type UploadTaskSnapshot } from 'firebase/storage';
3
3
  import { firebaseService } from '../firebase.js';
4
4
  import { firekitUploadTask } from '../services/storage.svelte.js';
5
5
  import { browser } from '$app/environment';
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { default as AuthGuard } from './components/auth-guard.svelte';
14
14
  export { default as CustomGuard } from './components/custom-guard.svelte';
15
15
  export { default as SignedIn } from './components/signed-in.svelte';
16
16
  export { default as SignedOut } from './components/signed-out.svelte';
17
- export { default as Doc } from './components/Ddoc.svelte';
17
+ export { default as Doc } from './components/Doc.svelte';
18
18
  export { default as Collection } from './components/Collection.svelte';
19
19
  export { default as Node } from './components/Node.svelte';
20
20
  export { default as NodeList } from './components/node-list.svelte';
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ export { default as AuthGuard } from './components/auth-guard.svelte';
23
23
  export { default as CustomGuard } from './components/custom-guard.svelte';
24
24
  export { default as SignedIn } from './components/signed-in.svelte';
25
25
  export { default as SignedOut } from './components/signed-out.svelte';
26
- export { default as Doc } from './components/Ddoc.svelte';
26
+ export { default as Doc } from './components/Doc.svelte';
27
27
  export { default as Collection } from './components/Collection.svelte';
28
28
  export { default as Node } from './components/Node.svelte';
29
29
  export { default as NodeList } from './components/node-list.svelte';
@@ -43,8 +43,10 @@ class FirekitAuth {
43
43
  stateListeners = new Set();
44
44
  recaptchaVerifiers = new Map();
45
45
  constructor() {
46
- // Don't initialize Firebase services in constructor
47
- // They will be initialized lazily when needed
46
+ if (typeof window !== 'undefined') {
47
+ // Initialize Firebase services immediately like the old working code
48
+ this.initializeServices();
49
+ }
48
50
  }
49
51
  /**
50
52
  * Gets singleton instance of FirekitAuth
@@ -149,7 +151,6 @@ class FirekitAuth {
149
151
  * @returns {AuthState} Current authentication state
150
152
  */
151
153
  getState() {
152
- this.initializeServices();
153
154
  return { ...this.authState };
154
155
  }
155
156
  /**
@@ -157,7 +158,6 @@ class FirekitAuth {
157
158
  * @returns {User | null} Current Firebase user or null
158
159
  */
159
160
  getCurrentUser() {
160
- this.initializeServices();
161
161
  return this.auth?.currentUser ?? null;
162
162
  }
163
163
  /**
@@ -165,7 +165,6 @@ class FirekitAuth {
165
165
  * @returns {UserProfile | null} Current user profile or null
166
166
  */
167
167
  getCurrentUserProfile() {
168
- this.initializeServices();
169
168
  return this.authState.user;
170
169
  }
171
170
  /**
@@ -173,7 +172,6 @@ class FirekitAuth {
173
172
  * @returns {Promise<UserProfile | null>} Promise that resolves when auth is initialized
174
173
  */
175
174
  async waitForAuth() {
176
- this.initializeServices();
177
175
  return new Promise((resolve) => {
178
176
  if (this.authState.initialized) {
179
177
  resolve(this.authState.user);
@@ -193,7 +191,6 @@ class FirekitAuth {
193
191
  * @returns {Function} Unsubscribe function
194
192
  */
195
193
  onAuthStateChanged(callback) {
196
- this.initializeServices();
197
194
  this.stateListeners.add(callback);
198
195
  // Immediately call with current state
199
196
  callback(this.authState);
@@ -222,7 +219,6 @@ class FirekitAuth {
222
219
  * ```
223
220
  */
224
221
  async signInWithEmail(email, password) {
225
- this.initializeServices();
226
222
  if (!this.auth) {
227
223
  throw new Error('Auth instance not available');
228
224
  }
@@ -259,7 +255,6 @@ class FirekitAuth {
259
255
  * ```
260
256
  */
261
257
  async signInWithGoogle() {
262
- this.initializeServices();
263
258
  if (!this.auth) {
264
259
  throw new Error('Auth instance not available');
265
260
  }
@@ -285,7 +280,6 @@ class FirekitAuth {
285
280
  * @throws {FirekitAuthError} If sign-in fails
286
281
  */
287
282
  async signInWithFacebook() {
288
- this.initializeServices();
289
283
  if (!this.auth) {
290
284
  throw new Error('Auth instance not available');
291
285
  }
@@ -311,7 +305,6 @@ class FirekitAuth {
311
305
  * @throws {FirekitAuthError} If sign-in fails
312
306
  */
313
307
  async signInWithApple() {
314
- this.initializeServices();
315
308
  if (!this.auth) {
316
309
  throw new Error('Auth instance not available');
317
310
  }
@@ -343,7 +336,6 @@ class FirekitAuth {
343
336
  * ```
344
337
  */
345
338
  async signInAnonymously() {
346
- this.initializeServices();
347
339
  if (!this.auth) {
348
340
  throw new Error('Auth instance not available');
349
341
  }
@@ -376,7 +368,6 @@ class FirekitAuth {
376
368
  * ```
377
369
  */
378
370
  async signInWithPhoneNumber(phoneNumber, recaptchaContainerId) {
379
- this.initializeServices();
380
371
  if (!this.auth) {
381
372
  throw new Error('Auth instance not available');
382
373
  }
@@ -450,7 +441,6 @@ class FirekitAuth {
450
441
  * ```
451
442
  */
452
443
  async registerWithEmail(email, password, displayName, sendVerification = true) {
453
- this.initializeServices();
454
444
  if (!this.auth) {
455
445
  throw new Error('Auth instance not available');
456
446
  }
@@ -494,7 +484,6 @@ class FirekitAuth {
494
484
  * ```
495
485
  */
496
486
  async sendPasswordReset(email) {
497
- this.initializeServices();
498
487
  if (!this.auth) {
499
488
  throw new Error('Auth instance not available');
500
489
  }
@@ -513,7 +502,6 @@ class FirekitAuth {
513
502
  * @throws {FirekitAuthError} If reset fails
514
503
  */
515
504
  async confirmPasswordReset(code, newPassword) {
516
- this.initializeServices();
517
505
  if (!this.auth) {
518
506
  throw new Error('Auth instance not available');
519
507
  }
@@ -541,7 +529,6 @@ class FirekitAuth {
541
529
  * ```
542
530
  */
543
531
  async updatePassword(newPassword, currentPassword) {
544
- this.initializeServices();
545
532
  if (!this.auth?.currentUser) {
546
533
  return {
547
534
  success: false,
@@ -593,7 +580,6 @@ class FirekitAuth {
593
580
  * ```
594
581
  */
595
582
  async updateUserProfile(profile) {
596
- this.initializeServices();
597
583
  if (!this.auth?.currentUser) {
598
584
  throw new FirekitAuthError('auth/no-current-user', 'No authenticated user found.');
599
585
  }
@@ -617,7 +603,6 @@ class FirekitAuth {
617
603
  * ```
618
604
  */
619
605
  async updateEmail(newEmail) {
620
- this.initializeServices();
621
606
  if (!this.auth?.currentUser) {
622
607
  throw new FirekitAuthError('auth/no-current-user', 'No authenticated user found.');
623
608
  }
@@ -640,7 +625,6 @@ class FirekitAuth {
640
625
  * ```
641
626
  */
642
627
  async sendEmailVerification() {
643
- this.initializeServices();
644
628
  if (!this.auth?.currentUser) {
645
629
  throw new FirekitAuthError('auth/no-current-user', 'No authenticated user found.');
646
630
  }
@@ -662,7 +646,6 @@ class FirekitAuth {
662
646
  * ```
663
647
  */
664
648
  async reloadUser() {
665
- this.initializeServices();
666
649
  if (!this.auth?.currentUser) {
667
650
  throw new FirekitAuthError('auth/no-current-user', 'No authenticated user found.');
668
651
  }
@@ -686,7 +669,6 @@ class FirekitAuth {
686
669
  * ```
687
670
  */
688
671
  async getIdToken(forceRefresh = false) {
689
- this.initializeServices();
690
672
  if (!this.auth?.currentUser) {
691
673
  throw new FirekitAuthError('auth/no-current-user', 'No authenticated user found.');
692
674
  }
@@ -702,7 +684,6 @@ class FirekitAuth {
702
684
  * @private
703
685
  */
704
686
  async reauthenticateUser(currentPassword) {
705
- this.initializeServices();
706
687
  if (!this.auth?.currentUser || !this.auth.currentUser.email) {
707
688
  throw new FirekitAuthError('auth/no-current-user', 'No authenticated user with email found.');
708
689
  }
@@ -730,7 +711,6 @@ class FirekitAuth {
730
711
  * ```
731
712
  */
732
713
  async deleteAccount(currentPassword) {
733
- this.initializeServices();
734
714
  if (!this.auth?.currentUser) {
735
715
  return {
736
716
  success: false,
@@ -779,7 +759,6 @@ class FirekitAuth {
779
759
  * ```
780
760
  */
781
761
  async signOut() {
782
- this.initializeServices();
783
762
  if (!this.auth) {
784
763
  throw new Error('Auth instance not available');
785
764
  }
@@ -801,7 +780,6 @@ class FirekitAuth {
801
780
  * @returns {boolean} True if user is authenticated
802
781
  */
803
782
  isAuthenticated() {
804
- this.initializeServices();
805
783
  return this.authState.user !== null && !this.authState.user.isAnonymous;
806
784
  }
807
785
  /**
@@ -809,7 +787,6 @@ class FirekitAuth {
809
787
  * @returns {boolean} True if user is anonymous
810
788
  */
811
789
  isAnonymous() {
812
- this.initializeServices();
813
790
  return this.authState.user?.isAnonymous ?? false;
814
791
  }
815
792
  /**
@@ -817,7 +794,6 @@ class FirekitAuth {
817
794
  * @returns {boolean} True if email is verified
818
795
  */
819
796
  isEmailVerified() {
820
- this.initializeServices();
821
797
  return this.authState.user?.emailVerified ?? false;
822
798
  }
823
799
  /**
@@ -825,7 +801,6 @@ class FirekitAuth {
825
801
  * @returns {string | null} User's email or null
826
802
  */
827
803
  getUserEmail() {
828
- this.initializeServices();
829
804
  return this.authState.user?.email ?? null;
830
805
  }
831
806
  /**
@@ -833,7 +808,6 @@ class FirekitAuth {
833
808
  * @returns {string | null} User's display name or null
834
809
  */
835
810
  getUserDisplayName() {
836
- this.initializeServices();
837
811
  return this.authState.user?.displayName ?? null;
838
812
  }
839
813
  /**
@@ -841,7 +815,6 @@ class FirekitAuth {
841
815
  * @returns {string | null} User's photo URL or null
842
816
  */
843
817
  getUserPhotoURL() {
844
- this.initializeServices();
845
818
  return this.authState.user?.photoURL ?? null;
846
819
  }
847
820
  /**
@@ -849,7 +822,6 @@ class FirekitAuth {
849
822
  * @returns {string | null} User's UID or null
850
823
  */
851
824
  getUserId() {
852
- this.initializeServices();
853
825
  return this.authState.user?.uid ?? null;
854
826
  }
855
827
  /**
@@ -857,7 +829,6 @@ class FirekitAuth {
857
829
  * @returns {Promise<void>} Promise that resolves when cleanup completes
858
830
  */
859
831
  async cleanup() {
860
- this.initializeServices();
861
832
  // Clear reCAPTCHA verifiers
862
833
  this.recaptchaVerifiers.forEach((verifier) => verifier.clear());
863
834
  this.recaptchaVerifiers.clear();
@@ -65,8 +65,10 @@ class FirekitUserStore {
65
65
  /** Derived: User's phone number */
66
66
  _userPhoneNumber = $derived(this._user?.phoneNumber ?? null);
67
67
  constructor() {
68
- // Don't initialize Firebase services in constructor
69
- // They will be initialized lazily when needed
68
+ if (typeof window !== 'undefined') {
69
+ // Initialize Firebase services immediately like the old working code
70
+ this.initializeServices();
71
+ }
70
72
  }
71
73
  /**
72
74
  * Gets singleton instance of FirekitUserStore
@@ -141,62 +143,50 @@ class FirekitUserStore {
141
143
  // ========================================
142
144
  /** Current user profile */
143
145
  get user() {
144
- this.initializeServices();
145
146
  return this._user;
146
147
  }
147
148
  /** Current loading state */
148
149
  get loading() {
149
- this.initializeServices();
150
150
  return this._loading;
151
151
  }
152
152
  /** Whether auth has been initialized */
153
153
  get initialized() {
154
- this.initializeServices();
155
154
  return this._initialized;
156
155
  }
157
156
  /** Current error state */
158
157
  get error() {
159
- this.initializeServices();
160
158
  return this._error;
161
159
  }
162
160
  /** Whether user is authenticated (not anonymous) */
163
161
  get isAuthenticated() {
164
- this.initializeServices();
165
162
  return this._isAuthenticated;
166
163
  }
167
164
  /** Whether user is anonymous */
168
165
  get isAnonymous() {
169
- this.initializeServices();
170
166
  return this._isAnonymous;
171
167
  }
172
168
  /** Whether user's email is verified */
173
169
  get isEmailVerified() {
174
- this.initializeServices();
175
170
  return this._isEmailVerified;
176
171
  }
177
172
  /** User's email address */
178
173
  get email() {
179
- this.initializeServices();
180
174
  return this._userEmail;
181
175
  }
182
176
  /** User's display name */
183
177
  get displayName() {
184
- this.initializeServices();
185
178
  return this._userDisplayName;
186
179
  }
187
180
  /** User's photo URL */
188
181
  get photoURL() {
189
- this.initializeServices();
190
182
  return this._userPhotoURL;
191
183
  }
192
184
  /** User's unique ID */
193
185
  get uid() {
194
- this.initializeServices();
195
186
  return this._userId;
196
187
  }
197
188
  /** User's phone number */
198
189
  get phoneNumber() {
199
- this.initializeServices();
200
190
  return this._userPhoneNumber;
201
191
  }
202
192
  // ========================================
@@ -214,7 +204,6 @@ class FirekitUserStore {
214
204
  * ```
215
205
  */
216
206
  async updateDisplayName(displayName) {
217
- this.initializeServices();
218
207
  if (!this.auth) {
219
208
  throw new Error('Auth instance not available');
220
209
  }
@@ -248,7 +237,6 @@ class FirekitUserStore {
248
237
  * ```
249
238
  */
250
239
  async updatePhotoURL(photoURL) {
251
- this.initializeServices();
252
240
  if (!this.auth) {
253
241
  throw new Error('Auth instance not available');
254
242
  }
@@ -285,7 +273,6 @@ class FirekitUserStore {
285
273
  * ```
286
274
  */
287
275
  async updateProfile(profileData) {
288
- this.initializeServices();
289
276
  if (!this.auth) {
290
277
  throw new Error('Auth instance not available');
291
278
  }
@@ -323,7 +310,6 @@ class FirekitUserStore {
323
310
  * ```
324
311
  */
325
312
  async updateEmail(newEmail) {
326
- this.initializeServices();
327
313
  if (!this.auth) {
328
314
  throw new Error('Auth instance not available');
329
315
  }
@@ -357,7 +343,6 @@ class FirekitUserStore {
357
343
  * ```
358
344
  */
359
345
  async updatePassword(newPassword) {
360
- this.initializeServices();
361
346
  if (!this.auth) {
362
347
  throw new Error('Auth instance not available');
363
348
  }
@@ -388,7 +373,6 @@ class FirekitUserStore {
388
373
  * ```
389
374
  */
390
375
  async sendEmailVerification() {
391
- this.initializeServices();
392
376
  if (!this.auth) {
393
377
  throw new Error('Auth instance not available');
394
378
  }
@@ -412,7 +396,6 @@ class FirekitUserStore {
412
396
  * ```
413
397
  */
414
398
  async reloadUser() {
415
- this.initializeServices();
416
399
  if (!this.auth) {
417
400
  throw new Error('Auth instance not available');
418
401
  }
@@ -447,7 +430,6 @@ class FirekitUserStore {
447
430
  * ```
448
431
  */
449
432
  async getIdToken(forceRefresh = false) {
450
- this.initializeServices();
451
433
  if (!this.auth) {
452
434
  throw new Error('Auth instance not available');
453
435
  }
@@ -474,7 +456,6 @@ class FirekitUserStore {
474
456
  * ```
475
457
  */
476
458
  async getExtendedUserData() {
477
- this.initializeServices();
478
459
  if (!this._user?.uid || !this.firestore) {
479
460
  return null;
480
461
  }
@@ -506,7 +487,6 @@ class FirekitUserStore {
506
487
  * ```
507
488
  */
508
489
  async updateExtendedUserData(data) {
509
- this.initializeServices();
510
490
  if (!this._user?.uid) {
511
491
  throw new FirekitAuthError(AuthErrorCode.USER_NOT_FOUND, 'No authenticated user found.');
512
492
  }
@@ -541,7 +521,6 @@ class FirekitUserStore {
541
521
  * ```
542
522
  */
543
523
  async waitForAuth() {
544
- this.initializeServices();
545
524
  return new Promise((resolve) => {
546
525
  if (this._initialized) {
547
526
  resolve(this._user);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-firekit",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "vite dev",