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,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module FirekitAwaitableDoc
|
|
3
|
-
*/
|
|
4
|
-
import { type DocumentReference, type DocumentData } from "firebase/firestore";
|
|
5
|
-
/**
|
|
6
|
-
* Provides real-time document subscription with state management.
|
|
7
|
-
* Automatically handles document data updates, loading states, and error handling.
|
|
8
|
-
*
|
|
9
|
-
* @class
|
|
10
|
-
* @template T Type of document data
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* interface UserProfile {
|
|
14
|
-
* id: string;
|
|
15
|
-
* name: string;
|
|
16
|
-
* email: string;
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* // Create document subscription
|
|
20
|
-
* const userDoc = firekitAwaitableDoc<UserProfile>(
|
|
21
|
-
* 'users/123',
|
|
22
|
-
* { id: '123', name: 'Loading...', email: '' }
|
|
23
|
-
* );
|
|
24
|
-
*
|
|
25
|
-
* // Access reactive state
|
|
26
|
-
* if (userDoc.loading) {
|
|
27
|
-
* console.log('Loading user data...');
|
|
28
|
-
* } else if (userDoc.error) {
|
|
29
|
-
* console.error('Error:', userDoc.error);
|
|
30
|
-
* } else {
|
|
31
|
-
* console.log('User data:', userDoc.data);
|
|
32
|
-
* }
|
|
33
|
-
*
|
|
34
|
-
* // Get fresh data
|
|
35
|
-
* const freshData = await userDoc.getData();
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
declare class FirekitAwaitableDoc<T> {
|
|
39
|
-
/**
|
|
40
|
-
* Current document data.
|
|
41
|
-
* Uses SvelteKit's $state for reactivity.
|
|
42
|
-
* @private
|
|
43
|
-
*/
|
|
44
|
-
private _data;
|
|
45
|
-
/**
|
|
46
|
-
* Loading state indicator.
|
|
47
|
-
* Uses SvelteKit's $state for reactivity.
|
|
48
|
-
* @private
|
|
49
|
-
*/
|
|
50
|
-
private _loading;
|
|
51
|
-
/**
|
|
52
|
-
* Error state container.
|
|
53
|
-
* Uses SvelteKit's $state for reactivity.
|
|
54
|
-
* @private
|
|
55
|
-
*/
|
|
56
|
-
private _error;
|
|
57
|
-
/**
|
|
58
|
-
* Firestore document reference.
|
|
59
|
-
* @private
|
|
60
|
-
*/
|
|
61
|
-
private docRef;
|
|
62
|
-
/**
|
|
63
|
-
* Creates a document subscription.
|
|
64
|
-
* Initializes document subscription if in browser environment.
|
|
65
|
-
*
|
|
66
|
-
* @param {string | DocumentReference<T>} ref - Document path or reference
|
|
67
|
-
* @param {T} [startWith] - Initial data before fetch completes
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```typescript
|
|
71
|
-
* const doc = new FirekitAwaitableDoc('users/123', defaultUser);
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
74
|
-
constructor(ref: string | DocumentReference<T>, startWith?: T);
|
|
75
|
-
/**
|
|
76
|
-
* Initializes document subscription.
|
|
77
|
-
* Sets up real-time updates and handles initial data fetch.
|
|
78
|
-
*
|
|
79
|
-
* @private
|
|
80
|
-
* @param {string | DocumentReference<T>} ref - Document path or reference
|
|
81
|
-
* @returns {Promise<void>}
|
|
82
|
-
*
|
|
83
|
-
* @throws {Error} If document initialization fails
|
|
84
|
-
*/
|
|
85
|
-
private initializeDoc;
|
|
86
|
-
/**
|
|
87
|
-
* Fetches fresh document data.
|
|
88
|
-
* Makes a new request to Firestore instead of using cached data.
|
|
89
|
-
*
|
|
90
|
-
* @returns {Promise<T | null>} Document data or null if not found
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```typescript
|
|
94
|
-
* const freshData = await doc.getData();
|
|
95
|
-
* if (freshData) {
|
|
96
|
-
* console.log('Fresh data:', freshData);
|
|
97
|
-
* }
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
getData(): Promise<T | null>;
|
|
101
|
-
/**
|
|
102
|
-
* Gets current document data.
|
|
103
|
-
* @returns {T | null} Current document data or null if not loaded
|
|
104
|
-
*/
|
|
105
|
-
get data(): T | null;
|
|
106
|
-
/**
|
|
107
|
-
* Gets current loading state.
|
|
108
|
-
* @returns {boolean} True if document is loading
|
|
109
|
-
*/
|
|
110
|
-
get loading(): boolean;
|
|
111
|
-
/**
|
|
112
|
-
* Gets current error state.
|
|
113
|
-
* @returns {Error | null} Error object if an error occurred, null otherwise
|
|
114
|
-
*/
|
|
115
|
-
get error(): Error | null;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Creates a document subscription.
|
|
119
|
-
* Factory function for creating FirekitAwaitableDoc instances.
|
|
120
|
-
*
|
|
121
|
-
* @template T Document data type
|
|
122
|
-
* @param {string} path Document path
|
|
123
|
-
* @param {T} [startWith] Initial data before fetch completes
|
|
124
|
-
* @returns {FirekitAwaitableDoc<T>} Document subscription instance
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* ```typescript
|
|
128
|
-
* interface UserProfile {
|
|
129
|
-
* id: string;
|
|
130
|
-
* name: string;
|
|
131
|
-
* email: string;
|
|
132
|
-
* }
|
|
133
|
-
*
|
|
134
|
-
* const userDoc = firekitAwaitableDoc<UserProfile>(
|
|
135
|
-
* 'users/123',
|
|
136
|
-
* { id: '123', name: 'Loading...', email: '' }
|
|
137
|
-
* );
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
export declare function firekitAwaitableDoc<T extends DocumentData>(path: string, startWith?: T): FirekitAwaitableDoc<T>;
|
|
141
|
-
export {};
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module FirekitAwaitableDoc
|
|
3
|
-
*/
|
|
4
|
-
import { doc, getDoc, onSnapshot } from "firebase/firestore";
|
|
5
|
-
import { firebaseService } from "../firebase.js";
|
|
6
|
-
import { browser } from "$app/environment";
|
|
7
|
-
/**
|
|
8
|
-
* Provides real-time document subscription with state management.
|
|
9
|
-
* Automatically handles document data updates, loading states, and error handling.
|
|
10
|
-
*
|
|
11
|
-
* @class
|
|
12
|
-
* @template T Type of document data
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* interface UserProfile {
|
|
16
|
-
* id: string;
|
|
17
|
-
* name: string;
|
|
18
|
-
* email: string;
|
|
19
|
-
* }
|
|
20
|
-
*
|
|
21
|
-
* // Create document subscription
|
|
22
|
-
* const userDoc = firekitAwaitableDoc<UserProfile>(
|
|
23
|
-
* 'users/123',
|
|
24
|
-
* { id: '123', name: 'Loading...', email: '' }
|
|
25
|
-
* );
|
|
26
|
-
*
|
|
27
|
-
* // Access reactive state
|
|
28
|
-
* if (userDoc.loading) {
|
|
29
|
-
* console.log('Loading user data...');
|
|
30
|
-
* } else if (userDoc.error) {
|
|
31
|
-
* console.error('Error:', userDoc.error);
|
|
32
|
-
* } else {
|
|
33
|
-
* console.log('User data:', userDoc.data);
|
|
34
|
-
* }
|
|
35
|
-
*
|
|
36
|
-
* // Get fresh data
|
|
37
|
-
* const freshData = await userDoc.getData();
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
class FirekitAwaitableDoc {
|
|
41
|
-
/**
|
|
42
|
-
* Current document data.
|
|
43
|
-
* Uses SvelteKit's $state for reactivity.
|
|
44
|
-
* @private
|
|
45
|
-
*/
|
|
46
|
-
_data = $state(null);
|
|
47
|
-
/**
|
|
48
|
-
* Loading state indicator.
|
|
49
|
-
* Uses SvelteKit's $state for reactivity.
|
|
50
|
-
* @private
|
|
51
|
-
*/
|
|
52
|
-
_loading = $state(true);
|
|
53
|
-
/**
|
|
54
|
-
* Error state container.
|
|
55
|
-
* Uses SvelteKit's $state for reactivity.
|
|
56
|
-
* @private
|
|
57
|
-
*/
|
|
58
|
-
_error = $state(null);
|
|
59
|
-
/**
|
|
60
|
-
* Firestore document reference.
|
|
61
|
-
* @private
|
|
62
|
-
*/
|
|
63
|
-
docRef = null;
|
|
64
|
-
/**
|
|
65
|
-
* Creates a document subscription.
|
|
66
|
-
* Initializes document subscription if in browser environment.
|
|
67
|
-
*
|
|
68
|
-
* @param {string | DocumentReference<T>} ref - Document path or reference
|
|
69
|
-
* @param {T} [startWith] - Initial data before fetch completes
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* const doc = new FirekitAwaitableDoc('users/123', defaultUser);
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
constructor(ref, startWith) {
|
|
77
|
-
this._data = startWith ?? null;
|
|
78
|
-
if (browser) {
|
|
79
|
-
this.initializeDoc(ref);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Initializes document subscription.
|
|
84
|
-
* Sets up real-time updates and handles initial data fetch.
|
|
85
|
-
*
|
|
86
|
-
* @private
|
|
87
|
-
* @param {string | DocumentReference<T>} ref - Document path or reference
|
|
88
|
-
* @returns {Promise<void>}
|
|
89
|
-
*
|
|
90
|
-
* @throws {Error} If document initialization fails
|
|
91
|
-
*/
|
|
92
|
-
async initializeDoc(ref) {
|
|
93
|
-
try {
|
|
94
|
-
const firestore = firebaseService.getDbInstance();
|
|
95
|
-
this.docRef = typeof ref === "string"
|
|
96
|
-
? doc(firestore, ref)
|
|
97
|
-
: ref;
|
|
98
|
-
// Initial fetch
|
|
99
|
-
const snapshot = await getDoc(this.docRef);
|
|
100
|
-
this._data = snapshot.exists() ? { id: snapshot.id, ...snapshot.data() } : null;
|
|
101
|
-
// Setup real-time updates
|
|
102
|
-
onSnapshot(this.docRef, (snapshot) => {
|
|
103
|
-
this._data = snapshot.exists() ? { id: snapshot.id, ...snapshot.data() } : null;
|
|
104
|
-
this._loading = false;
|
|
105
|
-
this._error = null;
|
|
106
|
-
}, (error) => {
|
|
107
|
-
this._error = error;
|
|
108
|
-
this._loading = false;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
this._error = error;
|
|
113
|
-
this._loading = false;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Fetches fresh document data.
|
|
118
|
-
* Makes a new request to Firestore instead of using cached data.
|
|
119
|
-
*
|
|
120
|
-
* @returns {Promise<T | null>} Document data or null if not found
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* ```typescript
|
|
124
|
-
* const freshData = await doc.getData();
|
|
125
|
-
* if (freshData) {
|
|
126
|
-
* console.log('Fresh data:', freshData);
|
|
127
|
-
* }
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
async getData() {
|
|
131
|
-
if (!this.docRef)
|
|
132
|
-
return null;
|
|
133
|
-
const snapshot = await getDoc(this.docRef);
|
|
134
|
-
return snapshot.exists() ? { id: snapshot.id, ...snapshot.data() } : null;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Gets current document data.
|
|
138
|
-
* @returns {T | null} Current document data or null if not loaded
|
|
139
|
-
*/
|
|
140
|
-
get data() {
|
|
141
|
-
return this._data;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Gets current loading state.
|
|
145
|
-
* @returns {boolean} True if document is loading
|
|
146
|
-
*/
|
|
147
|
-
get loading() {
|
|
148
|
-
return this._loading;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Gets current error state.
|
|
152
|
-
* @returns {Error | null} Error object if an error occurred, null otherwise
|
|
153
|
-
*/
|
|
154
|
-
get error() {
|
|
155
|
-
return this._error;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Creates a document subscription.
|
|
160
|
-
* Factory function for creating FirekitAwaitableDoc instances.
|
|
161
|
-
*
|
|
162
|
-
* @template T Document data type
|
|
163
|
-
* @param {string} path Document path
|
|
164
|
-
* @param {T} [startWith] Initial data before fetch completes
|
|
165
|
-
* @returns {FirekitAwaitableDoc<T>} Document subscription instance
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* ```typescript
|
|
169
|
-
* interface UserProfile {
|
|
170
|
-
* id: string;
|
|
171
|
-
* name: string;
|
|
172
|
-
* email: string;
|
|
173
|
-
* }
|
|
174
|
-
*
|
|
175
|
-
* const userDoc = firekitAwaitableDoc<UserProfile>(
|
|
176
|
-
* 'users/123',
|
|
177
|
-
* { id: '123', name: 'Loading...', email: '' }
|
|
178
|
-
* );
|
|
179
|
-
* ```
|
|
180
|
-
*/
|
|
181
|
-
export function firekitAwaitableDoc(path, startWith) {
|
|
182
|
-
return new FirekitAwaitableDoc(path, startWith);
|
|
183
|
-
}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module FirekitBatchMutations
|
|
3
|
-
*/
|
|
4
|
-
import { type DocumentData, type WithFieldValue } from 'firebase/firestore';
|
|
5
|
-
/**
|
|
6
|
-
* Response structure for batch operations
|
|
7
|
-
* @interface BatchResponse
|
|
8
|
-
*/
|
|
9
|
-
interface BatchResponse {
|
|
10
|
-
/** Operation success status */
|
|
11
|
-
success: boolean;
|
|
12
|
-
/** Number of processed items */
|
|
13
|
-
processedItems?: number;
|
|
14
|
-
/** Error details if operation failed */
|
|
15
|
-
error?: {
|
|
16
|
-
code: string;
|
|
17
|
-
message: string;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Options for batch mutations
|
|
22
|
-
* @interface BatchMutationOptions
|
|
23
|
-
*/
|
|
24
|
-
interface BatchMutationOptions {
|
|
25
|
-
/** Whether to include timestamp fields */
|
|
26
|
-
timestamps?: boolean;
|
|
27
|
-
/** Whether to merge data in set operations */
|
|
28
|
-
merge?: boolean;
|
|
29
|
-
/** Batch size limit (default: 500) */
|
|
30
|
-
batchSize?: number;
|
|
31
|
-
/** Delay between batches in milliseconds (default: 3000) */
|
|
32
|
-
delayBetweenBatches?: number;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Batch operation type
|
|
36
|
-
* @type BatchOperation
|
|
37
|
-
*/
|
|
38
|
-
type BatchOperation<T> = {
|
|
39
|
-
/** Operation type */
|
|
40
|
-
type: 'set' | 'update' | 'delete';
|
|
41
|
-
/** Document path */
|
|
42
|
-
path: string;
|
|
43
|
-
/** Document data */
|
|
44
|
-
data?: WithFieldValue<T>;
|
|
45
|
-
/** Operation options */
|
|
46
|
-
options?: BatchMutationOptions;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* Manages Firestore batch operations with automatic timestamps and error handling
|
|
50
|
-
* @class
|
|
51
|
-
*/
|
|
52
|
-
declare class FirekitBatchMutations {
|
|
53
|
-
/** Default batch size limit */
|
|
54
|
-
private readonly DEFAULT_BATCH_LIMIT;
|
|
55
|
-
/** Default delay between batches in milliseconds */
|
|
56
|
-
private readonly DEFAULT_BATCH_DELAY;
|
|
57
|
-
/**
|
|
58
|
-
* Generates timestamp data for document mutations
|
|
59
|
-
* @private
|
|
60
|
-
* @param {boolean} [isNew=true] Whether this is a new document
|
|
61
|
-
* @returns {Record<string, any>} Timestamp data
|
|
62
|
-
*/
|
|
63
|
-
private getTimestampData;
|
|
64
|
-
/**
|
|
65
|
-
* Creates a delay between batch operations
|
|
66
|
-
* @private
|
|
67
|
-
* @param {number} ms Milliseconds to delay
|
|
68
|
-
* @returns {Promise<void>}
|
|
69
|
-
*/
|
|
70
|
-
private delay;
|
|
71
|
-
/**
|
|
72
|
-
* Handles and formats batch operation errors
|
|
73
|
-
* @private
|
|
74
|
-
* @param {any} error Error object
|
|
75
|
-
* @returns {BatchResponse} Formatted error response
|
|
76
|
-
*/
|
|
77
|
-
private handleError;
|
|
78
|
-
/**
|
|
79
|
-
* Executes multiple write operations as batches
|
|
80
|
-
* @template T Document data type
|
|
81
|
-
* @param {BatchOperation<T>[]} operations Array of batch operations
|
|
82
|
-
* @param {BatchMutationOptions} [options] Batch options
|
|
83
|
-
* @returns {Promise<BatchResponse>} Batch operation response
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* ```typescript
|
|
87
|
-
* const operations = [
|
|
88
|
-
* {
|
|
89
|
-
* type: 'set',
|
|
90
|
-
* path: 'cities/NYC',
|
|
91
|
-
* data: { name: 'New York City' }
|
|
92
|
-
* },
|
|
93
|
-
* {
|
|
94
|
-
* type: 'update',
|
|
95
|
-
* path: 'cities/SF',
|
|
96
|
-
* data: { population: 1000000 }
|
|
97
|
-
* },
|
|
98
|
-
* {
|
|
99
|
-
* type: 'delete',
|
|
100
|
-
* path: 'cities/LA'
|
|
101
|
-
* }
|
|
102
|
-
* ];
|
|
103
|
-
*
|
|
104
|
-
* const result = await firekitBatchMutations.batch(operations);
|
|
105
|
-
* ```
|
|
106
|
-
*/
|
|
107
|
-
batch<T extends DocumentData>(operations: BatchOperation<T>[], options?: BatchMutationOptions): Promise<BatchResponse>;
|
|
108
|
-
/**
|
|
109
|
-
* Inserts multiple items into a collection using batched writes
|
|
110
|
-
* @template T Document data type
|
|
111
|
-
* @param {string} collectionPath Collection path
|
|
112
|
-
* @param {T[]} items Array of items to insert
|
|
113
|
-
* @param {BatchMutationOptions} [options] Batch options
|
|
114
|
-
* @param {string} [idKey] Optional key to use as document ID from items
|
|
115
|
-
* @returns {Promise<BatchResponse>} Batch operation response
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```typescript
|
|
119
|
-
* const items = [
|
|
120
|
-
* { id: 'nyc', name: 'New York City' },
|
|
121
|
-
* { id: 'sf', name: 'San Francisco' }
|
|
122
|
-
* ];
|
|
123
|
-
*
|
|
124
|
-
* const result = await firekitBatchMutations.batchInsert(
|
|
125
|
-
* 'cities',
|
|
126
|
-
* items,
|
|
127
|
-
* { timestamps: true },
|
|
128
|
-
* 'id'
|
|
129
|
-
* );
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
batchInsert<T extends DocumentData>(collectionPath: string, items: T[], options?: BatchMutationOptions, idKey?: string): Promise<BatchResponse>;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Pre-initialized instance of FirekitBatchMutations
|
|
136
|
-
* @const
|
|
137
|
-
* @type {FirekitBatchMutations}
|
|
138
|
-
*/
|
|
139
|
-
export declare const firekitBatchMutations: FirekitBatchMutations;
|
|
140
|
-
export {};
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module FirekitBatchMutations
|
|
3
|
-
*/
|
|
4
|
-
import { doc, collection, writeBatch, serverTimestamp } from 'firebase/firestore';
|
|
5
|
-
import { firebaseService } from '../firebase.js';
|
|
6
|
-
import { firekitUser } from '../auth/user.svelte.js';
|
|
7
|
-
/**
|
|
8
|
-
* Manages Firestore batch operations with automatic timestamps and error handling
|
|
9
|
-
* @class
|
|
10
|
-
*/
|
|
11
|
-
class FirekitBatchMutations {
|
|
12
|
-
/** Default batch size limit */
|
|
13
|
-
DEFAULT_BATCH_LIMIT = 500;
|
|
14
|
-
/** Default delay between batches in milliseconds */
|
|
15
|
-
DEFAULT_BATCH_DELAY = 3000;
|
|
16
|
-
/**
|
|
17
|
-
* Generates timestamp data for document mutations
|
|
18
|
-
* @private
|
|
19
|
-
* @param {boolean} [isNew=true] Whether this is a new document
|
|
20
|
-
* @returns {Record<string, any>} Timestamp data
|
|
21
|
-
*/
|
|
22
|
-
getTimestampData(isNew = true) {
|
|
23
|
-
const timestamps = {
|
|
24
|
-
updatedAt: serverTimestamp(),
|
|
25
|
-
updatedBy: firekitUser.uid
|
|
26
|
-
};
|
|
27
|
-
if (isNew) {
|
|
28
|
-
timestamps.createdAt = serverTimestamp();
|
|
29
|
-
timestamps.createdBy = firekitUser.uid;
|
|
30
|
-
}
|
|
31
|
-
return timestamps;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Creates a delay between batch operations
|
|
35
|
-
* @private
|
|
36
|
-
* @param {number} ms Milliseconds to delay
|
|
37
|
-
* @returns {Promise<void>}
|
|
38
|
-
*/
|
|
39
|
-
async delay(ms) {
|
|
40
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Handles and formats batch operation errors
|
|
44
|
-
* @private
|
|
45
|
-
* @param {any} error Error object
|
|
46
|
-
* @returns {BatchResponse} Formatted error response
|
|
47
|
-
*/
|
|
48
|
-
handleError(error) {
|
|
49
|
-
console.error('Firestore batch operation error:', error);
|
|
50
|
-
return {
|
|
51
|
-
success: false,
|
|
52
|
-
error: {
|
|
53
|
-
code: error.code || 'unknown_error',
|
|
54
|
-
message: error.message || 'An unknown error occurred'
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Executes multiple write operations as batches
|
|
60
|
-
* @template T Document data type
|
|
61
|
-
* @param {BatchOperation<T>[]} operations Array of batch operations
|
|
62
|
-
* @param {BatchMutationOptions} [options] Batch options
|
|
63
|
-
* @returns {Promise<BatchResponse>} Batch operation response
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* const operations = [
|
|
68
|
-
* {
|
|
69
|
-
* type: 'set',
|
|
70
|
-
* path: 'cities/NYC',
|
|
71
|
-
* data: { name: 'New York City' }
|
|
72
|
-
* },
|
|
73
|
-
* {
|
|
74
|
-
* type: 'update',
|
|
75
|
-
* path: 'cities/SF',
|
|
76
|
-
* data: { population: 1000000 }
|
|
77
|
-
* },
|
|
78
|
-
* {
|
|
79
|
-
* type: 'delete',
|
|
80
|
-
* path: 'cities/LA'
|
|
81
|
-
* }
|
|
82
|
-
* ];
|
|
83
|
-
*
|
|
84
|
-
* const result = await firekitBatchMutations.batch(operations);
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
async batch(operations, options = {}) {
|
|
88
|
-
try {
|
|
89
|
-
const firestore = firebaseService.getDbInstance();
|
|
90
|
-
let batch = writeBatch(firestore);
|
|
91
|
-
let batchCounter = 0;
|
|
92
|
-
const batchLimit = options.batchSize || this.DEFAULT_BATCH_LIMIT;
|
|
93
|
-
const batchDelay = options.delayBetweenBatches || this.DEFAULT_BATCH_DELAY;
|
|
94
|
-
for (const [index, operation] of operations.entries()) {
|
|
95
|
-
const docRef = doc(firestore, operation.path);
|
|
96
|
-
switch (operation.type) {
|
|
97
|
-
case 'set': {
|
|
98
|
-
if (!operation.data) {
|
|
99
|
-
throw new Error('Data is required for set operation');
|
|
100
|
-
}
|
|
101
|
-
const dataToSet = {
|
|
102
|
-
...operation.data,
|
|
103
|
-
...(operation.options?.timestamps && this.getTimestampData()),
|
|
104
|
-
id: docRef.id
|
|
105
|
-
};
|
|
106
|
-
batch.set(docRef, dataToSet, {
|
|
107
|
-
merge: operation.options?.merge
|
|
108
|
-
});
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
case 'update': {
|
|
112
|
-
if (!operation.data) {
|
|
113
|
-
throw new Error('Data is required for update operation');
|
|
114
|
-
}
|
|
115
|
-
const dataToUpdate = {
|
|
116
|
-
...operation.data,
|
|
117
|
-
...(operation.options?.timestamps && this.getTimestampData(false))
|
|
118
|
-
};
|
|
119
|
-
batch.update(docRef, dataToUpdate);
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
case 'delete': {
|
|
123
|
-
batch.delete(docRef);
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
default:
|
|
127
|
-
throw new Error(`Invalid operation type: ${operation.type}`);
|
|
128
|
-
}
|
|
129
|
-
batchCounter++;
|
|
130
|
-
// If batch limit reached or last item, commit and create new batch
|
|
131
|
-
if (batchCounter === batchLimit || index === operations.length - 1) {
|
|
132
|
-
await batch.commit();
|
|
133
|
-
console.log(`Batch committed at index ${index} of ${operations.length} operations.`);
|
|
134
|
-
if (index < operations.length - 1) {
|
|
135
|
-
batch = writeBatch(firestore);
|
|
136
|
-
batchCounter = 0;
|
|
137
|
-
await this.delay(batchDelay);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
success: true,
|
|
143
|
-
processedItems: operations.length
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
return this.handleError(error);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Inserts multiple items into a collection using batched writes
|
|
152
|
-
* @template T Document data type
|
|
153
|
-
* @param {string} collectionPath Collection path
|
|
154
|
-
* @param {T[]} items Array of items to insert
|
|
155
|
-
* @param {BatchMutationOptions} [options] Batch options
|
|
156
|
-
* @param {string} [idKey] Optional key to use as document ID from items
|
|
157
|
-
* @returns {Promise<BatchResponse>} Batch operation response
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```typescript
|
|
161
|
-
* const items = [
|
|
162
|
-
* { id: 'nyc', name: 'New York City' },
|
|
163
|
-
* { id: 'sf', name: 'San Francisco' }
|
|
164
|
-
* ];
|
|
165
|
-
*
|
|
166
|
-
* const result = await firekitBatchMutations.batchInsert(
|
|
167
|
-
* 'cities',
|
|
168
|
-
* items,
|
|
169
|
-
* { timestamps: true },
|
|
170
|
-
* 'id'
|
|
171
|
-
* );
|
|
172
|
-
* ```
|
|
173
|
-
*/
|
|
174
|
-
async batchInsert(collectionPath, items, options = { timestamps: true }, idKey) {
|
|
175
|
-
try {
|
|
176
|
-
const firestore = firebaseService.getDbInstance();
|
|
177
|
-
let batch = writeBatch(firestore);
|
|
178
|
-
let batchCounter = 0;
|
|
179
|
-
const batchLimit = options.batchSize || this.DEFAULT_BATCH_LIMIT;
|
|
180
|
-
const batchDelay = options.delayBetweenBatches || this.DEFAULT_BATCH_DELAY;
|
|
181
|
-
for (const [index, item] of items.entries()) {
|
|
182
|
-
const docRef = idKey && item[idKey]
|
|
183
|
-
? doc(firestore, collectionPath, item[idKey])
|
|
184
|
-
: doc(collection(firestore, collectionPath));
|
|
185
|
-
const dataToSet = {
|
|
186
|
-
...item,
|
|
187
|
-
...(options.timestamps && this.getTimestampData()),
|
|
188
|
-
id: docRef.id
|
|
189
|
-
};
|
|
190
|
-
batch.set(docRef, dataToSet, { merge: options.merge });
|
|
191
|
-
batchCounter++;
|
|
192
|
-
// If batch limit reached or last item, commit and create new batch
|
|
193
|
-
if (batchCounter === batchLimit || index === items.length - 1) {
|
|
194
|
-
await batch.commit();
|
|
195
|
-
console.log(`Batch committed at index ${index} of ${items.length} items.`);
|
|
196
|
-
if (index < items.length - 1) {
|
|
197
|
-
batch = writeBatch(firestore);
|
|
198
|
-
batchCounter = 0;
|
|
199
|
-
await this.delay(batchDelay);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return {
|
|
204
|
-
success: true,
|
|
205
|
-
processedItems: items.length
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
catch (error) {
|
|
209
|
-
return this.handleError(error);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Pre-initialized instance of FirekitBatchMutations
|
|
215
|
-
* @const
|
|
216
|
-
* @type {FirekitBatchMutations}
|
|
217
|
-
*/
|
|
218
|
-
export const firekitBatchMutations = new FirekitBatchMutations();
|