@ponceca/firestore-sdk 0.1.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.
- package/LICENSE +21 -0
- package/README.md +692 -0
- package/dist/app.d.mts +51 -0
- package/dist/app.d.ts +51 -0
- package/dist/app.js +16 -0
- package/dist/app.js.map +1 -0
- package/dist/app.mjs +16 -0
- package/dist/app.mjs.map +1 -0
- package/dist/auth/index.d.mts +43 -0
- package/dist/auth/index.d.ts +43 -0
- package/dist/auth/index.js +18 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +18 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/chunk-2RQUHE2K.js +719 -0
- package/dist/chunk-2RQUHE2K.js.map +1 -0
- package/dist/chunk-4CV4JOE5.js +27 -0
- package/dist/chunk-4CV4JOE5.js.map +1 -0
- package/dist/chunk-57XXMSJA.js +65 -0
- package/dist/chunk-57XXMSJA.js.map +1 -0
- package/dist/chunk-6J3LNKUQ.js +213 -0
- package/dist/chunk-6J3LNKUQ.js.map +1 -0
- package/dist/chunk-BXV7KTHB.js +645 -0
- package/dist/chunk-BXV7KTHB.js.map +1 -0
- package/dist/chunk-C3PCJJX4.mjs +645 -0
- package/dist/chunk-C3PCJJX4.mjs.map +1 -0
- package/dist/chunk-C6SKWUQV.mjs +213 -0
- package/dist/chunk-C6SKWUQV.mjs.map +1 -0
- package/dist/chunk-DXPQJR5D.mjs +2469 -0
- package/dist/chunk-DXPQJR5D.mjs.map +1 -0
- package/dist/chunk-MRVKMKSO.mjs +65 -0
- package/dist/chunk-MRVKMKSO.mjs.map +1 -0
- package/dist/chunk-NFEGQTCC.mjs +27 -0
- package/dist/chunk-NFEGQTCC.mjs.map +1 -0
- package/dist/chunk-RSBBZLDE.js +128 -0
- package/dist/chunk-RSBBZLDE.js.map +1 -0
- package/dist/chunk-RZWTSZSJ.js +2469 -0
- package/dist/chunk-RZWTSZSJ.js.map +1 -0
- package/dist/chunk-SZKHE2TQ.mjs +719 -0
- package/dist/chunk-SZKHE2TQ.mjs.map +1 -0
- package/dist/chunk-ZJ4A4Y2T.mjs +128 -0
- package/dist/chunk-ZJ4A4Y2T.mjs.map +1 -0
- package/dist/firestore/index.d.mts +1476 -0
- package/dist/firestore/index.d.ts +1476 -0
- package/dist/firestore/index.js +156 -0
- package/dist/firestore/index.js.map +1 -0
- package/dist/firestore/index.mjs +156 -0
- package/dist/firestore/index.mjs.map +1 -0
- package/dist/http-A2S5CWEV.js +10 -0
- package/dist/http-A2S5CWEV.js.map +1 -0
- package/dist/http-SZFONH6Z.mjs +10 -0
- package/dist/http-SZFONH6Z.mjs.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +171 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +171 -0
- package/dist/index.mjs.map +1 -0
- package/dist/indexeddb-mutation-queue-5EB7C2D5.js +192 -0
- package/dist/indexeddb-mutation-queue-5EB7C2D5.js.map +1 -0
- package/dist/indexeddb-mutation-queue-M2MAH4E4.mjs +192 -0
- package/dist/indexeddb-mutation-queue-M2MAH4E4.mjs.map +1 -0
- package/dist/indexeddb-store-D23ZY3PR.mjs +162 -0
- package/dist/indexeddb-store-D23ZY3PR.mjs.map +1 -0
- package/dist/indexeddb-store-DNWBZUQE.js +162 -0
- package/dist/indexeddb-store-DNWBZUQE.js.map +1 -0
- package/dist/snapshot-MCQVLVHL.js +22 -0
- package/dist/snapshot-MCQVLVHL.js.map +1 -0
- package/dist/snapshot-ZWZFIFZD.mjs +22 -0
- package/dist/snapshot-ZWZFIFZD.mjs.map +1 -0
- package/dist/types-meoR-Ecp.d.mts +269 -0
- package/dist/types-meoR-Ecp.d.ts +269 -0
- package/package.json +78 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import "./chunk-NFEGQTCC.mjs";
|
|
2
|
+
|
|
3
|
+
// src/persistence/indexeddb-store.ts
|
|
4
|
+
var DB_VERSION = 1;
|
|
5
|
+
var DOCS_STORE = "documents";
|
|
6
|
+
var QUERIES_STORE = "queries";
|
|
7
|
+
var IndexedDBStore = class _IndexedDBStore {
|
|
8
|
+
constructor(projectId) {
|
|
9
|
+
this.db = null;
|
|
10
|
+
this._initPromise = null;
|
|
11
|
+
this.dbName = `firestore_cache_${projectId}`;
|
|
12
|
+
}
|
|
13
|
+
// ===========================================================================
|
|
14
|
+
// INICIALIZACIÓN
|
|
15
|
+
// ===========================================================================
|
|
16
|
+
/** Abre o crea la base de datos IndexedDB */
|
|
17
|
+
init() {
|
|
18
|
+
if (this.db) return Promise.resolve();
|
|
19
|
+
if (this._initPromise) return this._initPromise;
|
|
20
|
+
this._initPromise = new Promise((resolve, reject) => {
|
|
21
|
+
const request = indexedDB.open(this.dbName, DB_VERSION);
|
|
22
|
+
request.onupgradeneeded = () => {
|
|
23
|
+
const db = request.result;
|
|
24
|
+
if (!db.objectStoreNames.contains(DOCS_STORE)) {
|
|
25
|
+
db.createObjectStore(DOCS_STORE, { keyPath: "path" });
|
|
26
|
+
}
|
|
27
|
+
if (!db.objectStoreNames.contains(QUERIES_STORE)) {
|
|
28
|
+
db.createObjectStore(QUERIES_STORE, { keyPath: "key" });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
request.onsuccess = () => {
|
|
32
|
+
this.db = request.result;
|
|
33
|
+
resolve();
|
|
34
|
+
};
|
|
35
|
+
request.onerror = () => {
|
|
36
|
+
reject(new Error(`IndexedDB open failed: ${request.error?.message}`));
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
return this._initPromise;
|
|
40
|
+
}
|
|
41
|
+
/** Helper: ejecuta una transacción read/write en un object store */
|
|
42
|
+
async tx(storeName, mode, fn) {
|
|
43
|
+
await this.init();
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const tx = this.db.transaction(storeName, mode);
|
|
46
|
+
const store = tx.objectStore(storeName);
|
|
47
|
+
const request = fn(store);
|
|
48
|
+
request.onsuccess = () => resolve(request.result);
|
|
49
|
+
request.onerror = () => reject(request.error);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// ===========================================================================
|
|
53
|
+
// DOCUMENTOS
|
|
54
|
+
// ===========================================================================
|
|
55
|
+
async putDocument(path, data, exists, updateTime) {
|
|
56
|
+
const doc = {
|
|
57
|
+
path,
|
|
58
|
+
data: data ? JSON.parse(JSON.stringify(data)) : null,
|
|
59
|
+
exists,
|
|
60
|
+
updateTime,
|
|
61
|
+
cachedAt: Date.now()
|
|
62
|
+
};
|
|
63
|
+
await this.tx(DOCS_STORE, "readwrite", (store) => store.put(doc));
|
|
64
|
+
}
|
|
65
|
+
async getDocument(path) {
|
|
66
|
+
const result = await this.tx(
|
|
67
|
+
DOCS_STORE,
|
|
68
|
+
"readonly",
|
|
69
|
+
(store) => store.get(path)
|
|
70
|
+
);
|
|
71
|
+
return result || void 0;
|
|
72
|
+
}
|
|
73
|
+
async removeDocument(path) {
|
|
74
|
+
await this.tx(DOCS_STORE, "readwrite", (store) => store.delete(path));
|
|
75
|
+
}
|
|
76
|
+
async markDeleted(path) {
|
|
77
|
+
await this.putDocument(path, null, false);
|
|
78
|
+
}
|
|
79
|
+
async getDocumentsByCollection(collectionPath) {
|
|
80
|
+
await this.init();
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const tx = this.db.transaction(DOCS_STORE, "readonly");
|
|
83
|
+
const store = tx.objectStore(DOCS_STORE);
|
|
84
|
+
const results = [];
|
|
85
|
+
const prefix = collectionPath + "/";
|
|
86
|
+
const request = store.openCursor();
|
|
87
|
+
request.onsuccess = () => {
|
|
88
|
+
const cursor = request.result;
|
|
89
|
+
if (cursor) {
|
|
90
|
+
const doc = cursor.value;
|
|
91
|
+
if (doc.path.startsWith(prefix) && !doc.path.substring(prefix.length).includes("/")) {
|
|
92
|
+
if (doc.exists) {
|
|
93
|
+
results.push(doc);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
cursor.continue();
|
|
97
|
+
} else {
|
|
98
|
+
resolve(results);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
request.onerror = () => reject(request.error);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// ===========================================================================
|
|
105
|
+
// QUERIES
|
|
106
|
+
// ===========================================================================
|
|
107
|
+
async putQuery(key, documentPaths) {
|
|
108
|
+
const entry = { key, documentPaths: [...documentPaths], cachedAt: Date.now() };
|
|
109
|
+
await this.tx(QUERIES_STORE, "readwrite", (store) => store.put(entry));
|
|
110
|
+
}
|
|
111
|
+
async getQuery(key) {
|
|
112
|
+
const result = await this.tx(
|
|
113
|
+
QUERIES_STORE,
|
|
114
|
+
"readonly",
|
|
115
|
+
(store) => store.get(key)
|
|
116
|
+
);
|
|
117
|
+
return result || void 0;
|
|
118
|
+
}
|
|
119
|
+
// ===========================================================================
|
|
120
|
+
// MANTENIMIENTO
|
|
121
|
+
// ===========================================================================
|
|
122
|
+
async clear() {
|
|
123
|
+
await this.init();
|
|
124
|
+
await this.tx(DOCS_STORE, "readwrite", (store) => store.clear());
|
|
125
|
+
await this.tx(QUERIES_STORE, "readwrite", (store) => store.clear());
|
|
126
|
+
}
|
|
127
|
+
get documentCount() {
|
|
128
|
+
return this.tx(DOCS_STORE, "readonly", (store) => store.count());
|
|
129
|
+
}
|
|
130
|
+
get queryCount() {
|
|
131
|
+
return this.tx(QUERIES_STORE, "readonly", (store) => store.count());
|
|
132
|
+
}
|
|
133
|
+
// ===========================================================================
|
|
134
|
+
// DESTRUCCIÓN
|
|
135
|
+
// ===========================================================================
|
|
136
|
+
/** Cierra la conexión y opcionalmente borra toda la DB */
|
|
137
|
+
close() {
|
|
138
|
+
if (this.db) {
|
|
139
|
+
this.db.close();
|
|
140
|
+
this.db = null;
|
|
141
|
+
this._initPromise = null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Borra toda la base de datos IndexedDB (instancia) */
|
|
145
|
+
async deleteDatabase() {
|
|
146
|
+
this.close();
|
|
147
|
+
return _IndexedDBStore.deleteDatabase(this.dbName);
|
|
148
|
+
}
|
|
149
|
+
/** Borra una base de datos IndexedDB por projectId (estático) */
|
|
150
|
+
static deleteDatabase(projectId) {
|
|
151
|
+
const dbName = projectId.startsWith("firestore_cache_") ? projectId : `firestore_cache_${projectId}`;
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
const request = indexedDB.deleteDatabase(dbName);
|
|
154
|
+
request.onsuccess = () => resolve();
|
|
155
|
+
request.onerror = () => reject(request.error);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
export {
|
|
160
|
+
IndexedDBStore
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=indexeddb-store-D23ZY3PR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/persistence/indexeddb-store.ts"],"sourcesContent":["/**\r\n * Firestore SDK - IndexedDB Store\r\n * Persistencia de documentos/queries en IndexedDB para sobrevivir recargas de página.\r\n * Implementa la misma interfaz que LocalStore pero con almacenamiento persistente.\r\n * \r\n * Schema de IndexedDB:\r\n * - DB name: `firestore_cache_${projectId}`\r\n * - Object stores: \"documents\" (key: path), \"queries\" (key: key), \"mutations\" (key: id)\r\n */\r\n\r\nimport type { DocumentData } from '../firestore/types';\r\nimport type { CachedDocument, CachedQuery, DocumentStore } from './types';\r\n\r\nconst DB_VERSION = 1;\r\nconst DOCS_STORE = 'documents';\r\nconst QUERIES_STORE = 'queries';\r\n\r\n/**\r\n * Cache de documentos y queries persistido en IndexedDB.\r\n * API async — todas las operaciones retornan Promises.\r\n */\r\nexport class IndexedDBStore implements DocumentStore {\r\n private db: IDBDatabase | null = null;\r\n private readonly dbName: string;\r\n private _initPromise: Promise<void> | null = null;\r\n\r\n constructor(projectId: string) {\r\n this.dbName = `firestore_cache_${projectId}`;\r\n }\r\n\r\n // ===========================================================================\r\n // INICIALIZACIÓN\r\n // ===========================================================================\r\n\r\n /** Abre o crea la base de datos IndexedDB */\r\n init(): Promise<void> {\r\n if (this.db) return Promise.resolve();\r\n if (this._initPromise) return this._initPromise;\r\n\r\n this._initPromise = new Promise<void>((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, DB_VERSION);\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result;\r\n if (!db.objectStoreNames.contains(DOCS_STORE)) {\r\n db.createObjectStore(DOCS_STORE, { keyPath: 'path' });\r\n }\r\n if (!db.objectStoreNames.contains(QUERIES_STORE)) {\r\n db.createObjectStore(QUERIES_STORE, { keyPath: 'key' });\r\n }\r\n };\r\n\r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n resolve();\r\n };\r\n\r\n request.onerror = () => {\r\n reject(new Error(`IndexedDB open failed: ${request.error?.message}`));\r\n };\r\n });\r\n\r\n return this._initPromise;\r\n }\r\n\r\n /** Helper: ejecuta una transacción read/write en un object store */\r\n private async tx<T>(\r\n storeName: string,\r\n mode: IDBTransactionMode,\r\n fn: (store: IDBObjectStore) => IDBRequest<T>,\r\n ): Promise<T> {\r\n await this.init();\r\n return new Promise<T>((resolve, reject) => {\r\n const tx = this.db!.transaction(storeName, mode);\r\n const store = tx.objectStore(storeName);\r\n const request = fn(store);\r\n request.onsuccess = () => resolve(request.result);\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n // ===========================================================================\r\n // DOCUMENTOS\r\n // ===========================================================================\r\n\r\n async putDocument(path: string, data: DocumentData | null, exists: boolean, updateTime?: string): Promise<void> {\r\n const doc: CachedDocument = {\r\n path,\r\n data: data ? JSON.parse(JSON.stringify(data)) : null,\r\n exists,\r\n updateTime,\r\n cachedAt: Date.now(),\r\n };\r\n await this.tx(DOCS_STORE, 'readwrite', (store) => store.put(doc));\r\n }\r\n\r\n async getDocument(path: string): Promise<CachedDocument | undefined> {\r\n const result = await this.tx<CachedDocument | undefined>(\r\n DOCS_STORE, 'readonly', (store) => store.get(path),\r\n );\r\n return result || undefined;\r\n }\r\n\r\n async removeDocument(path: string): Promise<void> {\r\n await this.tx(DOCS_STORE, 'readwrite', (store) => store.delete(path));\r\n }\r\n\r\n async markDeleted(path: string): Promise<void> {\r\n await this.putDocument(path, null, false);\r\n }\r\n\r\n async getDocumentsByCollection(collectionPath: string): Promise<CachedDocument[]> {\r\n await this.init();\r\n return new Promise<CachedDocument[]>((resolve, reject) => {\r\n const tx = this.db!.transaction(DOCS_STORE, 'readonly');\r\n const store = tx.objectStore(DOCS_STORE);\r\n const results: CachedDocument[] = [];\r\n const prefix = collectionPath + '/';\r\n\r\n const request = store.openCursor();\r\n request.onsuccess = () => {\r\n const cursor = request.result;\r\n if (cursor) {\r\n const doc = cursor.value as CachedDocument;\r\n // Solo documentos directos (no subcolecciones)\r\n if (doc.path.startsWith(prefix) && !doc.path.substring(prefix.length).includes('/')) {\r\n if (doc.exists) {\r\n results.push(doc);\r\n }\r\n }\r\n cursor.continue();\r\n } else {\r\n resolve(results);\r\n }\r\n };\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n // ===========================================================================\r\n // QUERIES\r\n // ===========================================================================\r\n\r\n async putQuery(key: string, documentPaths: string[]): Promise<void> {\r\n const entry: CachedQuery = { key, documentPaths: [...documentPaths], cachedAt: Date.now() };\r\n await this.tx(QUERIES_STORE, 'readwrite', (store) => store.put(entry));\r\n }\r\n\r\n async getQuery(key: string): Promise<CachedQuery | undefined> {\r\n const result = await this.tx<CachedQuery | undefined>(\r\n QUERIES_STORE, 'readonly', (store) => store.get(key),\r\n );\r\n return result || undefined;\r\n }\r\n\r\n // ===========================================================================\r\n // MANTENIMIENTO\r\n // ===========================================================================\r\n\r\n async clear(): Promise<void> {\r\n await this.init();\r\n await this.tx(DOCS_STORE, 'readwrite', (store) => store.clear());\r\n await this.tx(QUERIES_STORE, 'readwrite', (store) => store.clear());\r\n }\r\n\r\n get documentCount(): Promise<number> {\r\n return this.tx<number>(DOCS_STORE, 'readonly', (store) => store.count());\r\n }\r\n\r\n get queryCount(): Promise<number> {\r\n return this.tx<number>(QUERIES_STORE, 'readonly', (store) => store.count());\r\n }\r\n\r\n // ===========================================================================\r\n // DESTRUCCIÓN\r\n // ===========================================================================\r\n\r\n /** Cierra la conexión y opcionalmente borra toda la DB */\r\n close(): void {\r\n if (this.db) {\r\n this.db.close();\r\n this.db = null;\r\n this._initPromise = null;\r\n }\r\n }\r\n\r\n /** Borra toda la base de datos IndexedDB (instancia) */\r\n async deleteDatabase(): Promise<void> {\r\n this.close();\r\n return IndexedDBStore.deleteDatabase(this.dbName);\r\n }\r\n\r\n /** Borra una base de datos IndexedDB por projectId (estático) */\r\n static deleteDatabase(projectId: string): Promise<void> {\r\n const dbName = projectId.startsWith('firestore_cache_') ? projectId : `firestore_cache_${projectId}`;\r\n return new Promise<void>((resolve, reject) => {\r\n const request = indexedDB.deleteDatabase(dbName);\r\n request.onsuccess = () => resolve();\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;AAaA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,gBAAgB;AAMf,IAAM,iBAAN,MAAM,gBAAwC;AAAA,EAKnD,YAAY,WAAmB;AAJ/B,SAAQ,KAAyB;AAEjC,SAAQ,eAAqC;AAG3C,SAAK,SAAS,mBAAmB,SAAS;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAsB;AACpB,QAAI,KAAK,GAAI,QAAO,QAAQ,QAAQ;AACpC,QAAI,KAAK,aAAc,QAAO,KAAK;AAEnC,SAAK,eAAe,IAAI,QAAc,CAAC,SAAS,WAAW;AACzD,YAAM,UAAU,UAAU,KAAK,KAAK,QAAQ,UAAU;AAEtD,cAAQ,kBAAkB,MAAM;AAC9B,cAAM,KAAK,QAAQ;AACnB,YAAI,CAAC,GAAG,iBAAiB,SAAS,UAAU,GAAG;AAC7C,aAAG,kBAAkB,YAAY,EAAE,SAAS,OAAO,CAAC;AAAA,QACtD;AACA,YAAI,CAAC,GAAG,iBAAiB,SAAS,aAAa,GAAG;AAChD,aAAG,kBAAkB,eAAe,EAAE,SAAS,MAAM,CAAC;AAAA,QACxD;AAAA,MACF;AAEA,cAAQ,YAAY,MAAM;AACxB,aAAK,KAAK,QAAQ;AAClB,gBAAQ;AAAA,MACV;AAEA,cAAQ,UAAU,MAAM;AACtB,eAAO,IAAI,MAAM,0BAA0B,QAAQ,OAAO,OAAO,EAAE,CAAC;AAAA,MACtE;AAAA,IACF,CAAC;AAED,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAc,GACZ,WACA,MACA,IACY;AACZ,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,YAAM,KAAK,KAAK,GAAI,YAAY,WAAW,IAAI;AAC/C,YAAM,QAAQ,GAAG,YAAY,SAAS;AACtC,YAAM,UAAU,GAAG,KAAK;AACxB,cAAQ,YAAY,MAAM,QAAQ,QAAQ,MAAM;AAChD,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,MAAc,MAA2B,QAAiB,YAAoC;AAC9G,UAAM,MAAsB;AAAA,MAC1B;AAAA,MACA,MAAM,OAAO,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC,IAAI;AAAA,MAChD;AAAA,MACA;AAAA,MACA,UAAU,KAAK,IAAI;AAAA,IACrB;AACA,UAAM,KAAK,GAAG,YAAY,aAAa,CAAC,UAAU,MAAM,IAAI,GAAG,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,YAAY,MAAmD;AACnE,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB;AAAA,MAAY;AAAA,MAAY,CAAC,UAAU,MAAM,IAAI,IAAI;AAAA,IACnD;AACA,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,MAAM,eAAe,MAA6B;AAChD,UAAM,KAAK,GAAG,YAAY,aAAa,CAAC,UAAU,MAAM,OAAO,IAAI,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,YAAY,MAA6B;AAC7C,UAAM,KAAK,YAAY,MAAM,MAAM,KAAK;AAAA,EAC1C;AAAA,EAEA,MAAM,yBAAyB,gBAAmD;AAChF,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,QAA0B,CAAC,SAAS,WAAW;AACxD,YAAM,KAAK,KAAK,GAAI,YAAY,YAAY,UAAU;AACtD,YAAM,QAAQ,GAAG,YAAY,UAAU;AACvC,YAAM,UAA4B,CAAC;AACnC,YAAM,SAAS,iBAAiB;AAEhC,YAAM,UAAU,MAAM,WAAW;AACjC,cAAQ,YAAY,MAAM;AACxB,cAAM,SAAS,QAAQ;AACvB,YAAI,QAAQ;AACV,gBAAM,MAAM,OAAO;AAEnB,cAAI,IAAI,KAAK,WAAW,MAAM,KAAK,CAAC,IAAI,KAAK,UAAU,OAAO,MAAM,EAAE,SAAS,GAAG,GAAG;AACnF,gBAAI,IAAI,QAAQ;AACd,sBAAQ,KAAK,GAAG;AAAA,YAClB;AAAA,UACF;AACA,iBAAO,SAAS;AAAA,QAClB,OAAO;AACL,kBAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AACA,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,KAAa,eAAwC;AAClE,UAAM,QAAqB,EAAE,KAAK,eAAe,CAAC,GAAG,aAAa,GAAG,UAAU,KAAK,IAAI,EAAE;AAC1F,UAAM,KAAK,GAAG,eAAe,aAAa,CAAC,UAAU,MAAM,IAAI,KAAK,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,SAAS,KAA+C;AAC5D,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB;AAAA,MAAe;AAAA,MAAY,CAAC,UAAU,MAAM,IAAI,GAAG;AAAA,IACrD;AACA,WAAO,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAuB;AAC3B,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,GAAG,YAAY,aAAa,CAAC,UAAU,MAAM,MAAM,CAAC;AAC/D,UAAM,KAAK,GAAG,eAAe,aAAa,CAAC,UAAU,MAAM,MAAM,CAAC;AAAA,EACpE;AAAA,EAEA,IAAI,gBAAiC;AACnC,WAAO,KAAK,GAAW,YAAY,YAAY,CAAC,UAAU,MAAM,MAAM,CAAC;AAAA,EACzE;AAAA,EAEA,IAAI,aAA8B;AAChC,WAAO,KAAK,GAAW,eAAe,YAAY,CAAC,UAAU,MAAM,MAAM,CAAC;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAc;AACZ,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AACd,WAAK,KAAK;AACV,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,iBAAgC;AACpC,SAAK,MAAM;AACX,WAAO,gBAAe,eAAe,KAAK,MAAM;AAAA,EAClD;AAAA;AAAA,EAGA,OAAO,eAAe,WAAkC;AACtD,UAAM,SAAS,UAAU,WAAW,kBAAkB,IAAI,YAAY,mBAAmB,SAAS;AAClG,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAM,UAAU,UAAU,eAAe,MAAM;AAC/C,cAAQ,YAAY,MAAM,QAAQ;AAClC,cAAQ,UAAU,MAAM,OAAO,QAAQ,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }require('./chunk-4CV4JOE5.js');
|
|
2
|
+
|
|
3
|
+
// src/persistence/indexeddb-store.ts
|
|
4
|
+
var DB_VERSION = 1;
|
|
5
|
+
var DOCS_STORE = "documents";
|
|
6
|
+
var QUERIES_STORE = "queries";
|
|
7
|
+
var IndexedDBStore = class _IndexedDBStore {
|
|
8
|
+
constructor(projectId) {
|
|
9
|
+
this.db = null;
|
|
10
|
+
this._initPromise = null;
|
|
11
|
+
this.dbName = `firestore_cache_${projectId}`;
|
|
12
|
+
}
|
|
13
|
+
// ===========================================================================
|
|
14
|
+
// INICIALIZACIÓN
|
|
15
|
+
// ===========================================================================
|
|
16
|
+
/** Abre o crea la base de datos IndexedDB */
|
|
17
|
+
init() {
|
|
18
|
+
if (this.db) return Promise.resolve();
|
|
19
|
+
if (this._initPromise) return this._initPromise;
|
|
20
|
+
this._initPromise = new Promise((resolve, reject) => {
|
|
21
|
+
const request = indexedDB.open(this.dbName, DB_VERSION);
|
|
22
|
+
request.onupgradeneeded = () => {
|
|
23
|
+
const db = request.result;
|
|
24
|
+
if (!db.objectStoreNames.contains(DOCS_STORE)) {
|
|
25
|
+
db.createObjectStore(DOCS_STORE, { keyPath: "path" });
|
|
26
|
+
}
|
|
27
|
+
if (!db.objectStoreNames.contains(QUERIES_STORE)) {
|
|
28
|
+
db.createObjectStore(QUERIES_STORE, { keyPath: "key" });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
request.onsuccess = () => {
|
|
32
|
+
this.db = request.result;
|
|
33
|
+
resolve();
|
|
34
|
+
};
|
|
35
|
+
request.onerror = () => {
|
|
36
|
+
reject(new Error(`IndexedDB open failed: ${_optionalChain([request, 'access', _ => _.error, 'optionalAccess', _2 => _2.message])}`));
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
return this._initPromise;
|
|
40
|
+
}
|
|
41
|
+
/** Helper: ejecuta una transacción read/write en un object store */
|
|
42
|
+
async tx(storeName, mode, fn) {
|
|
43
|
+
await this.init();
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const tx = this.db.transaction(storeName, mode);
|
|
46
|
+
const store = tx.objectStore(storeName);
|
|
47
|
+
const request = fn(store);
|
|
48
|
+
request.onsuccess = () => resolve(request.result);
|
|
49
|
+
request.onerror = () => reject(request.error);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// ===========================================================================
|
|
53
|
+
// DOCUMENTOS
|
|
54
|
+
// ===========================================================================
|
|
55
|
+
async putDocument(path, data, exists, updateTime) {
|
|
56
|
+
const doc = {
|
|
57
|
+
path,
|
|
58
|
+
data: data ? JSON.parse(JSON.stringify(data)) : null,
|
|
59
|
+
exists,
|
|
60
|
+
updateTime,
|
|
61
|
+
cachedAt: Date.now()
|
|
62
|
+
};
|
|
63
|
+
await this.tx(DOCS_STORE, "readwrite", (store) => store.put(doc));
|
|
64
|
+
}
|
|
65
|
+
async getDocument(path) {
|
|
66
|
+
const result = await this.tx(
|
|
67
|
+
DOCS_STORE,
|
|
68
|
+
"readonly",
|
|
69
|
+
(store) => store.get(path)
|
|
70
|
+
);
|
|
71
|
+
return result || void 0;
|
|
72
|
+
}
|
|
73
|
+
async removeDocument(path) {
|
|
74
|
+
await this.tx(DOCS_STORE, "readwrite", (store) => store.delete(path));
|
|
75
|
+
}
|
|
76
|
+
async markDeleted(path) {
|
|
77
|
+
await this.putDocument(path, null, false);
|
|
78
|
+
}
|
|
79
|
+
async getDocumentsByCollection(collectionPath) {
|
|
80
|
+
await this.init();
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const tx = this.db.transaction(DOCS_STORE, "readonly");
|
|
83
|
+
const store = tx.objectStore(DOCS_STORE);
|
|
84
|
+
const results = [];
|
|
85
|
+
const prefix = collectionPath + "/";
|
|
86
|
+
const request = store.openCursor();
|
|
87
|
+
request.onsuccess = () => {
|
|
88
|
+
const cursor = request.result;
|
|
89
|
+
if (cursor) {
|
|
90
|
+
const doc = cursor.value;
|
|
91
|
+
if (doc.path.startsWith(prefix) && !doc.path.substring(prefix.length).includes("/")) {
|
|
92
|
+
if (doc.exists) {
|
|
93
|
+
results.push(doc);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
cursor.continue();
|
|
97
|
+
} else {
|
|
98
|
+
resolve(results);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
request.onerror = () => reject(request.error);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// ===========================================================================
|
|
105
|
+
// QUERIES
|
|
106
|
+
// ===========================================================================
|
|
107
|
+
async putQuery(key, documentPaths) {
|
|
108
|
+
const entry = { key, documentPaths: [...documentPaths], cachedAt: Date.now() };
|
|
109
|
+
await this.tx(QUERIES_STORE, "readwrite", (store) => store.put(entry));
|
|
110
|
+
}
|
|
111
|
+
async getQuery(key) {
|
|
112
|
+
const result = await this.tx(
|
|
113
|
+
QUERIES_STORE,
|
|
114
|
+
"readonly",
|
|
115
|
+
(store) => store.get(key)
|
|
116
|
+
);
|
|
117
|
+
return result || void 0;
|
|
118
|
+
}
|
|
119
|
+
// ===========================================================================
|
|
120
|
+
// MANTENIMIENTO
|
|
121
|
+
// ===========================================================================
|
|
122
|
+
async clear() {
|
|
123
|
+
await this.init();
|
|
124
|
+
await this.tx(DOCS_STORE, "readwrite", (store) => store.clear());
|
|
125
|
+
await this.tx(QUERIES_STORE, "readwrite", (store) => store.clear());
|
|
126
|
+
}
|
|
127
|
+
get documentCount() {
|
|
128
|
+
return this.tx(DOCS_STORE, "readonly", (store) => store.count());
|
|
129
|
+
}
|
|
130
|
+
get queryCount() {
|
|
131
|
+
return this.tx(QUERIES_STORE, "readonly", (store) => store.count());
|
|
132
|
+
}
|
|
133
|
+
// ===========================================================================
|
|
134
|
+
// DESTRUCCIÓN
|
|
135
|
+
// ===========================================================================
|
|
136
|
+
/** Cierra la conexión y opcionalmente borra toda la DB */
|
|
137
|
+
close() {
|
|
138
|
+
if (this.db) {
|
|
139
|
+
this.db.close();
|
|
140
|
+
this.db = null;
|
|
141
|
+
this._initPromise = null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Borra toda la base de datos IndexedDB (instancia) */
|
|
145
|
+
async deleteDatabase() {
|
|
146
|
+
this.close();
|
|
147
|
+
return _IndexedDBStore.deleteDatabase(this.dbName);
|
|
148
|
+
}
|
|
149
|
+
/** Borra una base de datos IndexedDB por projectId (estático) */
|
|
150
|
+
static deleteDatabase(projectId) {
|
|
151
|
+
const dbName = projectId.startsWith("firestore_cache_") ? projectId : `firestore_cache_${projectId}`;
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
const request = indexedDB.deleteDatabase(dbName);
|
|
154
|
+
request.onsuccess = () => resolve();
|
|
155
|
+
request.onerror = () => reject(request.error);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
exports.IndexedDBStore = IndexedDBStore;
|
|
162
|
+
//# sourceMappingURL=indexeddb-store-DNWBZUQE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["c:\\Users\\ponce\\Documents\\codigo-2026\\firestore\\sdk\\js\\dist\\indexeddb-store-DNWBZUQE.js"],"names":[],"mappings":"AAAA,4mBAA4B;AAC5B;AACA;AACA,IAAI,WAAW,EAAE,CAAC;AAClB,IAAI,WAAW,EAAE,WAAW;AAC5B,IAAI,cAAc,EAAE,SAAS;AAC7B,IAAI,eAAe,EAAE,MAAM,gBAAgB;AAC3C,EAAE,WAAW,CAAC,SAAS,EAAE;AACzB,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI;AAClB,IAAI,IAAI,CAAC,aAAa,EAAE,IAAI;AAC5B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,YAAA;AACA,cAAA;AACA,YAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA","file":"C:\\Users\\ponce\\Documents\\codigo-2026\\firestore\\sdk\\js\\dist\\indexeddb-store-DNWBZUQE.js","sourcesContent":[null]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
var _chunkBXV7KTHBjs = require('./chunk-BXV7KTHB.js');
|
|
11
|
+
require('./chunk-4CV4JOE5.js');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
exports.DocumentSnapshotImpl = _chunkBXV7KTHBjs.DocumentSnapshotImpl; exports.QuerySnapshotImpl = _chunkBXV7KTHBjs.QuerySnapshotImpl; exports.createDocumentSnapshot = _chunkBXV7KTHBjs.createDocumentSnapshot; exports.createQuerySnapshot = _chunkBXV7KTHBjs.createQuerySnapshot; exports.fromFirestoreFields = _chunkBXV7KTHBjs.fromFirestoreFields; exports.fromFirestoreValue = _chunkBXV7KTHBjs.fromFirestoreValue; exports.toFirestoreFields = _chunkBXV7KTHBjs.toFirestoreFields; exports.toFirestoreValue = _chunkBXV7KTHBjs.toFirestoreValue;
|
|
22
|
+
//# sourceMappingURL=snapshot-MCQVLVHL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["c:\\Users\\ponce\\Documents\\codigo-2026\\firestore\\sdk\\js\\dist\\snapshot-MCQVLVHL.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,uhBAAC","file":"C:\\Users\\ponce\\Documents\\codigo-2026\\firestore\\sdk\\js\\dist\\snapshot-MCQVLVHL.js"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentSnapshotImpl,
|
|
3
|
+
QuerySnapshotImpl,
|
|
4
|
+
createDocumentSnapshot,
|
|
5
|
+
createQuerySnapshot,
|
|
6
|
+
fromFirestoreFields,
|
|
7
|
+
fromFirestoreValue,
|
|
8
|
+
toFirestoreFields,
|
|
9
|
+
toFirestoreValue
|
|
10
|
+
} from "./chunk-C3PCJJX4.mjs";
|
|
11
|
+
import "./chunk-NFEGQTCC.mjs";
|
|
12
|
+
export {
|
|
13
|
+
DocumentSnapshotImpl,
|
|
14
|
+
QuerySnapshotImpl,
|
|
15
|
+
createDocumentSnapshot,
|
|
16
|
+
createQuerySnapshot,
|
|
17
|
+
fromFirestoreFields,
|
|
18
|
+
fromFirestoreValue,
|
|
19
|
+
toFirestoreFields,
|
|
20
|
+
toFirestoreValue
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=snapshot-ZWZFIFZD.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firestore SDK - Tipos TypeScript
|
|
3
|
+
* Compatible con Firebase Firestore v9
|
|
4
|
+
*/
|
|
5
|
+
/** Datos de un documento Firestore */
|
|
6
|
+
type DocumentData = Record<string, unknown>;
|
|
7
|
+
/** Tipo para campos anidados usando dot notation */
|
|
8
|
+
type FieldPath = string;
|
|
9
|
+
/** Unión de todos los field values especiales */
|
|
10
|
+
type FieldValue = {
|
|
11
|
+
readonly isEqual: (other: FieldValue) => boolean;
|
|
12
|
+
};
|
|
13
|
+
/** Opciones para inicializar la app (idéntico a Firebase) */
|
|
14
|
+
interface FirebaseOptions {
|
|
15
|
+
/** API Key del proyecto (para autenticación con API keys) */
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
/** ID del proyecto (requerido) */
|
|
18
|
+
projectId: string;
|
|
19
|
+
/** Auth Domain para autenticación OAuth */
|
|
20
|
+
authDomain?: string;
|
|
21
|
+
/** URL del Storage Bucket */
|
|
22
|
+
storageBucket?: string;
|
|
23
|
+
/** ID del sender para mensajería */
|
|
24
|
+
messagingSenderId?: string;
|
|
25
|
+
/** App ID de Firebase */
|
|
26
|
+
appId?: string;
|
|
27
|
+
/** ID de medición para Analytics */
|
|
28
|
+
measurementId?: string;
|
|
29
|
+
/** URL base del servidor (para self-hosted, no existe en Firebase original) */
|
|
30
|
+
baseUrl?: string;
|
|
31
|
+
/** ID de la base de datos (default: "(default)") */
|
|
32
|
+
databaseId?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Proveedor de tokens de autenticación
|
|
36
|
+
* Permite integrar cualquier sistema de auth (Firebase Auth, Auth0, custom, etc.)
|
|
37
|
+
*/
|
|
38
|
+
interface AuthTokenProvider {
|
|
39
|
+
/** Obtiene el token actual (puede ser async para refresh) */
|
|
40
|
+
getToken(): Promise<string | null>;
|
|
41
|
+
/** Listener para cambios de auth state */
|
|
42
|
+
onAuthStateChanged?(callback: (token: string | null) => void): () => void;
|
|
43
|
+
}
|
|
44
|
+
/** Configuración de Firestore (idéntico a Firebase) */
|
|
45
|
+
interface FirestoreSettings {
|
|
46
|
+
/** Host del servidor (ej: "localhost:3000" o "firestore.googleapis.com") */
|
|
47
|
+
host?: string;
|
|
48
|
+
/** Usar SSL/TLS */
|
|
49
|
+
ssl?: boolean;
|
|
50
|
+
/** Ignorar certificados no válidos (solo desarrollo) */
|
|
51
|
+
experimentalForceLongPolling?: boolean;
|
|
52
|
+
/** Usar fetch en lugar de WebChannel */
|
|
53
|
+
experimentalAutoDetectLongPolling?: boolean;
|
|
54
|
+
/** Tamaño de caché en bytes */
|
|
55
|
+
cacheSizeBytes?: number;
|
|
56
|
+
/** Habilitar persistencia multi-tab */
|
|
57
|
+
synchronizeTabs?: boolean;
|
|
58
|
+
/** Timeout para requests (ms) */
|
|
59
|
+
timeout?: number;
|
|
60
|
+
/** Token de autenticación (se configura automáticamente si hay Auth) */
|
|
61
|
+
authToken?: string;
|
|
62
|
+
/** Proveedor de tokens personalizado */
|
|
63
|
+
authTokenProvider?: AuthTokenProvider;
|
|
64
|
+
/** Permite queries flexibles fuera de restricciones de Firestore (solo PostgreSQL) */
|
|
65
|
+
allowFlexibleQueries?: boolean;
|
|
66
|
+
/** Número máximo de reintentos para errores transitorios de red */
|
|
67
|
+
maxRetries?: number;
|
|
68
|
+
/** Delay inicial de reintento en ms (backoff exponencial) */
|
|
69
|
+
retryInitialDelayMs?: number;
|
|
70
|
+
/** Delay máximo de reintento en ms */
|
|
71
|
+
retryMaxDelayMs?: number;
|
|
72
|
+
}
|
|
73
|
+
/** Tipo de referencia */
|
|
74
|
+
type ReferenceType = 'document' | 'collection';
|
|
75
|
+
/** Referencia base (abstracta) */
|
|
76
|
+
interface BaseReference {
|
|
77
|
+
/** Tipo de referencia */
|
|
78
|
+
readonly type: ReferenceType;
|
|
79
|
+
/** Path completo */
|
|
80
|
+
readonly path: string;
|
|
81
|
+
/** ID del elemento (último segmento del path) */
|
|
82
|
+
readonly id: string;
|
|
83
|
+
/** Referencia a Firestore */
|
|
84
|
+
readonly firestore: FirestoreInstance;
|
|
85
|
+
}
|
|
86
|
+
/** Referencia a un documento */
|
|
87
|
+
interface DocumentReference<T = DocumentData> extends BaseReference {
|
|
88
|
+
readonly type: 'document';
|
|
89
|
+
/** Referencia a la colección padre */
|
|
90
|
+
readonly parent: CollectionReference<T>;
|
|
91
|
+
}
|
|
92
|
+
/** Referencia a una colección */
|
|
93
|
+
interface CollectionReference<_T = DocumentData> extends BaseReference {
|
|
94
|
+
readonly type: 'collection';
|
|
95
|
+
/** Referencia al documento padre (si es subcolección) */
|
|
96
|
+
readonly parent: DocumentReference | null;
|
|
97
|
+
}
|
|
98
|
+
/** Query de Firestore */
|
|
99
|
+
interface Query<_T = DocumentData> {
|
|
100
|
+
readonly type: 'query' | 'collectionGroup';
|
|
101
|
+
readonly firestore: FirestoreInstance;
|
|
102
|
+
/** Path de la colección */
|
|
103
|
+
readonly path: string;
|
|
104
|
+
}
|
|
105
|
+
/** Operadores de comparación */
|
|
106
|
+
type WhereFilterOp = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'array-contains' | 'array-contains-any' | 'in' | 'not-in';
|
|
107
|
+
/** Dirección de ordenamiento */
|
|
108
|
+
type OrderByDirection = 'asc' | 'desc';
|
|
109
|
+
/** Constraint de query: where */
|
|
110
|
+
interface WhereConstraint {
|
|
111
|
+
readonly type: 'where';
|
|
112
|
+
readonly field: string;
|
|
113
|
+
readonly op: WhereFilterOp;
|
|
114
|
+
readonly value: unknown;
|
|
115
|
+
}
|
|
116
|
+
/** Constraint de query: orderBy */
|
|
117
|
+
interface OrderByConstraint {
|
|
118
|
+
readonly type: 'orderBy';
|
|
119
|
+
readonly field: string;
|
|
120
|
+
readonly direction: OrderByDirection;
|
|
121
|
+
}
|
|
122
|
+
/** Constraint de query: limit */
|
|
123
|
+
interface LimitConstraint {
|
|
124
|
+
readonly type: 'limit' | 'limitToLast';
|
|
125
|
+
readonly limit: number;
|
|
126
|
+
}
|
|
127
|
+
/** Constraint de query: startAt/startAfter */
|
|
128
|
+
interface StartAtConstraint {
|
|
129
|
+
readonly type: 'startAt' | 'startAfter';
|
|
130
|
+
readonly values: unknown[];
|
|
131
|
+
readonly inclusive: boolean;
|
|
132
|
+
}
|
|
133
|
+
/** Constraint de query: endAt/endBefore */
|
|
134
|
+
interface EndAtConstraint {
|
|
135
|
+
readonly type: 'endAt' | 'endBefore';
|
|
136
|
+
readonly values: unknown[];
|
|
137
|
+
readonly inclusive: boolean;
|
|
138
|
+
}
|
|
139
|
+
/** Constraint de query: and (filtro compuesto) */
|
|
140
|
+
interface AndConstraint {
|
|
141
|
+
readonly type: 'and';
|
|
142
|
+
readonly constraints: QueryConstraint[];
|
|
143
|
+
}
|
|
144
|
+
/** Constraint de query: or (filtro compuesto) */
|
|
145
|
+
interface OrConstraint {
|
|
146
|
+
readonly type: 'or';
|
|
147
|
+
readonly constraints: QueryConstraint[];
|
|
148
|
+
}
|
|
149
|
+
/** Constraint de offset para paginación directa */
|
|
150
|
+
interface OffsetConstraint {
|
|
151
|
+
readonly type: 'offset';
|
|
152
|
+
readonly count: number;
|
|
153
|
+
}
|
|
154
|
+
/** Unión de todos los constraints */
|
|
155
|
+
type QueryConstraint = WhereConstraint | OrderByConstraint | LimitConstraint | StartAtConstraint | EndAtConstraint | AndConstraint | OrConstraint | OffsetConstraint;
|
|
156
|
+
/** Metadatos de un snapshot */
|
|
157
|
+
interface SnapshotMetadata {
|
|
158
|
+
/** Si viene de cache local */
|
|
159
|
+
readonly fromCache: boolean;
|
|
160
|
+
/** Si tiene cambios pendientes de sincronizar */
|
|
161
|
+
readonly hasPendingWrites: boolean;
|
|
162
|
+
}
|
|
163
|
+
/** Tipo de cambio en un documento */
|
|
164
|
+
type DocumentChangeType = 'added' | 'modified' | 'removed';
|
|
165
|
+
/** Snapshot de un documento */
|
|
166
|
+
interface DocumentSnapshot<T = DocumentData> {
|
|
167
|
+
/** ID del documento */
|
|
168
|
+
readonly id: string;
|
|
169
|
+
/** Referencia al documento */
|
|
170
|
+
readonly ref: DocumentReference<T>;
|
|
171
|
+
/** Si el documento existe */
|
|
172
|
+
exists(): boolean;
|
|
173
|
+
/** Obtener datos del documento */
|
|
174
|
+
data(): T | undefined;
|
|
175
|
+
/** Obtener un campo específico */
|
|
176
|
+
get(fieldPath: FieldPath): unknown;
|
|
177
|
+
/** Metadatos */
|
|
178
|
+
readonly metadata: SnapshotMetadata;
|
|
179
|
+
}
|
|
180
|
+
/** Cambio en un documento (para onSnapshot) */
|
|
181
|
+
interface DocumentChange<T = DocumentData> {
|
|
182
|
+
/** Tipo de cambio */
|
|
183
|
+
readonly type: DocumentChangeType;
|
|
184
|
+
/** Snapshot del documento */
|
|
185
|
+
readonly doc: DocumentSnapshot<T>;
|
|
186
|
+
/** Índice anterior (-1 si es nuevo) */
|
|
187
|
+
readonly oldIndex: number;
|
|
188
|
+
/** Índice nuevo (-1 si fue eliminado) */
|
|
189
|
+
readonly newIndex: number;
|
|
190
|
+
}
|
|
191
|
+
/** Snapshot de una query */
|
|
192
|
+
interface QuerySnapshot<T = DocumentData> {
|
|
193
|
+
/** Referencia a la query */
|
|
194
|
+
readonly query: Query<T>;
|
|
195
|
+
/** Documentos en el resultado */
|
|
196
|
+
readonly docs: DocumentSnapshot<T>[];
|
|
197
|
+
/** Si está vacío */
|
|
198
|
+
readonly empty: boolean;
|
|
199
|
+
/** Número de documentos */
|
|
200
|
+
readonly size: number;
|
|
201
|
+
/** Metadatos */
|
|
202
|
+
readonly metadata: SnapshotMetadata;
|
|
203
|
+
/** Iterar sobre documentos */
|
|
204
|
+
forEach(callback: (doc: DocumentSnapshot<T>) => void): void;
|
|
205
|
+
/** Obtener cambios desde el último snapshot */
|
|
206
|
+
docChanges(): DocumentChange<T>[];
|
|
207
|
+
}
|
|
208
|
+
/** Instancia de FirebaseApp */
|
|
209
|
+
interface FirebaseApp {
|
|
210
|
+
/** Nombre de la app */
|
|
211
|
+
readonly name: string;
|
|
212
|
+
/** Opciones de configuración */
|
|
213
|
+
readonly options: FirebaseOptions;
|
|
214
|
+
}
|
|
215
|
+
/** Instancia de Firestore */
|
|
216
|
+
interface FirestoreInstance {
|
|
217
|
+
/** App asociada */
|
|
218
|
+
readonly app: FirebaseApp;
|
|
219
|
+
/** Tipo de instancia */
|
|
220
|
+
readonly type: 'firestore';
|
|
221
|
+
/** Configuración interna */
|
|
222
|
+
readonly _config: FirestoreSettings & {
|
|
223
|
+
host: string;
|
|
224
|
+
ssl: boolean;
|
|
225
|
+
timeout: number;
|
|
226
|
+
maxRetries: number;
|
|
227
|
+
retryInitialDelayMs: number;
|
|
228
|
+
retryMaxDelayMs: number;
|
|
229
|
+
};
|
|
230
|
+
/** Configuración pública (compatible con Firebase SDK) */
|
|
231
|
+
readonly settings: FirestoreSettings;
|
|
232
|
+
/** Project ID */
|
|
233
|
+
readonly _projectId: string;
|
|
234
|
+
/** Database ID */
|
|
235
|
+
readonly _databaseId: string;
|
|
236
|
+
/** Obtiene el token de autenticación actual */
|
|
237
|
+
getToken(): Promise<string | null>;
|
|
238
|
+
}
|
|
239
|
+
/** Alias para compatibilidad con Firebase SDK */
|
|
240
|
+
type Firestore = FirestoreInstance;
|
|
241
|
+
/** Opciones para setDoc */
|
|
242
|
+
interface SetOptions {
|
|
243
|
+
/** Merge con datos existentes */
|
|
244
|
+
merge?: boolean;
|
|
245
|
+
/** Campos específicos a mergear */
|
|
246
|
+
mergeFields?: FieldPath[];
|
|
247
|
+
}
|
|
248
|
+
/** Función para cancelar suscripción */
|
|
249
|
+
type Unsubscribe = () => void;
|
|
250
|
+
/** Origen de lectura para listeners en tiempo real */
|
|
251
|
+
type ListenSource = 'default' | 'cache';
|
|
252
|
+
/** Opciones para onSnapshot */
|
|
253
|
+
interface SnapshotListenOptions {
|
|
254
|
+
/** Incluir cambios de metadatos */
|
|
255
|
+
includeMetadataChanges?: boolean;
|
|
256
|
+
/** Origen de datos del listener (Firestore moderno) */
|
|
257
|
+
source?: ListenSource;
|
|
258
|
+
}
|
|
259
|
+
/** Códigos de error de Firestore */
|
|
260
|
+
type FirestoreErrorCode = 'cancelled' | 'unknown' | 'invalid-argument' | 'deadline-exceeded' | 'not-found' | 'already-exists' | 'permission-denied' | 'resource-exhausted' | 'failed-precondition' | 'aborted' | 'out-of-range' | 'unimplemented' | 'internal' | 'unavailable' | 'data-loss' | 'unauthenticated';
|
|
261
|
+
/** Error de Firestore */
|
|
262
|
+
interface FirestoreError extends Error {
|
|
263
|
+
/** Código de error */
|
|
264
|
+
readonly code: FirestoreErrorCode;
|
|
265
|
+
/** Mensaje de error */
|
|
266
|
+
readonly message: string;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export type { AuthTokenProvider as A, CollectionReference as C, DocumentChange as D, EndAtConstraint as E, FieldPath as F, ListenSource as L, OrderByDirection as O, Query as Q, SetOptions as S, Unsubscribe as U, WhereFilterOp as W, DocumentData as a, DocumentReference as b, DocumentSnapshot as c, FieldValue as d, FirebaseApp as e, FirebaseOptions as f, Firestore as g, FirestoreError as h, FirestoreErrorCode as i, FirestoreSettings as j, QuerySnapshot as k, FirestoreInstance as l, LimitConstraint as m, OrderByConstraint as n, QueryConstraint as o, StartAtConstraint as p, WhereConstraint as q, SnapshotListenOptions as r, DocumentChangeType as s };
|