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
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Authentication types and interfaces for FirekitAuth
|
|
3
|
+
* @module AuthTypes
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* User profile interface with all Firebase user properties
|
|
8
|
+
*/
|
|
9
|
+
export interface UserProfile {
|
|
10
|
+
uid: string;
|
|
11
|
+
email: string | null;
|
|
12
|
+
displayName: string | null;
|
|
13
|
+
photoURL: string | null;
|
|
14
|
+
phoneNumber: string | null;
|
|
15
|
+
emailVerified: boolean;
|
|
16
|
+
isAnonymous: boolean;
|
|
17
|
+
providerId: string;
|
|
18
|
+
metadata: {
|
|
19
|
+
creationTime?: string;
|
|
20
|
+
lastSignInTime?: string;
|
|
21
|
+
};
|
|
22
|
+
providerData: Array<{
|
|
23
|
+
providerId: string;
|
|
24
|
+
uid: string;
|
|
25
|
+
displayName: string | null;
|
|
26
|
+
email: string | null;
|
|
27
|
+
phoneNumber: string | null;
|
|
28
|
+
photoURL: string | null;
|
|
29
|
+
}>;
|
|
30
|
+
customClaims?: Record<string, any>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Authentication state interface
|
|
34
|
+
*/
|
|
35
|
+
export interface AuthState {
|
|
36
|
+
user: UserProfile | null;
|
|
37
|
+
loading: boolean;
|
|
38
|
+
initialized: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Password update result interface
|
|
42
|
+
*/
|
|
43
|
+
export interface PasswordUpdateResult {
|
|
44
|
+
success: boolean;
|
|
45
|
+
message: string;
|
|
46
|
+
code?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Account deletion result interface
|
|
50
|
+
*/
|
|
51
|
+
export interface AccountDeletionResult {
|
|
52
|
+
success: boolean;
|
|
53
|
+
message: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Phone verification result interface
|
|
57
|
+
*/
|
|
58
|
+
export interface PhoneVerificationResult {
|
|
59
|
+
verificationId: string;
|
|
60
|
+
confirm: (code: string) => Promise<UserProfile>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* User registration data interface
|
|
64
|
+
*/
|
|
65
|
+
export interface UserRegistrationData {
|
|
66
|
+
email: string;
|
|
67
|
+
password: string;
|
|
68
|
+
displayName?: string;
|
|
69
|
+
photoURL?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* User profile update data interface
|
|
73
|
+
*/
|
|
74
|
+
export interface UserProfileUpdateData {
|
|
75
|
+
displayName?: string;
|
|
76
|
+
photoURL?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* OAuth provider types
|
|
80
|
+
*/
|
|
81
|
+
export type OAuthProviderType = 'google' | 'facebook' | 'apple' | 'microsoft' | 'github' | 'twitter';
|
|
82
|
+
/**
|
|
83
|
+
* Authentication method types
|
|
84
|
+
*/
|
|
85
|
+
export type AuthMethodType = 'email' | 'phone' | 'google' | 'facebook' | 'apple' | 'microsoft' | 'github' | 'twitter' | 'anonymous';
|
|
86
|
+
/**
|
|
87
|
+
* Authentication event types
|
|
88
|
+
*/
|
|
89
|
+
export type AuthEventType = 'signIn' | 'signOut' | 'signUp' | 'passwordReset' | 'emailVerification' | 'profileUpdate' | 'accountDeletion' | 'error';
|
|
90
|
+
/**
|
|
91
|
+
* Authentication event data interface
|
|
92
|
+
*/
|
|
93
|
+
export interface AuthEventData {
|
|
94
|
+
type: AuthEventType;
|
|
95
|
+
user?: UserProfile | null;
|
|
96
|
+
method?: AuthMethodType;
|
|
97
|
+
error?: FirekitAuthError;
|
|
98
|
+
timestamp: Date;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Authentication configuration interface
|
|
102
|
+
*/
|
|
103
|
+
export interface AuthConfig {
|
|
104
|
+
/** Enable automatic Firestore user data sync */
|
|
105
|
+
enableFirestoreSync?: boolean;
|
|
106
|
+
/** Custom Firestore collection path for users */
|
|
107
|
+
usersCollectionPath?: string;
|
|
108
|
+
/** Enable email verification on registration */
|
|
109
|
+
requireEmailVerification?: boolean;
|
|
110
|
+
/** Custom error message overrides */
|
|
111
|
+
errorMessages?: Partial<Record<AuthErrorCode, string>>;
|
|
112
|
+
/** Enable analytics tracking */
|
|
113
|
+
enableAnalytics?: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Authentication error codes enum
|
|
117
|
+
*/
|
|
118
|
+
export declare enum AuthErrorCode {
|
|
119
|
+
EMAIL_ALREADY_IN_USE = "auth/email-already-in-use",
|
|
120
|
+
INVALID_EMAIL = "auth/invalid-email",
|
|
121
|
+
USER_NOT_FOUND = "auth/user-not-found",
|
|
122
|
+
WRONG_PASSWORD = "auth/wrong-password",
|
|
123
|
+
WEAK_PASSWORD = "auth/weak-password",
|
|
124
|
+
TOO_MANY_REQUESTS = "auth/too-many-requests",
|
|
125
|
+
POPUP_CLOSED = "auth/popup-closed-by-user",
|
|
126
|
+
NETWORK_REQUEST_FAILED = "auth/network-request-failed",
|
|
127
|
+
USER_DISABLED = "auth/user-disabled",
|
|
128
|
+
OPERATION_NOT_ALLOWED = "auth/operation-not-allowed",
|
|
129
|
+
INVALID_VERIFICATION_CODE = "auth/invalid-verification-code",
|
|
130
|
+
INVALID_VERIFICATION_ID = "auth/invalid-verification-id",
|
|
131
|
+
REQUIRES_RECENT_LOGIN = "auth/requires-recent-login",
|
|
132
|
+
EXPIRED_ACTION_CODE = "auth/expired-action-code",
|
|
133
|
+
INVALID_ACTION_CODE = "auth/invalid-action-code",
|
|
134
|
+
MISSING_EMAIL = "auth/missing-email",
|
|
135
|
+
MISSING_PASSWORD = "auth/missing-password",
|
|
136
|
+
INVALID_PHONE_NUMBER = "auth/invalid-phone-number",
|
|
137
|
+
MISSING_PHONE_NUMBER = "auth/missing-phone-number",
|
|
138
|
+
QUOTA_EXCEEDED = "auth/quota-exceeded",
|
|
139
|
+
APP_NOT_AUTHORIZED = "auth/app-not-authorized",
|
|
140
|
+
KEYBOARD_NOT_SUPPORTED = "auth/keychain-error",
|
|
141
|
+
INTERNAL_ERROR = "auth/internal-error"
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Custom authentication error class
|
|
145
|
+
*/
|
|
146
|
+
export declare class FirekitAuthError extends Error {
|
|
147
|
+
code: AuthErrorCode | string;
|
|
148
|
+
originalError?: any | undefined;
|
|
149
|
+
constructor(code: AuthErrorCode | string, message: string, originalError?: any | undefined);
|
|
150
|
+
/**
|
|
151
|
+
* Get user-friendly error message
|
|
152
|
+
*/
|
|
153
|
+
getFriendlyMessage(): string;
|
|
154
|
+
/**
|
|
155
|
+
* Check if error is retryable
|
|
156
|
+
*/
|
|
157
|
+
isRetryable(): boolean;
|
|
158
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Authentication types and interfaces for FirekitAuth
|
|
3
|
+
* @module AuthTypes
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Authentication error codes enum
|
|
8
|
+
*/
|
|
9
|
+
export var AuthErrorCode;
|
|
10
|
+
(function (AuthErrorCode) {
|
|
11
|
+
AuthErrorCode["EMAIL_ALREADY_IN_USE"] = "auth/email-already-in-use";
|
|
12
|
+
AuthErrorCode["INVALID_EMAIL"] = "auth/invalid-email";
|
|
13
|
+
AuthErrorCode["USER_NOT_FOUND"] = "auth/user-not-found";
|
|
14
|
+
AuthErrorCode["WRONG_PASSWORD"] = "auth/wrong-password";
|
|
15
|
+
AuthErrorCode["WEAK_PASSWORD"] = "auth/weak-password";
|
|
16
|
+
AuthErrorCode["TOO_MANY_REQUESTS"] = "auth/too-many-requests";
|
|
17
|
+
AuthErrorCode["POPUP_CLOSED"] = "auth/popup-closed-by-user";
|
|
18
|
+
AuthErrorCode["NETWORK_REQUEST_FAILED"] = "auth/network-request-failed";
|
|
19
|
+
AuthErrorCode["USER_DISABLED"] = "auth/user-disabled";
|
|
20
|
+
AuthErrorCode["OPERATION_NOT_ALLOWED"] = "auth/operation-not-allowed";
|
|
21
|
+
AuthErrorCode["INVALID_VERIFICATION_CODE"] = "auth/invalid-verification-code";
|
|
22
|
+
AuthErrorCode["INVALID_VERIFICATION_ID"] = "auth/invalid-verification-id";
|
|
23
|
+
AuthErrorCode["REQUIRES_RECENT_LOGIN"] = "auth/requires-recent-login";
|
|
24
|
+
AuthErrorCode["EXPIRED_ACTION_CODE"] = "auth/expired-action-code";
|
|
25
|
+
AuthErrorCode["INVALID_ACTION_CODE"] = "auth/invalid-action-code";
|
|
26
|
+
AuthErrorCode["MISSING_EMAIL"] = "auth/missing-email";
|
|
27
|
+
AuthErrorCode["MISSING_PASSWORD"] = "auth/missing-password";
|
|
28
|
+
AuthErrorCode["INVALID_PHONE_NUMBER"] = "auth/invalid-phone-number";
|
|
29
|
+
AuthErrorCode["MISSING_PHONE_NUMBER"] = "auth/missing-phone-number";
|
|
30
|
+
AuthErrorCode["QUOTA_EXCEEDED"] = "auth/quota-exceeded";
|
|
31
|
+
AuthErrorCode["APP_NOT_AUTHORIZED"] = "auth/app-not-authorized";
|
|
32
|
+
AuthErrorCode["KEYBOARD_NOT_SUPPORTED"] = "auth/keychain-error";
|
|
33
|
+
AuthErrorCode["INTERNAL_ERROR"] = "auth/internal-error";
|
|
34
|
+
})(AuthErrorCode || (AuthErrorCode = {}));
|
|
35
|
+
/**
|
|
36
|
+
* Custom authentication error class
|
|
37
|
+
*/
|
|
38
|
+
export class FirekitAuthError extends Error {
|
|
39
|
+
code;
|
|
40
|
+
originalError;
|
|
41
|
+
constructor(code, message, originalError) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.code = code;
|
|
44
|
+
this.originalError = originalError;
|
|
45
|
+
this.name = 'FirekitAuthError';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get user-friendly error message
|
|
49
|
+
*/
|
|
50
|
+
getFriendlyMessage() {
|
|
51
|
+
switch (this.code) {
|
|
52
|
+
case AuthErrorCode.EMAIL_ALREADY_IN_USE:
|
|
53
|
+
return 'An account with this email already exists.';
|
|
54
|
+
case AuthErrorCode.INVALID_EMAIL:
|
|
55
|
+
return 'Please enter a valid email address.';
|
|
56
|
+
case AuthErrorCode.USER_NOT_FOUND:
|
|
57
|
+
return 'No account found with this email address.';
|
|
58
|
+
case AuthErrorCode.WRONG_PASSWORD:
|
|
59
|
+
return 'Incorrect password. Please try again.';
|
|
60
|
+
case AuthErrorCode.WEAK_PASSWORD:
|
|
61
|
+
return 'Password should be at least 6 characters long.';
|
|
62
|
+
case AuthErrorCode.TOO_MANY_REQUESTS:
|
|
63
|
+
return 'Too many failed attempts. Please try again later.';
|
|
64
|
+
case AuthErrorCode.POPUP_CLOSED:
|
|
65
|
+
return 'Sign-in was cancelled. Please try again.';
|
|
66
|
+
case AuthErrorCode.NETWORK_REQUEST_FAILED:
|
|
67
|
+
return 'Network error. Please check your connection.';
|
|
68
|
+
case AuthErrorCode.USER_DISABLED:
|
|
69
|
+
return 'This account has been disabled.';
|
|
70
|
+
case AuthErrorCode.REQUIRES_RECENT_LOGIN:
|
|
71
|
+
return 'Please sign in again to complete this action.';
|
|
72
|
+
case AuthErrorCode.EXPIRED_ACTION_CODE:
|
|
73
|
+
return 'This action code has expired. Please request a new one.';
|
|
74
|
+
case AuthErrorCode.INVALID_ACTION_CODE:
|
|
75
|
+
return 'Invalid action code. Please check and try again.';
|
|
76
|
+
case AuthErrorCode.MISSING_EMAIL:
|
|
77
|
+
return 'Email address is required.';
|
|
78
|
+
case AuthErrorCode.MISSING_PASSWORD:
|
|
79
|
+
return 'Password is required.';
|
|
80
|
+
case AuthErrorCode.INVALID_PHONE_NUMBER:
|
|
81
|
+
return 'Please enter a valid phone number.';
|
|
82
|
+
case AuthErrorCode.MISSING_PHONE_NUMBER:
|
|
83
|
+
return 'Phone number is required.';
|
|
84
|
+
case AuthErrorCode.QUOTA_EXCEEDED:
|
|
85
|
+
return 'SMS quota exceeded. Please try again later.';
|
|
86
|
+
case AuthErrorCode.APP_NOT_AUTHORIZED:
|
|
87
|
+
return 'This app is not authorized to use Firebase Authentication.';
|
|
88
|
+
case AuthErrorCode.INTERNAL_ERROR:
|
|
89
|
+
return 'An internal error occurred. Please try again.';
|
|
90
|
+
default:
|
|
91
|
+
return this.message;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if error is retryable
|
|
96
|
+
*/
|
|
97
|
+
isRetryable() {
|
|
98
|
+
const retryableCodes = [
|
|
99
|
+
AuthErrorCode.NETWORK_REQUEST_FAILED,
|
|
100
|
+
AuthErrorCode.TOO_MANY_REQUESTS,
|
|
101
|
+
AuthErrorCode.QUOTA_EXCEEDED,
|
|
102
|
+
AuthErrorCode.INTERNAL_ERROR
|
|
103
|
+
];
|
|
104
|
+
return retryableCodes.includes(this.code);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Collection types and interfaces for FirekitCollection
|
|
3
|
+
* @module CollectionTypes
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import type { QueryConstraint } from 'firebase/firestore';
|
|
7
|
+
/**
|
|
8
|
+
* Collection state interface containing all reactive properties
|
|
9
|
+
*/
|
|
10
|
+
export interface CollectionState<T> {
|
|
11
|
+
/** Array of documents in the collection */
|
|
12
|
+
data: T[];
|
|
13
|
+
/** Loading state indicator */
|
|
14
|
+
loading: boolean;
|
|
15
|
+
/** Whether collection has been initialized */
|
|
16
|
+
initialized: boolean;
|
|
17
|
+
/** Current error state */
|
|
18
|
+
error: CollectionError | null;
|
|
19
|
+
/** Whether collection is empty */
|
|
20
|
+
empty: boolean;
|
|
21
|
+
/** Number of documents */
|
|
22
|
+
size: number;
|
|
23
|
+
/** Last update timestamp */
|
|
24
|
+
lastUpdated: Date | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Collection configuration options
|
|
28
|
+
*/
|
|
29
|
+
export interface CollectionOptions {
|
|
30
|
+
/** Enable real-time updates (default: true) */
|
|
31
|
+
realtime?: boolean;
|
|
32
|
+
/** Include metadata changes in updates (default: false) */
|
|
33
|
+
includeMetadata?: boolean;
|
|
34
|
+
/** Data source preference (default: 'default') */
|
|
35
|
+
source?: 'default' | 'server' | 'cache';
|
|
36
|
+
/** Transform function for documents */
|
|
37
|
+
transform?: (doc: any) => any;
|
|
38
|
+
/** Filter function for documents */
|
|
39
|
+
filter?: (doc: any) => boolean;
|
|
40
|
+
/** Sort function for documents */
|
|
41
|
+
sort?: (a: any, b: any) => number;
|
|
42
|
+
/** Pagination settings */
|
|
43
|
+
pagination?: PaginationConfig;
|
|
44
|
+
/** Cache configuration */
|
|
45
|
+
cache?: CacheConfig;
|
|
46
|
+
/** Error handling configuration */
|
|
47
|
+
errorHandling?: ErrorHandlingConfig;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Pagination configuration
|
|
51
|
+
*/
|
|
52
|
+
export interface PaginationConfig {
|
|
53
|
+
/** Enable pagination */
|
|
54
|
+
enabled: boolean;
|
|
55
|
+
/** Page size */
|
|
56
|
+
pageSize: number;
|
|
57
|
+
/** Current page number */
|
|
58
|
+
currentPage: number;
|
|
59
|
+
/** Auto-load next page when scrolling */
|
|
60
|
+
autoLoad?: boolean;
|
|
61
|
+
/** Cursor for pagination */
|
|
62
|
+
cursor?: any;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Cache configuration
|
|
66
|
+
*/
|
|
67
|
+
export interface CacheConfig {
|
|
68
|
+
/** Enable caching */
|
|
69
|
+
enabled: boolean;
|
|
70
|
+
/** Cache duration in milliseconds */
|
|
71
|
+
ttl: number;
|
|
72
|
+
/** Maximum cache size */
|
|
73
|
+
maxSize?: number;
|
|
74
|
+
/** Cache key strategy */
|
|
75
|
+
keyStrategy?: 'path' | 'query' | 'custom';
|
|
76
|
+
/** Custom cache key function */
|
|
77
|
+
customKey?: (path: string, constraints: QueryConstraint[]) => string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Error handling configuration
|
|
81
|
+
*/
|
|
82
|
+
export interface ErrorHandlingConfig {
|
|
83
|
+
/** Enable automatic retry on errors */
|
|
84
|
+
autoRetry?: boolean;
|
|
85
|
+
/** Maximum retry attempts */
|
|
86
|
+
maxRetries?: number;
|
|
87
|
+
/** Retry delay in milliseconds */
|
|
88
|
+
retryDelay?: number;
|
|
89
|
+
/** Custom error handler */
|
|
90
|
+
onError?: (error: CollectionError) => void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Query constraint builder interface
|
|
94
|
+
*/
|
|
95
|
+
export interface QueryBuilder<T> {
|
|
96
|
+
/** Add where constraint */
|
|
97
|
+
where(field: string, operator: FirestoreOperator, value: any): QueryBuilder<T>;
|
|
98
|
+
/** Add orderBy constraint */
|
|
99
|
+
orderBy(field: string, direction?: 'asc' | 'desc'): QueryBuilder<T>;
|
|
100
|
+
/** Add limit constraint */
|
|
101
|
+
limit(count: number): QueryBuilder<T>;
|
|
102
|
+
/** Add startAt constraint */
|
|
103
|
+
startAt(...values: any[]): QueryBuilder<T>;
|
|
104
|
+
/** Add startAfter constraint */
|
|
105
|
+
startAfter(...values: any[]): QueryBuilder<T>;
|
|
106
|
+
/** Add endAt constraint */
|
|
107
|
+
endAt(...values: any[]): QueryBuilder<T>;
|
|
108
|
+
/** Add endBefore constraint */
|
|
109
|
+
endBefore(...values: any[]): QueryBuilder<T>;
|
|
110
|
+
/** Build the query */
|
|
111
|
+
build(): QueryConstraint[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Firestore query operators
|
|
115
|
+
*/
|
|
116
|
+
export type FirestoreOperator = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'array-contains' | 'array-contains-any' | 'in' | 'not-in';
|
|
117
|
+
/**
|
|
118
|
+
* Collection change types
|
|
119
|
+
*/
|
|
120
|
+
export type CollectionChangeType = 'added' | 'modified' | 'removed';
|
|
121
|
+
/**
|
|
122
|
+
* Document change information
|
|
123
|
+
*/
|
|
124
|
+
export interface DocumentChange<T> {
|
|
125
|
+
/** Type of change */
|
|
126
|
+
type: CollectionChangeType;
|
|
127
|
+
/** Document data */
|
|
128
|
+
doc: T;
|
|
129
|
+
/** Old index in collection */
|
|
130
|
+
oldIndex: number;
|
|
131
|
+
/** New index in collection */
|
|
132
|
+
newIndex: number;
|
|
133
|
+
/** Change timestamp */
|
|
134
|
+
timestamp: Date;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Collection event types
|
|
138
|
+
*/
|
|
139
|
+
export type CollectionEventType = 'data_changed' | 'document_added' | 'document_modified' | 'document_removed' | 'error' | 'loading_started' | 'loading_finished' | 'query_changed' | 'cache_hit' | 'cache_miss';
|
|
140
|
+
/**
|
|
141
|
+
* Collection event interface
|
|
142
|
+
*/
|
|
143
|
+
export interface CollectionEvent<T> {
|
|
144
|
+
/** Event type */
|
|
145
|
+
type: CollectionEventType;
|
|
146
|
+
/** Event data */
|
|
147
|
+
data?: any;
|
|
148
|
+
/** Document changes */
|
|
149
|
+
changes?: DocumentChange<T>[];
|
|
150
|
+
/** Error if applicable */
|
|
151
|
+
error?: CollectionError;
|
|
152
|
+
/** Event timestamp */
|
|
153
|
+
timestamp: Date;
|
|
154
|
+
/** Collection path */
|
|
155
|
+
path?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Collection event callback function type
|
|
159
|
+
*/
|
|
160
|
+
export type CollectionEventCallback<T> = (event: CollectionEvent<T>) => void;
|
|
161
|
+
/**
|
|
162
|
+
* Collection metadata interface
|
|
163
|
+
*/
|
|
164
|
+
export interface CollectionMetadata {
|
|
165
|
+
/** Whether data is from cache */
|
|
166
|
+
fromCache: boolean;
|
|
167
|
+
/** Whether there are pending writes */
|
|
168
|
+
hasPendingWrites: boolean;
|
|
169
|
+
/** Sync state */
|
|
170
|
+
syncState: 'synced' | 'local' | 'unknown';
|
|
171
|
+
/** Last sync timestamp */
|
|
172
|
+
lastSyncTime?: Date;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Collection statistics
|
|
176
|
+
*/
|
|
177
|
+
export interface CollectionStats {
|
|
178
|
+
/** Total number of documents */
|
|
179
|
+
totalDocuments: number;
|
|
180
|
+
/** Number of read operations */
|
|
181
|
+
readCount: number;
|
|
182
|
+
/** Number of write operations */
|
|
183
|
+
writeCount: number;
|
|
184
|
+
/** Cache hit rate */
|
|
185
|
+
cacheHitRate: number;
|
|
186
|
+
/** Average query time */
|
|
187
|
+
averageQueryTime: number;
|
|
188
|
+
/** Last activity timestamp */
|
|
189
|
+
lastActivity: Date;
|
|
190
|
+
/** Memory usage in bytes */
|
|
191
|
+
memoryUsage: number;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Collection error codes enum
|
|
195
|
+
*/
|
|
196
|
+
export declare enum CollectionErrorCode {
|
|
197
|
+
PERMISSION_DENIED = "collection/permission-denied",
|
|
198
|
+
NOT_FOUND = "collection/not-found",
|
|
199
|
+
ALREADY_EXISTS = "collection/already-exists",
|
|
200
|
+
RESOURCE_EXHAUSTED = "collection/resource-exhausted",
|
|
201
|
+
FAILED_PRECONDITION = "collection/failed-precondition",
|
|
202
|
+
ABORTED = "collection/aborted",
|
|
203
|
+
OUT_OF_RANGE = "collection/out-of-range",
|
|
204
|
+
UNIMPLEMENTED = "collection/unimplemented",
|
|
205
|
+
INTERNAL_ERROR = "collection/internal",
|
|
206
|
+
UNAVAILABLE = "collection/unavailable",
|
|
207
|
+
DATA_LOSS = "collection/data-loss",
|
|
208
|
+
UNAUTHENTICATED = "collection/unauthenticated",
|
|
209
|
+
DEADLINE_EXCEEDED = "collection/deadline-exceeded",
|
|
210
|
+
CANCELLED = "collection/cancelled",
|
|
211
|
+
NETWORK_ERROR = "collection/network-error",
|
|
212
|
+
OFFLINE = "collection/offline",
|
|
213
|
+
INVALID_QUERY = "collection/invalid-query",
|
|
214
|
+
QUERY_TOO_COMPLEX = "collection/query-too-complex",
|
|
215
|
+
MISSING_INDEX = "collection/missing-index",
|
|
216
|
+
INVALID_ARGUMENT = "collection/invalid-argument",
|
|
217
|
+
COLLECTION_UNAVAILABLE = "collection/collection-unavailable",
|
|
218
|
+
REFERENCE_UNAVAILABLE = "collection/reference-unavailable",
|
|
219
|
+
LISTENER_ERROR = "collection/listener-error",
|
|
220
|
+
CACHE_ERROR = "collection/cache-error",
|
|
221
|
+
CACHE_FULL = "collection/cache-full",
|
|
222
|
+
CACHE_CORRUPTED = "collection/cache-corrupted",
|
|
223
|
+
PAGINATION_ERROR = "collection/pagination-error",
|
|
224
|
+
INVALID_CURSOR = "collection/invalid-cursor",
|
|
225
|
+
TRANSFORM_ERROR = "collection/transform-error",
|
|
226
|
+
FILTER_ERROR = "collection/filter-error",
|
|
227
|
+
UNKNOWN = "collection/unknown"
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Custom collection error class
|
|
231
|
+
*/
|
|
232
|
+
export declare class CollectionError extends Error {
|
|
233
|
+
code: CollectionErrorCode;
|
|
234
|
+
path?: string | undefined;
|
|
235
|
+
query?: QueryConstraint[] | undefined;
|
|
236
|
+
originalError?: any | undefined;
|
|
237
|
+
context?: Record<string, any> | undefined;
|
|
238
|
+
constructor(code: CollectionErrorCode, message: string, path?: string | undefined, query?: QueryConstraint[] | undefined, originalError?: any | undefined, context?: Record<string, any> | undefined);
|
|
239
|
+
/**
|
|
240
|
+
* Get user-friendly error message
|
|
241
|
+
*/
|
|
242
|
+
getFriendlyMessage(): string;
|
|
243
|
+
/**
|
|
244
|
+
* Check if error is retryable
|
|
245
|
+
*/
|
|
246
|
+
isRetryable(): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Check if error requires user authentication
|
|
249
|
+
*/
|
|
250
|
+
requiresAuth(): boolean;
|
|
251
|
+
/**
|
|
252
|
+
* Check if error is related to query issues
|
|
253
|
+
*/
|
|
254
|
+
isQueryError(): boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Check if error is network related
|
|
257
|
+
*/
|
|
258
|
+
isNetworkError(): boolean;
|
|
259
|
+
/**
|
|
260
|
+
* Convert to JSON for logging/debugging
|
|
261
|
+
*/
|
|
262
|
+
toJSON(): Record<string, any>;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Collection subscription interface
|
|
266
|
+
*/
|
|
267
|
+
export interface CollectionSubscription {
|
|
268
|
+
/** Unsubscribe from collection changes */
|
|
269
|
+
unsubscribe: () => void;
|
|
270
|
+
/** Whether subscription is active */
|
|
271
|
+
active: boolean;
|
|
272
|
+
/** Subscription configuration */
|
|
273
|
+
config: CollectionOptions;
|
|
274
|
+
/** Subscription statistics */
|
|
275
|
+
stats: CollectionStats;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Collection query result interface
|
|
279
|
+
*/
|
|
280
|
+
export interface CollectionQueryResult<T> {
|
|
281
|
+
/** Query result documents */
|
|
282
|
+
docs: T[];
|
|
283
|
+
/** Query metadata */
|
|
284
|
+
metadata: CollectionMetadata;
|
|
285
|
+
/** Total count (if available) */
|
|
286
|
+
totalCount?: number;
|
|
287
|
+
/** Whether there are more documents */
|
|
288
|
+
hasMore?: boolean;
|
|
289
|
+
/** Next page cursor */
|
|
290
|
+
nextCursor?: any;
|
|
291
|
+
/** Previous page cursor */
|
|
292
|
+
prevCursor?: any;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Collection aggregation result
|
|
296
|
+
*/
|
|
297
|
+
export interface CollectionAggregation {
|
|
298
|
+
/** Count of documents */
|
|
299
|
+
count?: number;
|
|
300
|
+
/** Sum of numeric field */
|
|
301
|
+
sum?: number;
|
|
302
|
+
/** Average of numeric field */
|
|
303
|
+
average?: number;
|
|
304
|
+
/** Minimum value */
|
|
305
|
+
min?: any;
|
|
306
|
+
/** Maximum value */
|
|
307
|
+
max?: any;
|
|
308
|
+
/** Custom aggregation results */
|
|
309
|
+
custom?: Record<string, any>;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Real-time collection listener configuration
|
|
313
|
+
*/
|
|
314
|
+
export interface ListenerConfig {
|
|
315
|
+
/** Include metadata changes */
|
|
316
|
+
includeMetadata?: boolean;
|
|
317
|
+
/** Custom error handler */
|
|
318
|
+
onError?: (error: CollectionError) => void;
|
|
319
|
+
/** Custom data handler */
|
|
320
|
+
onData?: (data: any[]) => void;
|
|
321
|
+
/** Custom change handler */
|
|
322
|
+
onChange?: (changes: DocumentChange<any>[]) => void;
|
|
323
|
+
/** Whether to automatically retry on connection issues */
|
|
324
|
+
autoRetry?: boolean;
|
|
325
|
+
/** Retry configuration */
|
|
326
|
+
retryConfig?: {
|
|
327
|
+
maxAttempts: number;
|
|
328
|
+
baseDelay: number;
|
|
329
|
+
maxDelay: number;
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Collection performance metrics
|
|
334
|
+
*/
|
|
335
|
+
export interface CollectionPerformanceMetrics {
|
|
336
|
+
/** Query execution time in milliseconds */
|
|
337
|
+
queryTime: number;
|
|
338
|
+
/** Network latency */
|
|
339
|
+
networkLatency: number;
|
|
340
|
+
/** Cache performance */
|
|
341
|
+
cachePerformance: {
|
|
342
|
+
hits: number;
|
|
343
|
+
misses: number;
|
|
344
|
+
hitRate: number;
|
|
345
|
+
};
|
|
346
|
+
/** Memory usage */
|
|
347
|
+
memoryUsage: {
|
|
348
|
+
current: number;
|
|
349
|
+
peak: number;
|
|
350
|
+
average: number;
|
|
351
|
+
};
|
|
352
|
+
/** Document processing time */
|
|
353
|
+
processingTime: number;
|
|
354
|
+
/** Listener performance */
|
|
355
|
+
listenerPerformance: {
|
|
356
|
+
updateFrequency: number;
|
|
357
|
+
averageUpdateTime: number;
|
|
358
|
+
totalUpdates: number;
|
|
359
|
+
};
|
|
360
|
+
}
|