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.
- package/README.md +445 -213
- package/dist/components/Collection.svelte +150 -0
- package/dist/components/Collection.svelte.d.ts +27 -0
- package/dist/components/Ddoc.svelte +131 -0
- package/dist/components/Ddoc.svelte.d.ts +28 -0
- package/dist/components/Node.svelte +97 -0
- package/dist/components/Node.svelte.d.ts +23 -0
- package/dist/components/auth-guard.svelte +89 -0
- package/dist/components/auth-guard.svelte.d.ts +26 -0
- package/dist/components/custom-guard.svelte +122 -0
- package/dist/components/custom-guard.svelte.d.ts +31 -0
- package/dist/components/download-url.svelte +92 -0
- package/dist/components/download-url.svelte.d.ts +19 -0
- package/dist/components/firebase-app.svelte +30 -0
- package/dist/components/firebase-app.svelte.d.ts +7 -0
- package/dist/components/node-list.svelte +102 -0
- package/dist/components/node-list.svelte.d.ts +27 -0
- package/dist/components/signed-in.svelte +42 -0
- package/dist/components/signed-in.svelte.d.ts +11 -0
- package/dist/components/signed-out.svelte +42 -0
- package/dist/components/signed-out.svelte.d.ts +11 -0
- package/dist/components/storage-list.svelte +97 -0
- package/dist/components/storage-list.svelte.d.ts +26 -0
- package/dist/components/upload-task.svelte +108 -0
- package/dist/components/upload-task.svelte.d.ts +24 -0
- package/dist/config.js +17 -39
- package/dist/firebase.d.ts +43 -21
- package/dist/firebase.js +121 -35
- package/dist/index.d.ts +21 -13
- package/dist/index.js +27 -15
- package/dist/services/auth.d.ts +397 -0
- package/dist/services/auth.js +882 -0
- package/dist/services/collection.svelte.d.ts +286 -0
- package/dist/services/collection.svelte.js +871 -0
- package/dist/services/document.svelte.d.ts +288 -0
- package/dist/services/document.svelte.js +555 -0
- package/dist/services/mutations.d.ts +336 -0
- package/dist/services/mutations.js +1079 -0
- package/dist/services/presence.svelte.d.ts +141 -0
- package/dist/services/presence.svelte.js +727 -0
- package/dist/{realtime → services}/realtime.svelte.d.ts +3 -1
- package/dist/{realtime → services}/realtime.svelte.js +13 -7
- package/dist/services/storage.svelte.d.ts +257 -0
- package/dist/services/storage.svelte.js +374 -0
- package/dist/services/user.svelte.d.ts +296 -0
- package/dist/services/user.svelte.js +609 -0
- package/dist/types/auth.d.ts +158 -0
- package/dist/types/auth.js +106 -0
- package/dist/types/collection.d.ts +360 -0
- package/dist/types/collection.js +167 -0
- package/dist/types/document.d.ts +342 -0
- package/dist/types/document.js +148 -0
- package/dist/types/firebase.d.ts +44 -0
- package/dist/types/firebase.js +33 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +4 -0
- package/dist/types/mutations.d.ts +387 -0
- package/dist/types/mutations.js +205 -0
- package/dist/types/presence.d.ts +282 -0
- package/dist/types/presence.js +80 -0
- package/dist/utils/errors.d.ts +21 -0
- package/dist/utils/errors.js +35 -0
- package/dist/utils/firestore.d.ts +9 -0
- package/dist/utils/firestore.js +33 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/providers.d.ts +16 -0
- package/dist/utils/providers.js +30 -0
- package/dist/utils/user.d.ts +8 -0
- package/dist/utils/user.js +29 -0
- package/package.json +64 -64
- package/dist/auth/auth.d.ts +0 -117
- package/dist/auth/auth.js +0 -194
- package/dist/auth/presence.svelte.d.ts +0 -139
- package/dist/auth/presence.svelte.js +0 -373
- package/dist/auth/user.svelte.d.ts +0 -112
- package/dist/auth/user.svelte.js +0 -155
- package/dist/firestore/awaitable-doc.svelte.d.ts +0 -141
- package/dist/firestore/awaitable-doc.svelte.js +0 -183
- package/dist/firestore/batch-mutations.svelte.d.ts +0 -140
- package/dist/firestore/batch-mutations.svelte.js +0 -218
- package/dist/firestore/collection-group.svelte.d.ts +0 -78
- package/dist/firestore/collection-group.svelte.js +0 -120
- package/dist/firestore/collection.svelte.d.ts +0 -96
- package/dist/firestore/collection.svelte.js +0 -137
- package/dist/firestore/doc.svelte.d.ts +0 -90
- package/dist/firestore/doc.svelte.js +0 -131
- package/dist/firestore/document-mutations.svelte.d.ts +0 -164
- package/dist/firestore/document-mutations.svelte.js +0 -273
- package/dist/storage/download-url.svelte.d.ts +0 -83
- package/dist/storage/download-url.svelte.js +0 -114
- package/dist/storage/storage-list.svelte.d.ts +0 -89
- package/dist/storage/storage-list.svelte.js +0 -123
- package/dist/storage/upload-task.svelte.d.ts +0 -94
- package/dist/storage/upload-task.svelte.js +0 -138
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
import { ref, onDisconnect, onValue, get, set } from 'firebase/database';
|
|
2
|
-
import { firebaseService } from '../firebase.js';
|
|
3
|
-
import { browser } from '$app/environment';
|
|
4
|
-
/**
|
|
5
|
-
* Manages real-time user presence tracking with optional geolocation support
|
|
6
|
-
* @class
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* // Initialize presence tracking
|
|
10
|
-
* await presenceService.initialize(currentUser, {
|
|
11
|
-
* geolocation: { enabled: true, type: 'browser' },
|
|
12
|
-
* sessionTTL: 30 * 60 * 1000
|
|
13
|
-
* });
|
|
14
|
-
*
|
|
15
|
-
* // Listen for presence events
|
|
16
|
-
* presenceService.addEventListener((event) => {
|
|
17
|
-
* console.log(event.type, event.data);
|
|
18
|
-
* });
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
class PresenceService {
|
|
22
|
-
static instance;
|
|
23
|
-
connectedListener = null;
|
|
24
|
-
locationWatcher = null;
|
|
25
|
-
currentUser = null;
|
|
26
|
-
eventListeners = new Set();
|
|
27
|
-
config = {
|
|
28
|
-
geolocation: {
|
|
29
|
-
enabled: false,
|
|
30
|
-
type: 'browser',
|
|
31
|
-
requireConsent: true
|
|
32
|
-
},
|
|
33
|
-
sessionTTL: 30 * 60 * 1000, // 30 minutes
|
|
34
|
-
updateInterval: 60 * 1000 // 1 minute
|
|
35
|
-
};
|
|
36
|
-
initialized = $state(false);
|
|
37
|
-
locationConsent = $state(false);
|
|
38
|
-
_currentSession = $state(null);
|
|
39
|
-
_sessions = $state([]);
|
|
40
|
-
_status = $state('offline');
|
|
41
|
-
_loading = $state(true);
|
|
42
|
-
_error = $state(null);
|
|
43
|
-
constructor() {
|
|
44
|
-
if (browser) {
|
|
45
|
-
this.setupVisibilityListener();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
static getInstance() {
|
|
49
|
-
if (!PresenceService.instance) {
|
|
50
|
-
PresenceService.instance = new PresenceService();
|
|
51
|
-
}
|
|
52
|
-
return PresenceService.instance;
|
|
53
|
-
}
|
|
54
|
-
// Getters
|
|
55
|
-
/** Get current session data */
|
|
56
|
-
get currentSession() { return this._currentSession; }
|
|
57
|
-
/** Get all active sessions */
|
|
58
|
-
get sessions() { return this._sessions; }
|
|
59
|
-
/** Get current presence status */
|
|
60
|
-
get status() { return this._status; }
|
|
61
|
-
/** Get loading state */
|
|
62
|
-
get loading() { return this._loading; }
|
|
63
|
-
/** Get error state */
|
|
64
|
-
get error() { return this._error; }
|
|
65
|
-
/** Check if service is initialized */
|
|
66
|
-
get isInitialized() { return this.initialized; }
|
|
67
|
-
/** Check if location consent is granted */
|
|
68
|
-
get hasLocationConsent() { return this.locationConsent; }
|
|
69
|
-
/**
|
|
70
|
-
* Initialize presence tracking
|
|
71
|
-
* @param {any} user Current user object
|
|
72
|
-
* @param {PresenceConfig} config Optional configuration
|
|
73
|
-
* @throws {Error} If initialization fails
|
|
74
|
-
*/
|
|
75
|
-
async initializePresence() {
|
|
76
|
-
const connectedRef = ref(firebaseService.getDatabaseInstance(), '.info/connected');
|
|
77
|
-
this.connectedListener = onValue(connectedRef, async (snapshot) => {
|
|
78
|
-
if (snapshot.val() === true) {
|
|
79
|
-
await this.setPresence('online');
|
|
80
|
-
const userStatusRef = ref(firebaseService.getDatabaseInstance(), `sessions/${this.currentUser.uid}`);
|
|
81
|
-
// Set up disconnect hook
|
|
82
|
-
await onDisconnect(userStatusRef).set({
|
|
83
|
-
sessionDatas: this._sessions.map(session => ({
|
|
84
|
-
...session,
|
|
85
|
-
status: 'offline',
|
|
86
|
-
lastSeen: new Date().toISOString()
|
|
87
|
-
}))
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
await this.setPresence('offline');
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
// Set up visibility change listener
|
|
95
|
-
if (browser) {
|
|
96
|
-
document.onvisibilitychange = async () => {
|
|
97
|
-
if (document.visibilityState === 'hidden') {
|
|
98
|
-
await this.setPresence('away');
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
await this.setPresence('online');
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
setupVisibilityListener() {
|
|
107
|
-
if (browser) {
|
|
108
|
-
document.onvisibilitychange = async () => {
|
|
109
|
-
if (this.initialized) {
|
|
110
|
-
if (document.visibilityState === 'hidden') {
|
|
111
|
-
await this.setPresence('away');
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
await this.setPresence('online');
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
getDeviceInfo() {
|
|
121
|
-
const userAgent = navigator.userAgent;
|
|
122
|
-
const platform = navigator.platform;
|
|
123
|
-
const browserInfo = userAgent.match(/(firefox|chrome|safari|opera|edge|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
|
|
124
|
-
const browser = browserInfo[1] || 'Unknown Browser';
|
|
125
|
-
return `${browser}-${platform}`.replace(/[^a-zA-Z0-9-]/g, '');
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Request location tracking consent
|
|
129
|
-
* @returns {Promise<boolean>} Whether consent was granted
|
|
130
|
-
*/
|
|
131
|
-
async requestLocationConsent() {
|
|
132
|
-
if (!this.config.geolocation?.enabled)
|
|
133
|
-
return false;
|
|
134
|
-
try {
|
|
135
|
-
if (this.config.geolocation.type === 'browser') {
|
|
136
|
-
const permission = await navigator.permissions.query({ name: 'geolocation' });
|
|
137
|
-
if (permission.state === 'granted') {
|
|
138
|
-
this.locationConsent = true;
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
const result = await new Promise((resolve) => {
|
|
142
|
-
navigator.geolocation.getCurrentPosition(() => resolve(true), () => resolve(false), { timeout: 10000 });
|
|
143
|
-
});
|
|
144
|
-
this.locationConsent = result;
|
|
145
|
-
return result;
|
|
146
|
-
}
|
|
147
|
-
return true;
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
console.error('Error requesting location consent:', error);
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async getLocation() {
|
|
155
|
-
if (!this.config.geolocation?.enabled ||
|
|
156
|
-
(this.config.geolocation.requireConsent && !this.locationConsent)) {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
switch (this.config.geolocation.type) {
|
|
161
|
-
case 'browser':
|
|
162
|
-
return new Promise((resolve) => {
|
|
163
|
-
navigator.geolocation.getCurrentPosition((position) => {
|
|
164
|
-
resolve({
|
|
165
|
-
latitude: position.coords.latitude,
|
|
166
|
-
longitude: position.coords.longitude,
|
|
167
|
-
lastUpdated: new Date().toISOString()
|
|
168
|
-
});
|
|
169
|
-
}, () => resolve(null), { timeout: 10000 });
|
|
170
|
-
});
|
|
171
|
-
case 'custom':
|
|
172
|
-
if (this.config.geolocation.customGeolocationFn) {
|
|
173
|
-
const result = await this.config.geolocation.customGeolocationFn();
|
|
174
|
-
return {
|
|
175
|
-
...result,
|
|
176
|
-
lastUpdated: new Date().toISOString()
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
return null;
|
|
180
|
-
case 'ip':
|
|
181
|
-
if (this.config.geolocation.ipServiceUrl) {
|
|
182
|
-
const response = await fetch(this.config.geolocation.ipServiceUrl);
|
|
183
|
-
const data = await response.json();
|
|
184
|
-
return {
|
|
185
|
-
latitude: data.latitude,
|
|
186
|
-
longitude: data.longitude,
|
|
187
|
-
lastUpdated: new Date().toISOString()
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
return null;
|
|
191
|
-
default:
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
catch (error) {
|
|
196
|
-
console.error('Error getting location:', error);
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
async initialize(user, config) {
|
|
201
|
-
try {
|
|
202
|
-
if (!browser) {
|
|
203
|
-
throw new Error('Presence service can only be initialized in browser environment');
|
|
204
|
-
}
|
|
205
|
-
if (this.initialized) {
|
|
206
|
-
console.warn('Presence service is already initialized');
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
this._loading = true;
|
|
210
|
-
this.currentUser = user;
|
|
211
|
-
this.config = { ...this.config, ...config };
|
|
212
|
-
// If geolocation is enabled and requires consent, request it
|
|
213
|
-
if (this.config.geolocation?.enabled && this.config.geolocation.requireConsent) {
|
|
214
|
-
await this.requestLocationConsent();
|
|
215
|
-
}
|
|
216
|
-
await this.initializePresence();
|
|
217
|
-
this.initialized = true;
|
|
218
|
-
// Start location watcher if enabled and has consent
|
|
219
|
-
if (this.config.geolocation?.enabled &&
|
|
220
|
-
(!this.config.geolocation.requireConsent || this.locationConsent)) {
|
|
221
|
-
this.startLocationWatcher();
|
|
222
|
-
}
|
|
223
|
-
this.emitEvent({
|
|
224
|
-
type: 'init',
|
|
225
|
-
data: { userId: user.uid },
|
|
226
|
-
timestamp: Date.now()
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
230
|
-
this._error = error;
|
|
231
|
-
this.emitEvent({
|
|
232
|
-
type: 'error',
|
|
233
|
-
error: error,
|
|
234
|
-
timestamp: Date.now()
|
|
235
|
-
});
|
|
236
|
-
throw error;
|
|
237
|
-
}
|
|
238
|
-
finally {
|
|
239
|
-
this._loading = false;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
async setPresence(status) {
|
|
243
|
-
try {
|
|
244
|
-
if (!this.currentUser) {
|
|
245
|
-
throw new Error('No authenticated user found');
|
|
246
|
-
}
|
|
247
|
-
const db = firebaseService.getDatabaseInstance();
|
|
248
|
-
const userSessionsRef = ref(db, `sessions/${this.currentUser.uid}`);
|
|
249
|
-
const deviceId = this.getDeviceInfo();
|
|
250
|
-
const sessionId = `${this.currentUser.uid}_${deviceId}`;
|
|
251
|
-
// Get location if enabled
|
|
252
|
-
const location = await this.getLocation();
|
|
253
|
-
const userSessionsSnap = await get(userSessionsRef);
|
|
254
|
-
let sessionDatas = [];
|
|
255
|
-
if (userSessionsSnap.exists()) {
|
|
256
|
-
sessionDatas = userSessionsSnap.val().sessionDatas || [];
|
|
257
|
-
const sessionIndex = sessionDatas.findIndex((session) => session.uid === sessionId);
|
|
258
|
-
if (sessionIndex !== -1) {
|
|
259
|
-
// Update existing session
|
|
260
|
-
sessionDatas[sessionIndex] = {
|
|
261
|
-
...sessionDatas[sessionIndex],
|
|
262
|
-
status,
|
|
263
|
-
lastSeen: new Date().toISOString(),
|
|
264
|
-
...(location && { location })
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
// Create new session
|
|
269
|
-
sessionDatas.push({
|
|
270
|
-
uid: sessionId,
|
|
271
|
-
userId: this.currentUser.uid,
|
|
272
|
-
deviceId,
|
|
273
|
-
status,
|
|
274
|
-
createdAt: new Date().toISOString(),
|
|
275
|
-
lastSeen: new Date().toISOString(),
|
|
276
|
-
...(location && { location })
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
// First session for this user
|
|
282
|
-
sessionDatas = [{
|
|
283
|
-
uid: sessionId,
|
|
284
|
-
userId: this.currentUser.uid,
|
|
285
|
-
deviceId,
|
|
286
|
-
status,
|
|
287
|
-
createdAt: new Date().toISOString(),
|
|
288
|
-
lastSeen: new Date().toISOString(),
|
|
289
|
-
...(location && { location })
|
|
290
|
-
}];
|
|
291
|
-
}
|
|
292
|
-
// Clean up stale sessions
|
|
293
|
-
if (this.config.sessionTTL) {
|
|
294
|
-
const cutoffTime = new Date(Date.now() - this.config.sessionTTL).toISOString();
|
|
295
|
-
sessionDatas = sessionDatas.filter(session => session.lastSeen >= cutoffTime);
|
|
296
|
-
}
|
|
297
|
-
await set(userSessionsRef, { sessionDatas });
|
|
298
|
-
this._sessions = sessionDatas;
|
|
299
|
-
this._currentSession = sessionDatas.find(session => session.uid === sessionId) || null;
|
|
300
|
-
this._status = status;
|
|
301
|
-
this.emitEvent({
|
|
302
|
-
type: 'status_change',
|
|
303
|
-
data: { status, sessionId, location },
|
|
304
|
-
timestamp: Date.now()
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
catch (error) {
|
|
308
|
-
this._error = error;
|
|
309
|
-
this.emitEvent({
|
|
310
|
-
type: 'error',
|
|
311
|
-
error: error,
|
|
312
|
-
timestamp: Date.now()
|
|
313
|
-
});
|
|
314
|
-
throw error;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
startLocationWatcher() {
|
|
318
|
-
if (this.locationWatcher)
|
|
319
|
-
return;
|
|
320
|
-
const watchLocation = async () => {
|
|
321
|
-
const location = await this.getLocation();
|
|
322
|
-
if (location && this._currentSession) {
|
|
323
|
-
await this.setPresence(this._status);
|
|
324
|
-
this.emitEvent({
|
|
325
|
-
type: 'location_update',
|
|
326
|
-
data: { location },
|
|
327
|
-
timestamp: Date.now()
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
// Update location periodically
|
|
332
|
-
this.locationWatcher = window.setInterval(watchLocation, this.config.updateInterval);
|
|
333
|
-
}
|
|
334
|
-
stopLocationWatcher() {
|
|
335
|
-
if (this.locationWatcher) {
|
|
336
|
-
clearInterval(this.locationWatcher);
|
|
337
|
-
this.locationWatcher = null;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Add presence event listener
|
|
342
|
-
* @param {Function} callback Event callback function
|
|
343
|
-
* @returns {Function} Cleanup function to remove listener
|
|
344
|
-
*/
|
|
345
|
-
addEventListener(callback) {
|
|
346
|
-
this.eventListeners.add(callback);
|
|
347
|
-
return () => this.eventListeners.delete(callback);
|
|
348
|
-
}
|
|
349
|
-
emitEvent(event) {
|
|
350
|
-
this.eventListeners.forEach(callback => callback(event));
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Cleanup presence tracking
|
|
354
|
-
*/
|
|
355
|
-
dispose() {
|
|
356
|
-
this.stopLocationWatcher();
|
|
357
|
-
if (this.connectedListener) {
|
|
358
|
-
this.connectedListener();
|
|
359
|
-
this.connectedListener = null;
|
|
360
|
-
}
|
|
361
|
-
this.initialized = false;
|
|
362
|
-
this._currentSession = null;
|
|
363
|
-
this._sessions = [];
|
|
364
|
-
this._status = 'offline';
|
|
365
|
-
this._loading = false;
|
|
366
|
-
this._error = null;
|
|
367
|
-
this.emitEvent({
|
|
368
|
-
type: 'disconnect',
|
|
369
|
-
timestamp: Date.now()
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
export const presenceService = PresenceService.getInstance();
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { type User } from "firebase/auth";
|
|
2
|
-
/**
|
|
3
|
-
* FirekitUser provides a singleton class for managing Firebase authentication state and user operations.
|
|
4
|
-
* Implements state management using SvelteKit's $state and $derived.
|
|
5
|
-
*
|
|
6
|
-
* @class
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* // Get instance and check auth state
|
|
10
|
-
* const auth = firekitUser;
|
|
11
|
-
* if (auth.isLoggedIn) {
|
|
12
|
-
* console.log(auth.user);
|
|
13
|
-
* }
|
|
14
|
-
*
|
|
15
|
-
* // Update user profile
|
|
16
|
-
* await auth.updateDisplayName("John Doe");
|
|
17
|
-
* await auth.updatePhotoURL("https://example.com/photo.jpg");
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
declare class FirekitUser {
|
|
21
|
-
private static instance;
|
|
22
|
-
/** @private Current user object state */
|
|
23
|
-
private _user;
|
|
24
|
-
/** @private Authentication initialization state */
|
|
25
|
-
private _initialized;
|
|
26
|
-
/** @private User login state */
|
|
27
|
-
private _isLoggedIn;
|
|
28
|
-
/** Current user's UID */
|
|
29
|
-
readonly uid: string | undefined;
|
|
30
|
-
/** Current user's email */
|
|
31
|
-
readonly email: string | null | undefined;
|
|
32
|
-
/** Current user's display name */
|
|
33
|
-
readonly displayName: string | null | undefined;
|
|
34
|
-
/** Current user's photo URL */
|
|
35
|
-
readonly photoURL: string | null | undefined;
|
|
36
|
-
/** Whether current user's email is verified */
|
|
37
|
-
readonly emailVerified: boolean | undefined;
|
|
38
|
-
/**
|
|
39
|
-
* Private constructor that initializes auth state listener
|
|
40
|
-
* @private
|
|
41
|
-
*/
|
|
42
|
-
private constructor();
|
|
43
|
-
/**
|
|
44
|
-
* Gets the singleton instance of FirekitUser
|
|
45
|
-
* @returns {FirekitUser} The FirekitUser instance
|
|
46
|
-
*/
|
|
47
|
-
static getInstance(): FirekitUser;
|
|
48
|
-
/**
|
|
49
|
-
* Gets the current Firebase user object
|
|
50
|
-
* @returns {User | undefined} The current user or undefined if not logged in
|
|
51
|
-
*/
|
|
52
|
-
get user(): User | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* Checks if the Firebase Auth state has been initialized
|
|
55
|
-
* @returns {boolean | undefined} True if initialized, undefined if pending
|
|
56
|
-
*/
|
|
57
|
-
get initialized(): boolean | undefined;
|
|
58
|
-
/**
|
|
59
|
-
* Checks if a user is currently logged in
|
|
60
|
-
* @returns {boolean | undefined} True if logged in, false if not, undefined if pending
|
|
61
|
-
*/
|
|
62
|
-
get isLoggedIn(): boolean | undefined;
|
|
63
|
-
/**
|
|
64
|
-
* Updates the user's email address
|
|
65
|
-
* @param {string} email - The new email address
|
|
66
|
-
* @throws {Error} If no user is authenticated
|
|
67
|
-
* @example
|
|
68
|
-
* ```typescript
|
|
69
|
-
* await firekitUser.updateEmailUser("new@email.com");
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
updateEmailUser(email: string): Promise<void>;
|
|
73
|
-
/**
|
|
74
|
-
* Updates the user's password
|
|
75
|
-
* @param {string} password - The new password
|
|
76
|
-
* @throws {Error} If no user is authenticated
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* await firekitUser.updatePassword("newPassword123");
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
updatePassword(password: string): Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* Updates the user's display name
|
|
85
|
-
* @param {string} displayName - The new display name
|
|
86
|
-
* @throws {Error} If no user is authenticated
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* await firekitUser.updateDisplayName("John Doe");
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
updateDisplayName(displayName: string): Promise<void>;
|
|
93
|
-
/**
|
|
94
|
-
* Updates the user's profile photo URL
|
|
95
|
-
* @param {string} photoURL - The new photo URL
|
|
96
|
-
* @throws {Error} If no user is authenticated
|
|
97
|
-
* @example
|
|
98
|
-
* ```typescript
|
|
99
|
-
* await firekitUser.updatePhotoURL("https://example.com/photo.jpg");
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
updatePhotoURL(photoURL: string): Promise<void>;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Pre-initialized singleton instance of FirekitUser.
|
|
106
|
-
* Use this to access auth state and user operations.
|
|
107
|
-
*
|
|
108
|
-
* @const
|
|
109
|
-
* @type {FirekitUser}
|
|
110
|
-
*/
|
|
111
|
-
export declare const firekitUser: FirekitUser;
|
|
112
|
-
export {};
|
package/dist/auth/user.svelte.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module FirekitUser
|
|
3
|
-
*/
|
|
4
|
-
import { firebaseService } from "../firebase.js";
|
|
5
|
-
import { onAuthStateChanged, updateEmail, updatePassword, updateProfile } from "firebase/auth";
|
|
6
|
-
/**
|
|
7
|
-
* FirekitUser provides a singleton class for managing Firebase authentication state and user operations.
|
|
8
|
-
* Implements state management using SvelteKit's $state and $derived.
|
|
9
|
-
*
|
|
10
|
-
* @class
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* // Get instance and check auth state
|
|
14
|
-
* const auth = firekitUser;
|
|
15
|
-
* if (auth.isLoggedIn) {
|
|
16
|
-
* console.log(auth.user);
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* // Update user profile
|
|
20
|
-
* await auth.updateDisplayName("John Doe");
|
|
21
|
-
* await auth.updatePhotoURL("https://example.com/photo.jpg");
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
class FirekitUser {
|
|
25
|
-
static instance;
|
|
26
|
-
/** @private Current user object state */
|
|
27
|
-
_user = $state();
|
|
28
|
-
/** @private Authentication initialization state */
|
|
29
|
-
_initialized = $state();
|
|
30
|
-
/** @private User login state */
|
|
31
|
-
_isLoggedIn = $state();
|
|
32
|
-
/** Current user's UID */
|
|
33
|
-
uid = $derived(this._user?.uid);
|
|
34
|
-
/** Current user's email */
|
|
35
|
-
email = $derived(this._user?.email);
|
|
36
|
-
/** Current user's display name */
|
|
37
|
-
displayName = $derived(this._user?.displayName);
|
|
38
|
-
/** Current user's photo URL */
|
|
39
|
-
photoURL = $derived(this._user?.photoURL);
|
|
40
|
-
/** Whether current user's email is verified */
|
|
41
|
-
emailVerified = $derived(this._user?.emailVerified);
|
|
42
|
-
/**
|
|
43
|
-
* Private constructor that initializes auth state listener
|
|
44
|
-
* @private
|
|
45
|
-
*/
|
|
46
|
-
constructor() {
|
|
47
|
-
const auth = firebaseService.getAuthInstance();
|
|
48
|
-
onAuthStateChanged(auth, async (user) => {
|
|
49
|
-
if (user) {
|
|
50
|
-
this._user = user;
|
|
51
|
-
this._isLoggedIn = true;
|
|
52
|
-
this._initialized = true;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
this._isLoggedIn = false;
|
|
56
|
-
this._initialized = true;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Gets the singleton instance of FirekitUser
|
|
62
|
-
* @returns {FirekitUser} The FirekitUser instance
|
|
63
|
-
*/
|
|
64
|
-
static getInstance() {
|
|
65
|
-
if (!FirekitUser.instance) {
|
|
66
|
-
FirekitUser.instance = new FirekitUser();
|
|
67
|
-
}
|
|
68
|
-
return FirekitUser.instance;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Gets the current Firebase user object
|
|
72
|
-
* @returns {User | undefined} The current user or undefined if not logged in
|
|
73
|
-
*/
|
|
74
|
-
get user() {
|
|
75
|
-
return this._user;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Checks if the Firebase Auth state has been initialized
|
|
79
|
-
* @returns {boolean | undefined} True if initialized, undefined if pending
|
|
80
|
-
*/
|
|
81
|
-
get initialized() {
|
|
82
|
-
return this._initialized;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Checks if a user is currently logged in
|
|
86
|
-
* @returns {boolean | undefined} True if logged in, false if not, undefined if pending
|
|
87
|
-
*/
|
|
88
|
-
get isLoggedIn() {
|
|
89
|
-
return this._isLoggedIn;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Updates the user's email address
|
|
93
|
-
* @param {string} email - The new email address
|
|
94
|
-
* @throws {Error} If no user is authenticated
|
|
95
|
-
* @example
|
|
96
|
-
* ```typescript
|
|
97
|
-
* await firekitUser.updateEmailUser("new@email.com");
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
async updateEmailUser(email) {
|
|
101
|
-
if (!this._user)
|
|
102
|
-
throw new Error("No authenticated user");
|
|
103
|
-
await updateEmail(this._user, email);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Updates the user's password
|
|
107
|
-
* @param {string} password - The new password
|
|
108
|
-
* @throws {Error} If no user is authenticated
|
|
109
|
-
* @example
|
|
110
|
-
* ```typescript
|
|
111
|
-
* await firekitUser.updatePassword("newPassword123");
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
async updatePassword(password) {
|
|
115
|
-
if (!this._user)
|
|
116
|
-
throw new Error("No authenticated user");
|
|
117
|
-
await updatePassword(this._user, password);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Updates the user's display name
|
|
121
|
-
* @param {string} displayName - The new display name
|
|
122
|
-
* @throws {Error} If no user is authenticated
|
|
123
|
-
* @example
|
|
124
|
-
* ```typescript
|
|
125
|
-
* await firekitUser.updateDisplayName("John Doe");
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
async updateDisplayName(displayName) {
|
|
129
|
-
if (!this._user)
|
|
130
|
-
throw new Error("No authenticated user");
|
|
131
|
-
await updateProfile(this._user, { displayName });
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Updates the user's profile photo URL
|
|
135
|
-
* @param {string} photoURL - The new photo URL
|
|
136
|
-
* @throws {Error} If no user is authenticated
|
|
137
|
-
* @example
|
|
138
|
-
* ```typescript
|
|
139
|
-
* await firekitUser.updatePhotoURL("https://example.com/photo.jpg");
|
|
140
|
-
* ```
|
|
141
|
-
*/
|
|
142
|
-
async updatePhotoURL(photoURL) {
|
|
143
|
-
if (!this._user)
|
|
144
|
-
throw new Error("No authenticated user");
|
|
145
|
-
await updateProfile(this._user, { photoURL });
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Pre-initialized singleton instance of FirekitUser.
|
|
150
|
-
* Use this to access auth state and user operations.
|
|
151
|
-
*
|
|
152
|
-
* @const
|
|
153
|
-
* @type {FirekitUser}
|
|
154
|
-
*/
|
|
155
|
-
export const firekitUser = FirekitUser.getInstance();
|