svelte-firekit 0.0.25 → 0.1.1

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.
Files changed (95) hide show
  1. package/README.md +445 -213
  2. package/dist/components/Collection.svelte +150 -0
  3. package/dist/components/Collection.svelte.d.ts +27 -0
  4. package/dist/components/Ddoc.svelte +131 -0
  5. package/dist/components/Ddoc.svelte.d.ts +28 -0
  6. package/dist/components/Node.svelte +97 -0
  7. package/dist/components/Node.svelte.d.ts +23 -0
  8. package/dist/components/auth-guard.svelte +89 -0
  9. package/dist/components/auth-guard.svelte.d.ts +26 -0
  10. package/dist/components/custom-guard.svelte +122 -0
  11. package/dist/components/custom-guard.svelte.d.ts +31 -0
  12. package/dist/components/download-url.svelte +92 -0
  13. package/dist/components/download-url.svelte.d.ts +19 -0
  14. package/dist/components/firebase-app.svelte +30 -0
  15. package/dist/components/firebase-app.svelte.d.ts +7 -0
  16. package/dist/components/node-list.svelte +102 -0
  17. package/dist/components/node-list.svelte.d.ts +27 -0
  18. package/dist/components/signed-in.svelte +42 -0
  19. package/dist/components/signed-in.svelte.d.ts +11 -0
  20. package/dist/components/signed-out.svelte +42 -0
  21. package/dist/components/signed-out.svelte.d.ts +11 -0
  22. package/dist/components/storage-list.svelte +97 -0
  23. package/dist/components/storage-list.svelte.d.ts +26 -0
  24. package/dist/components/upload-task.svelte +108 -0
  25. package/dist/components/upload-task.svelte.d.ts +24 -0
  26. package/dist/config.js +17 -39
  27. package/dist/firebase.d.ts +43 -21
  28. package/dist/firebase.js +121 -35
  29. package/dist/index.d.ts +21 -13
  30. package/dist/index.js +27 -15
  31. package/dist/services/auth.d.ts +397 -0
  32. package/dist/services/auth.js +882 -0
  33. package/dist/services/collection.svelte.d.ts +286 -0
  34. package/dist/services/collection.svelte.js +871 -0
  35. package/dist/services/document.svelte.d.ts +288 -0
  36. package/dist/services/document.svelte.js +555 -0
  37. package/dist/services/mutations.d.ts +336 -0
  38. package/dist/services/mutations.js +1079 -0
  39. package/dist/services/presence.svelte.d.ts +141 -0
  40. package/dist/services/presence.svelte.js +727 -0
  41. package/dist/{realtime → services}/realtime.svelte.d.ts +3 -1
  42. package/dist/{realtime → services}/realtime.svelte.js +13 -7
  43. package/dist/services/storage.svelte.d.ts +257 -0
  44. package/dist/services/storage.svelte.js +374 -0
  45. package/dist/services/user.svelte.d.ts +296 -0
  46. package/dist/services/user.svelte.js +609 -0
  47. package/dist/types/auth.d.ts +158 -0
  48. package/dist/types/auth.js +106 -0
  49. package/dist/types/collection.d.ts +360 -0
  50. package/dist/types/collection.js +167 -0
  51. package/dist/types/document.d.ts +342 -0
  52. package/dist/types/document.js +148 -0
  53. package/dist/types/firebase.d.ts +44 -0
  54. package/dist/types/firebase.js +33 -0
  55. package/dist/types/index.d.ts +6 -0
  56. package/dist/types/index.js +4 -0
  57. package/dist/types/mutations.d.ts +387 -0
  58. package/dist/types/mutations.js +205 -0
  59. package/dist/types/presence.d.ts +282 -0
  60. package/dist/types/presence.js +80 -0
  61. package/dist/utils/errors.d.ts +21 -0
  62. package/dist/utils/errors.js +35 -0
  63. package/dist/utils/firestore.d.ts +9 -0
  64. package/dist/utils/firestore.js +33 -0
  65. package/dist/utils/index.d.ts +4 -0
  66. package/dist/utils/index.js +8 -0
  67. package/dist/utils/providers.d.ts +16 -0
  68. package/dist/utils/providers.js +30 -0
  69. package/dist/utils/user.d.ts +8 -0
  70. package/dist/utils/user.js +29 -0
  71. package/package.json +64 -64
  72. package/dist/auth/auth.d.ts +0 -117
  73. package/dist/auth/auth.js +0 -194
  74. package/dist/auth/presence.svelte.d.ts +0 -139
  75. package/dist/auth/presence.svelte.js +0 -373
  76. package/dist/auth/user.svelte.d.ts +0 -112
  77. package/dist/auth/user.svelte.js +0 -155
  78. package/dist/firestore/awaitable-doc.svelte.d.ts +0 -141
  79. package/dist/firestore/awaitable-doc.svelte.js +0 -183
  80. package/dist/firestore/batch-mutations.svelte.d.ts +0 -140
  81. package/dist/firestore/batch-mutations.svelte.js +0 -218
  82. package/dist/firestore/collection-group.svelte.d.ts +0 -78
  83. package/dist/firestore/collection-group.svelte.js +0 -120
  84. package/dist/firestore/collection.svelte.d.ts +0 -96
  85. package/dist/firestore/collection.svelte.js +0 -137
  86. package/dist/firestore/doc.svelte.d.ts +0 -90
  87. package/dist/firestore/doc.svelte.js +0 -131
  88. package/dist/firestore/document-mutations.svelte.d.ts +0 -164
  89. package/dist/firestore/document-mutations.svelte.js +0 -273
  90. package/dist/storage/download-url.svelte.d.ts +0 -83
  91. package/dist/storage/download-url.svelte.js +0 -114
  92. package/dist/storage/storage-list.svelte.d.ts +0 -89
  93. package/dist/storage/storage-list.svelte.js +0 -123
  94. package/dist/storage/upload-task.svelte.d.ts +0 -94
  95. package/dist/storage/upload-task.svelte.js +0 -138
