nexabase-console 1.1.4 → 2.0.0

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 (72) hide show
  1. package/README.md +33 -8
  2. package/dist/app/NexaApp.d.ts +63 -0
  3. package/dist/app/NexaApp.js +184 -0
  4. package/dist/app/initializeApp.d.ts +8 -0
  5. package/dist/app/initializeApp.js +27 -0
  6. package/dist/auth/Auth.d.ts +21 -0
  7. package/dist/auth/Auth.js +73 -0
  8. package/dist/auth/authTypes.d.ts +1 -0
  9. package/dist/auth/authTypes.js +2 -0
  10. package/dist/auth/persistence.d.ts +9 -0
  11. package/dist/auth/persistence.js +34 -0
  12. package/dist/errors/NexaError.d.ts +7 -0
  13. package/dist/errors/NexaError.js +61 -0
  14. package/dist/firestore/CollectionReference.d.ts +3 -0
  15. package/dist/firestore/CollectionReference.js +7 -0
  16. package/dist/firestore/DocumentReference.d.ts +3 -0
  17. package/dist/firestore/DocumentReference.js +22 -0
  18. package/dist/firestore/FieldPath.d.ts +7 -0
  19. package/dist/firestore/FieldPath.js +23 -0
  20. package/dist/firestore/FieldValue.d.ts +11 -0
  21. package/dist/firestore/FieldValue.js +21 -0
  22. package/dist/firestore/Firestore.d.ts +8 -0
  23. package/dist/firestore/Firestore.js +24 -0
  24. package/dist/firestore/GeoPoint.d.ts +10 -0
  25. package/dist/firestore/GeoPoint.js +22 -0
  26. package/dist/firestore/Query.d.ts +4 -0
  27. package/dist/firestore/Query.js +172 -0
  28. package/dist/firestore/Snapshot.d.ts +6 -0
  29. package/dist/firestore/Snapshot.js +126 -0
  30. package/dist/firestore/SnapshotManager.d.ts +9 -0
  31. package/dist/firestore/SnapshotManager.js +37 -0
  32. package/dist/firestore/Timestamp.d.ts +16 -0
  33. package/dist/firestore/Timestamp.js +36 -0
  34. package/dist/firestore/batch.d.ts +3 -0
  35. package/dist/firestore/batch.js +79 -0
  36. package/dist/firestore/queryConstraints.d.ts +9 -0
  37. package/dist/firestore/queryConstraints.js +31 -0
  38. package/dist/firestore/transaction.d.ts +5 -0
  39. package/dist/firestore/transaction.js +71 -0
  40. package/dist/firestore/writes.d.ts +15 -0
  41. package/dist/firestore/writes.js +146 -0
  42. package/dist/index.d.ts +34 -206
  43. package/dist/index.js +56 -1022
  44. package/dist/persistence/IndexedDB.d.ts +8 -0
  45. package/dist/persistence/IndexedDB.js +37 -0
  46. package/dist/persistence/LocalStore.d.ts +12 -0
  47. package/dist/persistence/LocalStore.js +78 -0
  48. package/dist/persistence/MutationQueue.d.ts +22 -0
  49. package/dist/persistence/MutationQueue.js +145 -0
  50. package/dist/realtime/RealtimeConnection.d.ts +7 -0
  51. package/dist/realtime/RealtimeConnection.js +19 -0
  52. package/dist/realtime/RealtimeDatabase.d.ts +10 -0
  53. package/dist/realtime/RealtimeDatabase.js +62 -0
  54. package/dist/storage/Storage.d.ts +12 -0
  55. package/dist/storage/Storage.js +41 -0
  56. package/dist/storage/StorageReference.d.ts +13 -0
  57. package/dist/storage/StorageReference.js +20 -0
  58. package/dist/storage/UploadTask.d.ts +10 -0
  59. package/dist/storage/UploadTask.js +22 -0
  60. package/dist/sync/ConflictResolver.d.ts +3 -0
  61. package/dist/sync/ConflictResolver.js +24 -0
  62. package/dist/sync/SyncEngine.d.ts +13 -0
  63. package/dist/sync/SyncEngine.js +47 -0
  64. package/dist/transport/HttpClient.d.ts +8 -0
  65. package/dist/transport/HttpClient.js +42 -0
  66. package/dist/transport/SSEClient.d.ts +15 -0
  67. package/dist/transport/SSEClient.js +96 -0
  68. package/dist/types/index.d.ts +150 -0
  69. package/dist/types/index.js +2 -0
  70. package/dist/utils/helpers.d.ts +7 -0
  71. package/dist/utils/helpers.js +124 -0
  72. package/package.json +1 -1
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteField = exports.arrayRemove = exports.arrayUnion = exports.increment = exports.serverTimestamp = exports.FieldValue = void 0;
4
+ class FieldValue {
5
+ constructor(method, value) {
6
+ this.method = method;
7
+ this.value = value;
8
+ this._isFieldValue = true;
9
+ }
10
+ }
11
+ exports.FieldValue = FieldValue;
12
+ const serverTimestamp = () => new FieldValue('serverTimestamp');
13
+ exports.serverTimestamp = serverTimestamp;
14
+ const increment = (n) => new FieldValue('increment', n);
15
+ exports.increment = increment;
16
+ const arrayUnion = (...elements) => new FieldValue('arrayUnion', elements);
17
+ exports.arrayUnion = arrayUnion;
18
+ const arrayRemove = (...elements) => new FieldValue('arrayRemove', elements);
19
+ exports.arrayRemove = arrayRemove;
20
+ const deleteField = () => new FieldValue('deleteField');
21
+ exports.deleteField = deleteField;
@@ -0,0 +1,8 @@
1
+ import { NexaApp } from '../app/NexaApp';
2
+ export declare class Firestore {
3
+ private app;
4
+ constructor(app: NexaApp);
5
+ getApp(): NexaApp;
6
+ }
7
+ export declare const enableIndexedDbPersistence: (db: NexaApp) => Promise<void>;
8
+ export declare const enableOfflinePersistence: (db: NexaApp) => Promise<void>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enableOfflinePersistence = exports.enableIndexedDbPersistence = exports.Firestore = void 0;
4
+ class Firestore {
5
+ constructor(app) {
6
+ this.app = app;
7
+ }
8
+ getApp() {
9
+ return this.app;
10
+ }
11
+ }
12
+ exports.Firestore = Firestore;
13
+ const enableIndexedDbPersistence = async (db) => {
14
+ db.enablePersistence = true;
15
+ if (db._initPromise)
16
+ await db._initPromise;
17
+ };
18
+ exports.enableIndexedDbPersistence = enableIndexedDbPersistence;
19
+ const enableOfflinePersistence = async (db) => {
20
+ db.enablePersistence = true;
21
+ if (db._initPromise)
22
+ await db._initPromise;
23
+ };
24
+ exports.enableOfflinePersistence = enableOfflinePersistence;
@@ -0,0 +1,10 @@
1
+ export declare class GeoPoint {
2
+ readonly latitude: number;
3
+ readonly longitude: number;
4
+ constructor(latitude: number, longitude: number);
5
+ isEqual(other: GeoPoint): boolean;
6
+ toJSON(): {
7
+ latitude: number;
8
+ longitude: number;
9
+ };
10
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GeoPoint = void 0;
4
+ class GeoPoint {
5
+ constructor(latitude, longitude) {
6
+ this.latitude = latitude;
7
+ this.longitude = longitude;
8
+ if (isNaN(latitude) || latitude < -90 || latitude > 90) {
9
+ throw new Error(`Latitude must be a number between -90 and 90, but got ${latitude}`);
10
+ }
11
+ if (isNaN(longitude) || longitude < -180 || longitude > 180) {
12
+ throw new Error(`Longitude must be a number between -180 and 180, but got ${longitude}`);
13
+ }
14
+ }
15
+ isEqual(other) {
16
+ return this.latitude === other.latitude && this.longitude === other.longitude;
17
+ }
18
+ toJSON() {
19
+ return { latitude: this.latitude, longitude: this.longitude };
20
+ }
21
+ }
22
+ exports.GeoPoint = GeoPoint;
@@ -0,0 +1,4 @@
1
+ import { CollectionReference, Query, QueryConstraint, QuerySnapshot } from '../types/index';
2
+ export declare const query: <T = any>(queryObject: Query<T> | CollectionReference<T>, ...queryConstraints: QueryConstraint[]) => Query<T>;
3
+ export declare const getCachedDocs: <T = any>(queryOrCollection: Query<T> | CollectionReference<T>) => QuerySnapshot<T>;
4
+ export declare const getDocs: <T = any>(queryOrCollection: Query<T> | CollectionReference<T>) => Promise<QuerySnapshot<T>>;
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDocs = exports.getCachedDocs = exports.query = void 0;
4
+ const SnapshotManager_1 = require("./SnapshotManager");
5
+ const DocumentReference_1 = require("./DocumentReference");
6
+ const NexaError_1 = require("../errors/NexaError");
7
+ const helpers_1 = require("../utils/helpers");
8
+ const query = (queryObject, ...queryConstraints) => {
9
+ const q = {
10
+ type: 'query',
11
+ path: queryObject.path,
12
+ db: queryObject.db,
13
+ constraints: queryObject.type === 'query' ? [...(queryObject.constraints || [])] : []
14
+ };
15
+ q.constraints = [...(q.constraints || []), ...queryConstraints];
16
+ return q;
17
+ };
18
+ exports.query = query;
19
+ const getCachedDocs = (queryOrCollection) => {
20
+ const db = queryOrCollection.db;
21
+ const collectionPath = queryOrCollection.path;
22
+ const constraints = 'constraints' in queryOrCollection ? queryOrCollection.constraints || [] : [];
23
+ const results = [];
24
+ Object.keys(db._firestoreCache).forEach((p) => {
25
+ if (p.startsWith(collectionPath + '/')) {
26
+ const parts = p.split('/');
27
+ const docId = parts[parts.length - 1];
28
+ const docRef = (0, DocumentReference_1.doc)(db, `${collectionPath}/${docId}`);
29
+ const cachedData = db._firestoreCache[p];
30
+ results.push({
31
+ id: docId,
32
+ ref: docRef,
33
+ metadata: { fromCache: true, hasPendingWrites: db.hasPendingWrites(docRef.path) },
34
+ exists: () => true,
35
+ data: () => cachedData,
36
+ get: (fieldPath) => (0, helpers_1.getNestedValue)(cachedData, fieldPath, docId)
37
+ });
38
+ }
39
+ });
40
+ let filtered = results;
41
+ let limitCount = undefined;
42
+ for (const c of constraints) {
43
+ if (c.type === 'where' && c.fieldPath && c.opStr) {
44
+ filtered = filtered.filter((docItem) => {
45
+ const val = (0, helpers_1.getNestedValue)(docItem.data(), c.fieldPath, docItem.id);
46
+ if (c.opStr === '==')
47
+ return val === c.value;
48
+ if (c.opStr === '>')
49
+ return val > c.value;
50
+ if (c.opStr === '<')
51
+ return val < c.value;
52
+ if (c.opStr === '>=')
53
+ return val >= c.value;
54
+ if (c.opStr === '<=')
55
+ return val <= c.value;
56
+ if (c.opStr === '!=')
57
+ return val !== c.value;
58
+ if (c.opStr === 'in')
59
+ return Array.isArray(c.value) && c.value.includes(val);
60
+ if (c.opStr === 'not-in')
61
+ return Array.isArray(c.value) && !c.value.includes(val);
62
+ if (c.opStr === 'array-contains')
63
+ return Array.isArray(val) && val.includes(c.value);
64
+ if (c.opStr === 'array-contains-any')
65
+ return Array.isArray(val) && Array.isArray(c.value) && c.value.some((v) => val.includes(v));
66
+ return true;
67
+ });
68
+ }
69
+ else if (c.type === 'orderBy' && c.fieldPath) {
70
+ filtered = [...filtered].sort((a, b) => {
71
+ const valA = (0, helpers_1.getNestedValue)(a.data(), c.fieldPath, a.id);
72
+ const valB = (0, helpers_1.getNestedValue)(b.data(), c.fieldPath, b.id);
73
+ if (valA < valB)
74
+ return c.directionStr === 'desc' ? 1 : -1;
75
+ if (valA > valB)
76
+ return c.directionStr === 'desc' ? -1 : 1;
77
+ return 0;
78
+ });
79
+ }
80
+ }
81
+ for (const c of constraints) {
82
+ if (['startAt', 'startAfter', 'endAt', 'endBefore'].includes(c.type)) {
83
+ const isSnapshot = c.docSnapshot && typeof c.docSnapshot === 'object' && 'id' in c.docSnapshot;
84
+ const cursorIndex = filtered.findIndex((d) => (isSnapshot ? d.id === c.docSnapshot.id : d.id === c.docSnapshot));
85
+ if (cursorIndex !== -1) {
86
+ if (c.type === 'startAt')
87
+ filtered = filtered.slice(cursorIndex);
88
+ if (c.type === 'startAfter')
89
+ filtered = filtered.slice(cursorIndex + 1);
90
+ if (c.type === 'endAt')
91
+ filtered = filtered.slice(0, cursorIndex + 1);
92
+ if (c.type === 'endBefore')
93
+ filtered = filtered.slice(0, cursorIndex);
94
+ }
95
+ }
96
+ else if (c.type === 'limit' && typeof c.limitValue === 'number') {
97
+ limitCount = c.limitValue;
98
+ }
99
+ }
100
+ if (limitCount !== undefined) {
101
+ filtered = filtered.slice(0, limitCount);
102
+ }
103
+ return SnapshotManager_1.SnapshotManager.createQuerySnapshot(filtered, true, db.hasPendingWrites(collectionPath));
104
+ };
105
+ exports.getCachedDocs = getCachedDocs;
106
+ const getDocs = async (queryOrCollection) => {
107
+ const db = queryOrCollection.db;
108
+ if (db._initPromise)
109
+ await db._initPromise;
110
+ const collectionPath = queryOrCollection.path;
111
+ const constraints = 'constraints' in queryOrCollection ? queryOrCollection.constraints || [] : [];
112
+ if (db.cacheStrategy === 'cache-first') {
113
+ const cached = (0, exports.getCachedDocs)(queryOrCollection);
114
+ if (cached && !cached.empty) {
115
+ db.client
116
+ .post(`/api/firestore/${db.projectId}/query`, { collectionPath, constraints })
117
+ .then(async (res) => {
118
+ const docs = res.data.documents || [];
119
+ const serverIds = new Set(docs.map((d) => d.id));
120
+ for (const d of docs) {
121
+ await db._setCache(`${collectionPath}/${d.id}`, d.fields);
122
+ }
123
+ for (const cachePath of Object.keys(db._firestoreCache)) {
124
+ if (cachePath.startsWith(collectionPath + '/')) {
125
+ const docId = cachePath.split('/').pop();
126
+ if (docId && !serverIds.has(docId)) {
127
+ await db._deleteCache(cachePath);
128
+ }
129
+ }
130
+ }
131
+ db._notifySnapshotCallbacks(collectionPath, 'bulk_update', null);
132
+ })
133
+ .catch(() => { });
134
+ return cached;
135
+ }
136
+ }
137
+ try {
138
+ const res = await db.client.post(`/api/firestore/${db.projectId}/query`, { collectionPath, constraints });
139
+ const docs = res.data.documents || [];
140
+ const serverIds = new Set(docs.map((d) => d.id));
141
+ for (const d of docs) {
142
+ await db._setCache(`${collectionPath}/${d.id}`, d.fields);
143
+ }
144
+ for (const cachePath of Object.keys(db._firestoreCache)) {
145
+ if (cachePath.startsWith(collectionPath + '/')) {
146
+ const docId = cachePath.split('/').pop();
147
+ if (docId && !serverIds.has(docId)) {
148
+ await db._deleteCache(cachePath);
149
+ }
150
+ }
151
+ }
152
+ const docsArray = docs.map((d) => {
153
+ const docRef = (0, DocumentReference_1.doc)(db, `${collectionPath}/${d.id}`);
154
+ return {
155
+ id: d.id,
156
+ ref: docRef,
157
+ metadata: { fromCache: false, hasPendingWrites: db.hasPendingWrites(docRef.path) },
158
+ exists: () => true,
159
+ data: () => d.fields,
160
+ get: (fieldPath) => (0, helpers_1.getNestedValue)(d.fields, fieldPath, d.id)
161
+ };
162
+ });
163
+ return SnapshotManager_1.SnapshotManager.createQuerySnapshot(docsArray, false, db.hasPendingWrites(collectionPath));
164
+ }
165
+ catch (err) {
166
+ if (err && err.response && err.response.status < 500) {
167
+ throw (0, NexaError_1.toNexaError)(err);
168
+ }
169
+ return (0, exports.getCachedDocs)(queryOrCollection);
170
+ }
171
+ };
172
+ exports.getDocs = getDocs;
@@ -0,0 +1,6 @@
1
+ import { SnapshotManager } from './SnapshotManager';
2
+ import { CollectionReference, DocumentReference, Query, DocumentSnapshot } from '../types/index';
3
+ export declare const getCachedDoc: <T = any>(docRef: DocumentReference<T>) => DocumentSnapshot<T>;
4
+ export declare const getDoc: <T = any>(docRef: DocumentReference<T>) => Promise<DocumentSnapshot<T>>;
5
+ export declare const onSnapshot: (ref: CollectionReference | DocumentReference | Query, callback: (snapshot: any) => void) => (() => void);
6
+ export { SnapshotManager };
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnapshotManager = exports.onSnapshot = exports.getDoc = exports.getCachedDoc = void 0;
4
+ const SnapshotManager_1 = require("./SnapshotManager");
5
+ Object.defineProperty(exports, "SnapshotManager", { enumerable: true, get: function () { return SnapshotManager_1.SnapshotManager; } });
6
+ const Query_1 = require("./Query");
7
+ const NexaError_1 = require("../errors/NexaError");
8
+ const helpers_1 = require("../utils/helpers");
9
+ const getCachedDoc = (docRef) => {
10
+ const db = docRef.db;
11
+ const data = (db._firestoreCache[docRef.path] || null);
12
+ return SnapshotManager_1.SnapshotManager.createDocumentSnapshot(docRef, data, true, db.hasPendingWrites(docRef.path));
13
+ };
14
+ exports.getCachedDoc = getCachedDoc;
15
+ const getDoc = async (docRef) => {
16
+ const db = docRef.db;
17
+ if (db._initPromise)
18
+ await db._initPromise;
19
+ if (db.cacheStrategy === 'cache-first') {
20
+ const cached = (0, exports.getCachedDoc)(docRef);
21
+ if (cached && cached.exists()) {
22
+ db.client
23
+ .get(`/api/firestore/${db.projectId}/document?docPath=${encodeURIComponent(docRef.path)}`)
24
+ .then(async (res) => {
25
+ const data = res.data.data;
26
+ await db._setCache(docRef.path, data);
27
+ db._notifySnapshotCallbacks(docRef.path, 'document_written', data);
28
+ })
29
+ .catch(() => { });
30
+ return cached;
31
+ }
32
+ }
33
+ try {
34
+ const res = await db.client.get(`/api/firestore/${db.projectId}/document?docPath=${encodeURIComponent(docRef.path)}`);
35
+ const data = res.data.data;
36
+ await db._setCache(docRef.path, data);
37
+ return SnapshotManager_1.SnapshotManager.createDocumentSnapshot(docRef, data, false, db.hasPendingWrites(docRef.path));
38
+ }
39
+ catch (err) {
40
+ if (err && err.response && err.response.status < 500) {
41
+ throw (0, NexaError_1.toNexaError)(err);
42
+ }
43
+ return (0, exports.getCachedDoc)(docRef);
44
+ }
45
+ };
46
+ exports.getDoc = getDoc;
47
+ const onSnapshot = (ref, callback) => {
48
+ const db = ref.db;
49
+ let active = true;
50
+ const pathKey = ref.path;
51
+ const listenerId = Math.random().toString(36).substring(2, 9);
52
+ const keyToClean = `${ref.type}_${listenerId}_${pathKey}`;
53
+ let isInitial = true;
54
+ let lastData = undefined;
55
+ let lastDocsForChanges = [];
56
+ const triggerCallback = () => {
57
+ if (!active)
58
+ return;
59
+ try {
60
+ if (ref.type === 'collection' || ref.type === 'query') {
61
+ const cached = (0, Query_1.getCachedDocs)(ref);
62
+ const newData = cached.docs.map((d) => ({ id: d.id, data: d.data() }));
63
+ if (!(0, helpers_1.deepEqual)(newData, lastData)) {
64
+ const currentDocsForChanges = cached.docs.map((d) => ({ id: d.id, data: d.data(), doc: d }));
65
+ const snapshotWithChanges = SnapshotManager_1.SnapshotManager.createQuerySnapshot(cached.docs, true, db.hasPendingWrites(ref.path), lastDocsForChanges);
66
+ lastDocsForChanges = currentDocsForChanges;
67
+ callback(snapshotWithChanges);
68
+ lastData = newData;
69
+ }
70
+ }
71
+ else {
72
+ const cached = (0, exports.getCachedDoc)(ref);
73
+ const newData = cached.exists() ? { id: cached.id, data: cached.data() } : null;
74
+ if (!(0, helpers_1.deepEqual)(newData, lastData)) {
75
+ callback(cached);
76
+ lastData = newData;
77
+ }
78
+ }
79
+ }
80
+ catch (e) { }
81
+ };
82
+ db._snapshotCallbacks[keyToClean] = triggerCallback;
83
+ triggerCallback();
84
+ db._ensureFirestoreSSE();
85
+ (async () => {
86
+ if (db._initPromise)
87
+ await db._initPromise;
88
+ if (!active)
89
+ return;
90
+ if (isInitial) {
91
+ isInitial = false;
92
+ try {
93
+ if (ref.type === 'collection' || ref.type === 'query') {
94
+ const docs = await (0, Query_1.getDocs)(ref);
95
+ const newData = docs.docs.map((d) => ({ id: d.id, data: d.data() }));
96
+ if (!(0, helpers_1.deepEqual)(newData, lastData) && active) {
97
+ const currentDocsForChanges = docs.docs.map((d) => ({ id: d.id, data: d.data(), doc: d }));
98
+ const snapshotWithChanges = SnapshotManager_1.SnapshotManager.createQuerySnapshot(docs.docs, false, db.hasPendingWrites(ref.path), lastDocsForChanges);
99
+ lastDocsForChanges = currentDocsForChanges;
100
+ callback(snapshotWithChanges);
101
+ lastData = newData;
102
+ }
103
+ }
104
+ else {
105
+ const docData = await (0, exports.getDoc)(ref);
106
+ const newData = docData.exists() ? { id: docData.id, data: docData.data() } : null;
107
+ if (!(0, helpers_1.deepEqual)(newData, lastData) && active) {
108
+ callback(docData);
109
+ lastData = newData;
110
+ }
111
+ }
112
+ }
113
+ catch (e) { }
114
+ }
115
+ })();
116
+ return () => {
117
+ active = false;
118
+ if (keyToClean) {
119
+ delete db._snapshotCallbacks[keyToClean];
120
+ if (Object.keys(db._snapshotCallbacks).length === 0) {
121
+ db._closeFirestoreSSEIfIdle();
122
+ }
123
+ }
124
+ };
125
+ };
126
+ exports.onSnapshot = onSnapshot;
@@ -0,0 +1,9 @@
1
+ import { DocumentReference, DocumentSnapshot, QueryDocumentSnapshot, QuerySnapshot } from '../types/index';
2
+ export declare class SnapshotManager {
3
+ static createDocumentSnapshot<T = any>(docRef: DocumentReference<T>, data: T | null, fromCache: boolean, hasPendingWrites: boolean): DocumentSnapshot<T>;
4
+ static createQuerySnapshot<T = any>(docs: QueryDocumentSnapshot<T>[], fromCache: boolean, hasPendingWrites: boolean, previousDocs?: {
5
+ id: string;
6
+ data: any;
7
+ doc: QueryDocumentSnapshot<T>;
8
+ }[]): QuerySnapshot<T>;
9
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnapshotManager = void 0;
4
+ const helpers_1 = require("../utils/helpers");
5
+ class SnapshotManager {
6
+ static createDocumentSnapshot(docRef, data, fromCache, hasPendingWrites) {
7
+ const segments = docRef.path.split('/');
8
+ const docId = segments[segments.length - 1];
9
+ return {
10
+ id: docId,
11
+ ref: docRef,
12
+ metadata: { fromCache, hasPendingWrites },
13
+ exists: () => data !== null && data !== undefined,
14
+ data: () => data,
15
+ get: (fieldPath) => (0, helpers_1.getNestedValue)(data, fieldPath, docId)
16
+ };
17
+ }
18
+ static createQuerySnapshot(docs, fromCache, hasPendingWrites, previousDocs) {
19
+ const currentDocsForChanges = docs.map((d) => ({
20
+ id: d.id,
21
+ data: d.data(),
22
+ doc: d
23
+ }));
24
+ const changes = previousDocs
25
+ ? (0, helpers_1.calculateDocChanges)(previousDocs, currentDocsForChanges)
26
+ : docs.map((d, i) => ({ type: 'added', doc: d, oldIndex: -1, newIndex: i }));
27
+ return {
28
+ docs,
29
+ forEach: (cb) => docs.forEach(cb),
30
+ empty: docs.length === 0,
31
+ size: docs.length,
32
+ metadata: { fromCache, hasPendingWrites },
33
+ docChanges: () => changes
34
+ };
35
+ }
36
+ }
37
+ exports.SnapshotManager = SnapshotManager;
@@ -0,0 +1,16 @@
1
+ export declare class Timestamp {
2
+ readonly seconds: number;
3
+ readonly nanoseconds: number;
4
+ constructor(seconds: number, nanoseconds: number);
5
+ static now(): Timestamp;
6
+ static fromDate(date: Date): Timestamp;
7
+ static fromMillis(milliseconds: number): Timestamp;
8
+ toDate(): Date;
9
+ toMillis(): number;
10
+ isEqual(other: Timestamp): boolean;
11
+ toString(): string;
12
+ toJSON(): {
13
+ seconds: number;
14
+ nanoseconds: number;
15
+ };
16
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Timestamp = void 0;
4
+ class Timestamp {
5
+ constructor(seconds, nanoseconds) {
6
+ this.seconds = seconds;
7
+ this.nanoseconds = nanoseconds;
8
+ }
9
+ static now() {
10
+ return Timestamp.fromMillis(Date.now());
11
+ }
12
+ static fromDate(date) {
13
+ return Timestamp.fromMillis(date.getTime());
14
+ }
15
+ static fromMillis(milliseconds) {
16
+ const seconds = Math.floor(milliseconds / 1000);
17
+ const nanoseconds = Math.floor((milliseconds % 1000) * 1e6);
18
+ return new Timestamp(seconds, nanoseconds);
19
+ }
20
+ toDate() {
21
+ return new Date(this.toMillis());
22
+ }
23
+ toMillis() {
24
+ return this.seconds * 1000 + Math.floor(this.nanoseconds / 1e6);
25
+ }
26
+ isEqual(other) {
27
+ return this.seconds === other.seconds && this.nanoseconds === other.nanoseconds;
28
+ }
29
+ toString() {
30
+ return `Timestamp(seconds=${this.seconds}, nanoseconds=${this.nanoseconds})`;
31
+ }
32
+ toJSON() {
33
+ return { seconds: this.seconds, nanoseconds: this.nanoseconds };
34
+ }
35
+ }
36
+ exports.Timestamp = Timestamp;
@@ -0,0 +1,3 @@
1
+ import { NexaApp } from '../app/NexaApp';
2
+ import { WriteBatch } from '../types/index';
3
+ export declare const writeBatch: (db: NexaApp) => WriteBatch;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeBatch = void 0;
4
+ const helpers_1 = require("../utils/helpers");
5
+ const writeBatch = (db) => {
6
+ const operations = [];
7
+ const batchObj = {
8
+ set: (docRef, data) => {
9
+ operations.push({ type: 'set', path: docRef.path, data });
10
+ return batchObj;
11
+ },
12
+ update: (docRef, data) => {
13
+ operations.push({ type: 'update', path: docRef.path, data });
14
+ return batchObj;
15
+ },
16
+ patch: (docRef, data) => {
17
+ operations.push({ type: 'update', path: docRef.path, data });
18
+ return batchObj;
19
+ },
20
+ delete: (docRef) => {
21
+ operations.push({ type: 'delete', path: docRef.path });
22
+ return batchObj;
23
+ },
24
+ commit: async () => {
25
+ if (db._initPromise)
26
+ await db._initPromise;
27
+ if (operations.length === 0)
28
+ return;
29
+ const idempotencyKey = (0, helpers_1.generateIdempotencyKey)();
30
+ const isOnline = typeof navigator !== 'undefined' ? navigator.onLine : true;
31
+ for (const op of operations) {
32
+ if (op.type === 'set' || op.type === 'update') {
33
+ const newData = (0, helpers_1.applyDataTransforms)(db._firestoreCache[op.path] || {}, op.data);
34
+ await db._setCache(op.path, newData);
35
+ db._broadcastLocalMutation(op.path, op.type === 'set' ? 'set' : 'patch', op.data);
36
+ db._notifySnapshotCallbacks(op.path, 'document_written', db._firestoreCache[op.path]);
37
+ }
38
+ else if (op.type === 'delete') {
39
+ await db._deleteCache(op.path);
40
+ db._broadcastLocalMutation(op.path, 'delete');
41
+ db._notifySnapshotCallbacks(op.path, 'document_deleted', null);
42
+ }
43
+ }
44
+ if (!isOnline) {
45
+ for (const op of operations) {
46
+ await db._addOfflineJob({
47
+ id: Math.random().toString(36).substring(2, 9),
48
+ type: op.type,
49
+ path: op.path,
50
+ data: op.data,
51
+ idempotencyKey,
52
+ state: 'pending'
53
+ });
54
+ }
55
+ return { success: true, message: 'Offline: Batch operations queued in IndexedDB' };
56
+ }
57
+ else {
58
+ try {
59
+ return (await db.client.post(`/api/firestore/${db.projectId}/batch`, { operations, idempotencyKey }, { headers: { 'X-Idempotency-Key': idempotencyKey } })).data;
60
+ }
61
+ catch (error) {
62
+ for (const op of operations) {
63
+ await db._addOfflineJob({
64
+ id: Math.random().toString(36).substring(2, 9),
65
+ type: op.type,
66
+ path: op.path,
67
+ data: op.data,
68
+ idempotencyKey,
69
+ state: 'pending'
70
+ });
71
+ }
72
+ return { success: true, message: 'Koneksi terganggu: Tersimpan di antrean offline' };
73
+ }
74
+ }
75
+ }
76
+ };
77
+ return batchObj;
78
+ };
79
+ exports.writeBatch = writeBatch;
@@ -0,0 +1,9 @@
1
+ import { FieldPath } from './FieldPath';
2
+ import { QueryConstraint, WhereFilterOp } from '../types/index';
3
+ export declare const where: (fieldPath: string | FieldPath, opStr: WhereFilterOp | string, value: any) => QueryConstraint;
4
+ export declare const orderBy: (fieldPath: string | FieldPath, directionStr?: "asc" | "desc") => QueryConstraint;
5
+ export declare const limit: (limitValue: number) => QueryConstraint;
6
+ export declare const startAt: (docSnapshot: any) => QueryConstraint;
7
+ export declare const startAfter: (docSnapshot: any) => QueryConstraint;
8
+ export declare const endAt: (docSnapshot: any) => QueryConstraint;
9
+ export declare const endBefore: (docSnapshot: any) => QueryConstraint;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.endBefore = exports.endAt = exports.startAfter = exports.startAt = exports.limit = exports.orderBy = exports.where = void 0;
4
+ const where = (fieldPath, opStr, value) => {
5
+ return { type: 'where', fieldPath, opStr, value };
6
+ };
7
+ exports.where = where;
8
+ const orderBy = (fieldPath, directionStr = 'asc') => {
9
+ return { type: 'orderBy', fieldPath, directionStr };
10
+ };
11
+ exports.orderBy = orderBy;
12
+ const limit = (limitValue) => {
13
+ return { type: 'limit', limitValue };
14
+ };
15
+ exports.limit = limit;
16
+ const startAt = (docSnapshot) => {
17
+ return { type: 'startAt', docSnapshot };
18
+ };
19
+ exports.startAt = startAt;
20
+ const startAfter = (docSnapshot) => {
21
+ return { type: 'startAfter', docSnapshot };
22
+ };
23
+ exports.startAfter = startAfter;
24
+ const endAt = (docSnapshot) => {
25
+ return { type: 'endAt', docSnapshot };
26
+ };
27
+ exports.endAt = endAt;
28
+ const endBefore = (docSnapshot) => {
29
+ return { type: 'endBefore', docSnapshot };
30
+ };
31
+ exports.endBefore = endBefore;
@@ -0,0 +1,5 @@
1
+ import { NexaApp } from '../app/NexaApp';
2
+ import { Transaction } from '../types/index';
3
+ export declare const runTransaction: <T = any>(db: NexaApp, updateFunction: (transaction: Transaction) => Promise<T>, options?: {
4
+ maxAttempts?: number;
5
+ }) => Promise<T>;