@@ -0,0 +1,609 @@
1
+ /**
2
+ * @fileoverview FirekitUser Store - Reactive user state management using Svelte 5 runes
3
+ * @module FirekitUserStore
4
+ * @version 1.0.0
5
+ */
6
+ import { onAuthStateChanged, updateProfile, updateEmail, updatePassword, reload, sendEmailVerification, getIdToken } from 'firebase/auth';
7
+ import { doc, setDoc, getDoc, serverTimestamp } from 'firebase/firestore';
8
+ import { firebaseService } from '../firebase.js';
9
+ import { FirekitAuthError, AuthErrorCode } from '../types/auth.js';
10
+ import { mapFirebaseUserToProfile, updateUserInFirestore, createAuthError, validateCurrentUser } from '../utils/index.js';
11
+ /**
12
+ * Reactive user store using Svelte 5 runes for state management.
13
+ * Provides real-time authentication state and user profile management.
14
+ *
15
+ * @class FirekitUserStore
16
+ * @example
17
+ * ```typescript
18
+ * import { firekitUser } from 'svelte-firekit';
19
+ *
20
+ * // Access reactive state
21
+ * $: if (firekitUser.isAuthenticated) {
22
+ * console.log("User:", firekitUser.user);
23
+ * }
24
+ *
25
+ * // Update profile
26
+ * await firekitUser.updateDisplayName("John Doe");
27
+ *
28
+ * // Get extended user data
29
+ * const userData = await firekitUser.getExtendedUserData();
30
+ * ```
31
+ */
32
+ class FirekitUserStore {
33
+ static instance;
34
+ auth = null;
35
+ firestore = null;
36
+ _servicesInitialized = false;
37
+ // ========================================
38
+ // REACTIVE STATE (Svelte 5 Runes)
39
+ // ========================================
40
+ /** Current user profile state */
41
+ _user = $state(null);
42
+ /** Loading state indicator */
43
+ _loading = $state(true);
44
+ /** Authentication initialization state */
45
+ _initialized = $state(false);
46
+ /** Current error state */
47
+ _error = $state(null);
48
+ // ========================================
49
+ // DERIVED STATE
50
+ // ========================================
51
+ /** Derived: Whether user is authenticated (not anonymous) */
52
+ _isAuthenticated = $derived(this._user !== null && !this._user.isAnonymous);
53
+ /** Derived: Whether user is anonymous */
54
+ _isAnonymous = $derived(this._user?.isAnonymous ?? false);
55
+ /** Derived: Whether user's email is verified */
56
+ _isEmailVerified = $derived(this._user?.emailVerified ?? false);
57
+ /** Derived: User's primary email address */
58
+ _userEmail = $derived(this._user?.email ?? null);
59
+ /** Derived: User's display name */
60
+ _userDisplayName = $derived(this._user?.displayName ?? null);
61
+ /** Derived: User's photo URL */
62
+ _userPhotoURL = $derived(this._user?.photoURL ?? null);
63
+ /** Derived: User's unique ID */
64
+ _userId = $derived(this._user?.uid ?? null);
65
+ /** Derived: User's phone number */
66
+ _userPhoneNumber = $derived(this._user?.phoneNumber ?? null);
67
+ constructor() {
68
+ // Don't initialize Firebase services in constructor
69
+ // They will be initialized lazily when needed
70
+ }
71
+ /**
72
+ * Gets singleton instance of FirekitUserStore
73
+ * @returns {FirekitUserStore} The FirekitUserStore instance
74
+ */
75
+ static getInstance() {
76
+ if (!FirekitUserStore.instance) {
77
+ FirekitUserStore.instance = new FirekitUserStore();
78
+ }
79
+ return FirekitUserStore.instance;
80
+ }
81
+ /**
82
+ * Initializes Firebase services and auth state listener
83
+ * @private
84
+ */
85
+ initializeServices() {
86
+ if (this._servicesInitialized)
87
+ return;
88
+ try {
89
+ this.auth = firebaseService.getAuthInstance();
90
+ this.firestore = firebaseService.getDbInstance();
91
+ this._servicesInitialized = true;
92
+ this.initializeAuthStateListener();
93
+ }
94
+ catch (error) {
95
+ console.error('Failed to initialize Firebase services:', error);
96
+ this._error = error instanceof Error ? error : new Error(String(error));
97
+ this._loading = false;
98
+ this._initialized = true;
99
+ }
100
+ }
101
+ /**
102
+ * Initializes the authentication state listener
103
+ * @private
104
+ */
105
+ initializeAuthStateListener() {
106
+ if (!this.auth) {
107
+ console.error('Auth instance not available');
108
+ return;
109
+ }
110
+ onAuthStateChanged(this.auth, (firebaseUser) => {
111
+ this._user = firebaseUser ? this.mapFirebaseUserToProfile(firebaseUser) : null;
112
+ this._loading = false;
113
+ this._initialized = true;
114
+ this._error = null;
115
+ }, (error) => {
116
+ console.error('Auth state change error:', error);
117
+ this._error = error;
118
+ this._loading = false;
119
+ this._initialized = true;
120
+ });
121
+ }
122
+ /**
123
+ * Maps Firebase User to UserProfile interface
124
+ * @private
125
+ */
126
+ mapFirebaseUserToProfile(user) {
127
+ return mapFirebaseUserToProfile(user);
128
+ }
129
+ /**
130
+ * Updates user data in Firestore
131
+ * @private
132
+ */
133
+ async updateUserInFirestore(user) {
134
+ if (!this.firestore) {
135
+ throw new Error('Firestore instance not available');
136
+ }
137
+ await updateUserInFirestore(this.firestore, user);
138
+ }
139
+ // ========================================
140
+ // PUBLIC GETTERS (Reactive State)
141
+ // ========================================
142
+ /** Current user profile */
143
+ get user() {
144
+ this.initializeServices();
145
+ return this._user;
146
+ }
147
+ /** Current loading state */
148
+ get loading() {
149
+ this.initializeServices();
150
+ return this._loading;
151
+ }
152
+ /** Whether auth has been initialized */
153
+ get initialized() {
154
+ this.initializeServices();
155
+ return this._initialized;
156
+ }
157
+ /** Current error state */
158
+ get error() {
159
+ this.initializeServices();
160
+ return this._error;
161
+ }
162
+ /** Whether user is authenticated (not anonymous) */
163
+ get isAuthenticated() {
164
+ this.initializeServices();
165
+ return this._isAuthenticated;
166
+ }
167
+ /** Whether user is anonymous */
168
+ get isAnonymous() {
169
+ this.initializeServices();
170
+ return this._isAnonymous;
171
+ }
172
+ /** Whether user's email is verified */
173
+ get isEmailVerified() {
174
+ this.initializeServices();
175
+ return this._isEmailVerified;
176
+ }
177
+ /** User's email address */
178
+ get email() {
179
+ this.initializeServices();
180
+ return this._userEmail;
181
+ }
182
+ /** User's display name */
183
+ get displayName() {
184
+ this.initializeServices();
185
+ return this._userDisplayName;
186
+ }
187
+ /** User's photo URL */
188
+ get photoURL() {
189
+ this.initializeServices();
190
+ return this._userPhotoURL;
191
+ }
192
+ /** User's unique ID */
193
+ get uid() {
194
+ this.initializeServices();
195
+ return this._userId;
196
+ }
197
+ /** User's phone number */
198
+ get phoneNumber() {
199
+ this.initializeServices();
200
+ return this._userPhoneNumber;
201
+ }
202
+ // ========================================
203
+ // PROFILE UPDATE METHODS
204
+ // ========================================
205
+ /**
206
+ * Updates user's display name
207
+ * @param {string} displayName New display name
208
+ * @returns {Promise<void>} Promise that resolves when update completes
209
+ * @throws {FirekitAuthError} If update fails
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * await firekitUser.updateDisplayName("John Doe");
214
+ * ```
215
+ */
216
+ async updateDisplayName(displayName) {
217
+ this.initializeServices();
218
+ if (!this.auth) {
219
+ throw new Error('Auth instance not available');
220
+ }
221
+ const currentUser = validateCurrentUser(this.auth);
222
+ try {
223
+ this._loading = true;
224
+ await updateProfile(currentUser, { displayName });
225
+ await this.updateUserInFirestore(currentUser);
226
+ // Update local state
227
+ if (this._user) {
228
+ this._user = { ...this._user, displayName };
229
+ }
230
+ }
231
+ catch (error) {
232
+ this._error = error;
233
+ throw createAuthError(error, 'update display name');
234
+ }
235
+ finally {
236
+ this._loading = false;
237
+ }
238
+ }
239
+ /**
240
+ * Updates user's photo URL
241
+ * @param {string} photoURL New photo URL
242
+ * @returns {Promise<void>} Promise that resolves when update completes
243
+ * @throws {FirekitAuthError} If update fails
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * await firekitUser.updatePhotoURL("https://example.com/photo.jpg");
248
+ * ```
249
+ */
250
+ async updatePhotoURL(photoURL) {
251
+ this.initializeServices();
252
+ if (!this.auth) {
253
+ throw new Error('Auth instance not available');
254
+ }
255
+ const currentUser = validateCurrentUser(this.auth);
256
+ try {
257
+ this._loading = true;
258
+ await updateProfile(currentUser, { photoURL });
259
+ await this.updateUserInFirestore(currentUser);
260
+ // Update local state
261
+ if (this._user) {
262
+ this._user = { ...this._user, photoURL };
263
+ }
264
+ }
265
+ catch (error) {
266
+ this._error = error;
267
+ throw createAuthError(error, 'update photo URL');
268
+ }
269
+ finally {
270
+ this._loading = false;
271
+ }
272
+ }
273
+ /**
274
+ * Updates user's profile data
275
+ * @param {UserProfileUpdateData} profileData Profile data to update
276
+ * @returns {Promise<void>} Promise that resolves when update completes
277
+ * @throws {FirekitAuthError} If update fails
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * await firekitUser.updateProfile({
282
+ * displayName: "John Smith",
283
+ * photoURL: "https://example.com/new-photo.jpg"
284
+ * });
285
+ * ```
286
+ */
287
+ async updateProfile(profileData) {
288
+ this.initializeServices();
289
+ if (!this.auth) {
290
+ throw new Error('Auth instance not available');
291
+ }
292
+ const currentUser = validateCurrentUser(this.auth);
293
+ try {
294
+ this._loading = true;
295
+ await updateProfile(currentUser, profileData);
296
+ await this.updateUserInFirestore(currentUser);
297
+ // Update local state
298
+ if (this._user) {
299
+ this._user = {
300
+ ...this._user,
301
+ displayName: profileData.displayName ?? this._user.displayName,
302
+ photoURL: profileData.photoURL ?? this._user.photoURL
303
+ };
304
+ }
305
+ }
306
+ catch (error) {
307
+ this._error = error;
308
+ throw createAuthError(error, 'update profile');
309
+ }
310
+ finally {
311
+ this._loading = false;
312
+ }
313
+ }
314
+ /**
315
+ * Updates user's email address
316
+ * @param {string} newEmail New email address
317
+ * @returns {Promise<void>} Promise that resolves when update completes
318
+ * @throws {FirekitAuthError} If update fails
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * await firekitUser.updateEmail("newemail@example.com");
323
+ * ```
324
+ */
325
+ async updateEmail(newEmail) {
326
+ this.initializeServices();
327
+ if (!this.auth) {
328
+ throw new Error('Auth instance not available');
329
+ }
330
+ const currentUser = validateCurrentUser(this.auth);
331
+ try {
332
+ this._loading = true;
333
+ await updateEmail(currentUser, newEmail);
334
+ await this.updateUserInFirestore(currentUser);
335
+ // Update local state
336
+ if (this._user) {
337
+ this._user = { ...this._user, email: newEmail, emailVerified: false };
338
+ }
339
+ }
340
+ catch (error) {
341
+ this._error = error;
342
+ throw createAuthError(error, 'update email');
343
+ }
344
+ finally {
345
+ this._loading = false;
346
+ }
347
+ }
348
+ /**
349
+ * Updates user's password
350
+ * @param {string} newPassword New password
351
+ * @returns {Promise<void>} Promise that resolves when update completes
352
+ * @throws {FirekitAuthError} If update fails
353
+ *
354
+ * @example
355
+ * ```typescript
356
+ * await firekitUser.updatePassword("newSecurePassword123");
357
+ * ```
358
+ */
359
+ async updatePassword(newPassword) {
360
+ this.initializeServices();
361
+ if (!this.auth) {
362
+ throw new Error('Auth instance not available');
363
+ }
364
+ const currentUser = validateCurrentUser(this.auth);
365
+ try {
366
+ this._loading = true;
367
+ await updatePassword(currentUser, newPassword);
368
+ }
369
+ catch (error) {
370
+ this._error = error;
371
+ throw createAuthError(error, 'update password');
372
+ }
373
+ finally {
374
+ this._loading = false;
375
+ }
376
+ }
377
+ // ========================================
378
+ // EMAIL VERIFICATION METHODS
379
+ // ========================================
380
+ /**
381
+ * Sends email verification to current user
382
+ * @returns {Promise<void>} Promise that resolves when verification email is sent
383
+ * @throws {FirekitAuthError} If sending fails
384
+ *
385
+ * @example
386
+ * ```typescript
387
+ * await firekitUser.sendEmailVerification();
388
+ * ```
389
+ */
390
+ async sendEmailVerification() {
391
+ this.initializeServices();
392
+ if (!this.auth) {
393
+ throw new Error('Auth instance not available');
394
+ }
395
+ const currentUser = validateCurrentUser(this.auth);
396
+ try {
397
+ await sendEmailVerification(currentUser);
398
+ }
399
+ catch (error) {
400
+ this._error = error;
401
+ throw createAuthError(error, 'send email verification');
402
+ }
403
+ }
404
+ /**
405
+ * Reloads user to get updated email verification status
406
+ * @returns {Promise<void>} Promise that resolves when user is reloaded
407
+ * @throws {FirekitAuthError} If reload fails
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * await firekitUser.reloadUser();
412
+ * ```
413
+ */
414
+ async reloadUser() {
415
+ this.initializeServices();
416
+ if (!this.auth) {
417
+ throw new Error('Auth instance not available');
418
+ }
419
+ const currentUser = validateCurrentUser(this.auth);
420
+ try {
421
+ this._loading = true;
422
+ await reload(currentUser);
423
+ await this.updateUserInFirestore(currentUser);
424
+ // Update local state with reloaded data
425
+ this._user = this.mapFirebaseUserToProfile(currentUser);
426
+ }
427
+ catch (error) {
428
+ this._error = error;
429
+ throw createAuthError(error, 'reload user');
430
+ }
431
+ finally {
432
+ this._loading = false;
433
+ }
434
+ }
435
+ // ========================================
436
+ // TOKEN METHODS
437
+ // ========================================
438
+ /**
439
+ * Gets the current user's ID token
440
+ * @param {boolean} [forceRefresh=false] Whether to force token refresh
441
+ * @returns {Promise<string>} Promise resolving to ID token
442
+ * @throws {FirekitAuthError} If getting token fails
443
+ *
444
+ * @example
445
+ * ```typescript
446
+ * const token = await firekitUser.getIdToken();
447
+ * ```
448
+ */
449
+ async getIdToken(forceRefresh = false) {
450
+ this.initializeServices();
451
+ if (!this.auth) {
452
+ throw new Error('Auth instance not available');
453
+ }
454
+ const currentUser = validateCurrentUser(this.auth);
455
+ try {
456
+ return await getIdToken(currentUser, forceRefresh);
457
+ }
458
+ catch (error) {
459
+ this._error = error;
460
+ throw createAuthError(error, 'get ID token');
461
+ }
462
+ }
463
+ // ========================================
464
+ // FIRESTORE EXTENDED DATA METHODS
465
+ // ========================================
466
+ /**
467
+ * Gets extended user data from Firestore
468
+ * @returns {Promise<ExtendedUserData | null>} Promise resolving to extended user data
469
+ *
470
+ * @example
471
+ * ```typescript
472
+ * const userData = await firekitUser.getExtendedUserData();
473
+ * console.log(userData?.preferences);
474
+ * ```
475
+ */
476
+ async getExtendedUserData() {
477
+ this.initializeServices();
478
+ if (!this._user?.uid || !this.firestore) {
479
+ return null;
480
+ }
481
+ try {
482
+ const userRef = doc(this.firestore, 'users', this._user.uid);
483
+ const userDoc = await getDoc(userRef);
484
+ if (userDoc.exists()) {
485
+ return userDoc.data();
486
+ }
487
+ return null;
488
+ }
489
+ catch (error) {
490
+ console.error('Failed to get extended user data:', error);
491
+ this._error = error;
492
+ return null;
493
+ }
494
+ }
495
+ /**
496
+ * Updates extended user data in Firestore
497
+ * @param {Partial<ExtendedUserData>} data Data to update
498
+ * @returns {Promise<void>} Promise that resolves when update completes
499
+ *
500
+ * @example
501
+ * ```typescript
502
+ * await firekitUser.updateExtendedUserData({
503
+ * preferences: { theme: 'dark', language: 'en' },
504
+ * settings: { notifications: true }
505
+ * });
506
+ * ```
507
+ */
508
+ async updateExtendedUserData(data) {
509
+ this.initializeServices();
510
+ if (!this._user?.uid) {
511
+ throw new FirekitAuthError(AuthErrorCode.USER_NOT_FOUND, 'No authenticated user found.');
512
+ }
513
+ if (!this.firestore) {
514
+ throw new Error('Firestore instance not available');
515
+ }
516
+ try {
517
+ const userRef = doc(this.firestore, 'users', this._user.uid);
518
+ await setDoc(userRef, {
519
+ ...data,
520
+ updatedAt: serverTimestamp()
521
+ }, { merge: true });
522
+ }
523
+ catch (error) {
524
+ this._error = error;
525
+ throw createAuthError(error, 'update user data');
526
+ }
527
+ }
528
+ // ========================================
529
+ // UTILITY METHODS
530
+ // ========================================
531
+ /**
532
+ * Waits for authentication to initialize
533
+ * @returns {Promise<UserProfile | null>} Promise that resolves when auth is initialized
534
+ *
535
+ * @example
536
+ * ```typescript
537
+ * const user = await firekitUser.waitForAuth();
538
+ * if (user) {
539
+ * console.log("User is authenticated");
540
+ * }
541
+ * ```
542
+ */
543
+ async waitForAuth() {
544
+ this.initializeServices();
545
+ return new Promise((resolve) => {
546
+ if (this._initialized) {
547
+ resolve(this._user);
548
+ return;
549
+ }
550
+ // Create a one-time watcher
551
+ const checkInitialized = () => {
552
+ if (this._initialized) {
553
+ resolve(this._user);
554
+ }
555
+ else {
556
+ // Check again in next tick
557
+ setTimeout(checkInitialized, 10);
558
+ }
559
+ };
560
+ checkInitialized();
561
+ });
562
+ }
563
+ /**
564
+ * Clears any error state
565
+ */
566
+ clearError() {
567
+ this._error = null;
568
+ }
569
+ /**
570
+ * Manually sets loading state (use with caution)
571
+ * @param {boolean} loading Loading state
572
+ */
573
+ setLoading(loading) {
574
+ this._loading = loading;
575
+ }
576
+ /**
577
+ * Resets the store to initial state
578
+ */
579
+ reset() {
580
+ this._user = null;
581
+ this._loading = true;
582
+ this._initialized = false;
583
+ this._error = null;
584
+ this._servicesInitialized = false;
585
+ this.auth = null;
586
+ this.firestore = null;
587
+ }
588
+ }
589
+ /**
590
+ * Pre-initialized singleton instance of FirekitUserStore.
591
+ * Provides reactive user state management for Svelte applications.
592
+ *
593
+ * @example
594
+ * ```typescript
595
+ * import { firekitUser } from 'svelte-firekit';
596
+ *
597
+ * // In a Svelte component
598
+ * $: if (firekitUser.isAuthenticated) {
599
+ * console.log("Welcome:", firekitUser.displayName);
600
+ * }
601
+ *
602
+ * // Update profile
603
+ * await firekitUser.updateDisplayName("John Doe");
604
+ *
605
+ * // Get extended data
606
+ * const userData = await firekitUser.getExtendedUserData();
607
+ * ```
608
+ */
609
+ export const firekitUser = FirekitUserStore.getInstance();