@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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +692 -0
  3. package/dist/app.d.mts +51 -0
  4. package/dist/app.d.ts +51 -0
  5. package/dist/app.js +16 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/app.mjs +16 -0
  8. package/dist/app.mjs.map +1 -0
  9. package/dist/auth/index.d.mts +43 -0
  10. package/dist/auth/index.d.ts +43 -0
  11. package/dist/auth/index.js +18 -0
  12. package/dist/auth/index.js.map +1 -0
  13. package/dist/auth/index.mjs +18 -0
  14. package/dist/auth/index.mjs.map +1 -0
  15. package/dist/chunk-2RQUHE2K.js +719 -0
  16. package/dist/chunk-2RQUHE2K.js.map +1 -0
  17. package/dist/chunk-4CV4JOE5.js +27 -0
  18. package/dist/chunk-4CV4JOE5.js.map +1 -0
  19. package/dist/chunk-57XXMSJA.js +65 -0
  20. package/dist/chunk-57XXMSJA.js.map +1 -0
  21. package/dist/chunk-6J3LNKUQ.js +213 -0
  22. package/dist/chunk-6J3LNKUQ.js.map +1 -0
  23. package/dist/chunk-BXV7KTHB.js +645 -0
  24. package/dist/chunk-BXV7KTHB.js.map +1 -0
  25. package/dist/chunk-C3PCJJX4.mjs +645 -0
  26. package/dist/chunk-C3PCJJX4.mjs.map +1 -0
  27. package/dist/chunk-C6SKWUQV.mjs +213 -0
  28. package/dist/chunk-C6SKWUQV.mjs.map +1 -0
  29. package/dist/chunk-DXPQJR5D.mjs +2469 -0
  30. package/dist/chunk-DXPQJR5D.mjs.map +1 -0
  31. package/dist/chunk-MRVKMKSO.mjs +65 -0
  32. package/dist/chunk-MRVKMKSO.mjs.map +1 -0
  33. package/dist/chunk-NFEGQTCC.mjs +27 -0
  34. package/dist/chunk-NFEGQTCC.mjs.map +1 -0
  35. package/dist/chunk-RSBBZLDE.js +128 -0
  36. package/dist/chunk-RSBBZLDE.js.map +1 -0
  37. package/dist/chunk-RZWTSZSJ.js +2469 -0
  38. package/dist/chunk-RZWTSZSJ.js.map +1 -0
  39. package/dist/chunk-SZKHE2TQ.mjs +719 -0
  40. package/dist/chunk-SZKHE2TQ.mjs.map +1 -0
  41. package/dist/chunk-ZJ4A4Y2T.mjs +128 -0
  42. package/dist/chunk-ZJ4A4Y2T.mjs.map +1 -0
  43. package/dist/firestore/index.d.mts +1476 -0
  44. package/dist/firestore/index.d.ts +1476 -0
  45. package/dist/firestore/index.js +156 -0
  46. package/dist/firestore/index.js.map +1 -0
  47. package/dist/firestore/index.mjs +156 -0
  48. package/dist/firestore/index.mjs.map +1 -0
  49. package/dist/http-A2S5CWEV.js +10 -0
  50. package/dist/http-A2S5CWEV.js.map +1 -0
  51. package/dist/http-SZFONH6Z.mjs +10 -0
  52. package/dist/http-SZFONH6Z.mjs.map +1 -0
  53. package/dist/index.d.mts +4 -0
  54. package/dist/index.d.ts +4 -0
  55. package/dist/index.js +171 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/index.mjs +171 -0
  58. package/dist/index.mjs.map +1 -0
  59. package/dist/indexeddb-mutation-queue-5EB7C2D5.js +192 -0
  60. package/dist/indexeddb-mutation-queue-5EB7C2D5.js.map +1 -0
  61. package/dist/indexeddb-mutation-queue-M2MAH4E4.mjs +192 -0
  62. package/dist/indexeddb-mutation-queue-M2MAH4E4.mjs.map +1 -0
  63. package/dist/indexeddb-store-D23ZY3PR.mjs +162 -0
  64. package/dist/indexeddb-store-D23ZY3PR.mjs.map +1 -0
  65. package/dist/indexeddb-store-DNWBZUQE.js +162 -0
  66. package/dist/indexeddb-store-DNWBZUQE.js.map +1 -0
  67. package/dist/snapshot-MCQVLVHL.js +22 -0
  68. package/dist/snapshot-MCQVLVHL.js.map +1 -0
  69. package/dist/snapshot-ZWZFIFZD.mjs +22 -0
  70. package/dist/snapshot-ZWZFIFZD.mjs.map +1 -0
  71. package/dist/types-meoR-Ecp.d.mts +269 -0
  72. package/dist/types-meoR-Ecp.d.ts +269 -0
  73. package/package.json +78 -0
@@ -0,0 +1,719 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } 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; }
2
+
3
+
4
+ var _chunk57XXMSJAjs = require('./chunk-57XXMSJA.js');
5
+
6
+
7
+ var _chunk6J3LNKUQjs = require('./chunk-6J3LNKUQ.js');
8
+
9
+
10
+ var _chunkBXV7KTHBjs = require('./chunk-BXV7KTHB.js');
11
+
12
+
13
+ var _chunk4CV4JOE5js = require('./chunk-4CV4JOE5.js');
14
+
15
+ // src/persistence/local-store.ts
16
+ var LocalStore = class {
17
+ constructor() {
18
+ /** Cache de documentos indexado por path */
19
+ this.documents = /* @__PURE__ */ new Map();
20
+ /** Cache de resultados de queries indexado por key */
21
+ this.queries = /* @__PURE__ */ new Map();
22
+ }
23
+ // ===========================================================================
24
+ // DOCUMENTOS
25
+ // ===========================================================================
26
+ /** Almacena o actualiza un documento en cache */
27
+ putDocument(path, data, exists, updateTime) {
28
+ this.documents.set(path, {
29
+ path,
30
+ data: data ? structuredClonePolyfill(data) : null,
31
+ exists,
32
+ updateTime,
33
+ cachedAt: Date.now()
34
+ });
35
+ }
36
+ /** Obtiene un documento del cache (undefined si no existe en cache) */
37
+ getDocument(path) {
38
+ return this.documents.get(path);
39
+ }
40
+ /** Elimina un documento del cache */
41
+ removeDocument(path) {
42
+ this.documents.delete(path);
43
+ }
44
+ /** Marca un documento como eliminado en cache (sin removerlo del mapa) */
45
+ markDeleted(path) {
46
+ this.documents.set(path, {
47
+ path,
48
+ data: null,
49
+ exists: false,
50
+ cachedAt: Date.now()
51
+ });
52
+ }
53
+ /** Obtiene todos los documentos de una colección desde el cache */
54
+ getDocumentsByCollection(collectionPath) {
55
+ const results = [];
56
+ const prefix = collectionPath + "/";
57
+ for (const [path, doc] of this.documents) {
58
+ if (path.startsWith(prefix) && !path.substring(prefix.length).includes("/")) {
59
+ if (doc.exists) {
60
+ results.push(doc);
61
+ }
62
+ }
63
+ }
64
+ return results;
65
+ }
66
+ // ===========================================================================
67
+ // QUERIES
68
+ // ===========================================================================
69
+ /** Almacena el resultado de una query */
70
+ putQuery(key, documentPaths) {
71
+ this.queries.set(key, {
72
+ key,
73
+ documentPaths: [...documentPaths],
74
+ cachedAt: Date.now()
75
+ });
76
+ }
77
+ /** Obtiene un resultado de query del cache */
78
+ getQuery(key) {
79
+ return this.queries.get(key);
80
+ }
81
+ // ===========================================================================
82
+ // MANTENIMIENTO
83
+ // ===========================================================================
84
+ /** Limpia todo el cache */
85
+ clear() {
86
+ this.documents.clear();
87
+ this.queries.clear();
88
+ }
89
+ /** Número de documentos en cache */
90
+ get documentCount() {
91
+ return this.documents.size;
92
+ }
93
+ /** Número de queries en cache */
94
+ get queryCount() {
95
+ return this.queries.size;
96
+ }
97
+ };
98
+ function structuredClonePolyfill(obj) {
99
+ if (typeof globalThis.structuredClone === "function") {
100
+ try {
101
+ return globalThis.structuredClone(obj);
102
+ } catch (e) {
103
+ }
104
+ }
105
+ return JSON.parse(JSON.stringify(obj));
106
+ }
107
+
108
+ // src/persistence/mutation-queue.ts
109
+ var mutationCounter = 0;
110
+ var MutationQueue = class {
111
+ constructor() {
112
+ /** Cola ordenada de mutaciones pendientes */
113
+ this.queue = [];
114
+ /** Callbacks que esperan a que la cola se vacíe */
115
+ this.pendingWaiters = [];
116
+ }
117
+ /**
118
+ * Añade una mutación a la cola
119
+ * @returns ID de la mutación creada
120
+ */
121
+ add(type, path, data, options) {
122
+ const id = `mutation_${++mutationCounter}_${Date.now()}`;
123
+ this.queue.push({
124
+ id,
125
+ type,
126
+ path,
127
+ data: data ? { ...data } : null,
128
+ options: options ? { ...options } : void 0,
129
+ timestamp: Date.now()
130
+ });
131
+ return id;
132
+ }
133
+ /** Obtiene la siguiente mutación sin removerla */
134
+ peek() {
135
+ return this.queue[0];
136
+ }
137
+ /** Remueve y retorna la primera mutación de la cola */
138
+ shift() {
139
+ const mutation = this.queue.shift();
140
+ if (this.queue.length === 0) {
141
+ this.notifyWaiters();
142
+ }
143
+ return mutation;
144
+ }
145
+ /** Remueve una mutación específica por ID */
146
+ remove(id) {
147
+ const idx = this.queue.findIndex((m) => m.id === id);
148
+ if (idx === -1) return false;
149
+ this.queue.splice(idx, 1);
150
+ if (this.queue.length === 0) {
151
+ this.notifyWaiters();
152
+ }
153
+ return true;
154
+ }
155
+ /** Verifica si hay mutaciones pendientes para un path */
156
+ hasPendingForPath(path) {
157
+ return this.queue.some((m) => m.path === path);
158
+ }
159
+ /** Obtiene todas las mutaciones pendientes para un path (en orden) */
160
+ getForPath(path) {
161
+ return this.queue.filter((m) => m.path === path);
162
+ }
163
+ /** Obtiene todas las mutaciones pendientes para una colección */
164
+ getForCollection(collectionPath) {
165
+ const prefix = collectionPath + "/";
166
+ return this.queue.filter((m) => m.path.startsWith(prefix) && !m.path.substring(prefix.length).includes("/"));
167
+ }
168
+ /** Retorna todas las mutaciones pendientes (copia) */
169
+ getAll() {
170
+ return [...this.queue];
171
+ }
172
+ /** Número de mutaciones pendientes */
173
+ get size() {
174
+ return this.queue.length;
175
+ }
176
+ /** Si la cola está vacía */
177
+ get isEmpty() {
178
+ return this.queue.length === 0;
179
+ }
180
+ /** Limpia toda la cola */
181
+ clear() {
182
+ this.queue.length = 0;
183
+ this.notifyWaiters();
184
+ }
185
+ /**
186
+ * Espera a que todas las mutaciones pendientes se sincronicen.
187
+ * Resuelve inmediatamente si la cola ya está vacía.
188
+ */
189
+ waitForEmpty() {
190
+ if (this.queue.length === 0) {
191
+ return Promise.resolve();
192
+ }
193
+ return new Promise((resolve) => {
194
+ this.pendingWaiters.push(resolve);
195
+ });
196
+ }
197
+ /** Notifica a todos los waiters que la cola está vacía */
198
+ notifyWaiters() {
199
+ const waiters = this.pendingWaiters.splice(0);
200
+ for (const resolve of waiters) {
201
+ resolve();
202
+ }
203
+ }
204
+ };
205
+
206
+ // src/persistence/persistence-manager.ts
207
+ var managers = /* @__PURE__ */ new WeakMap();
208
+ function getPersistenceManager(firestore) {
209
+ return managers.get(firestore);
210
+ }
211
+ function createPersistenceManager(firestore) {
212
+ if (managers.has(firestore)) {
213
+ throw new Error("Persistence already enabled for this Firestore instance");
214
+ }
215
+ const pm = new PersistenceManager(firestore, new LocalStore(), new MutationQueue());
216
+ managers.set(firestore, pm);
217
+ return pm;
218
+ }
219
+ function createPersistenceManagerWithStores(firestore, store, mutations) {
220
+ if (managers.has(firestore)) {
221
+ throw new Error("Persistence already enabled for this Firestore instance");
222
+ }
223
+ const pm = new PersistenceManager(firestore, store, mutations);
224
+ managers.set(firestore, pm);
225
+ return pm;
226
+ }
227
+ async function removePersistenceManager(firestore) {
228
+ const pm = managers.get(firestore);
229
+ if (pm) {
230
+ await pm.destroy();
231
+ managers.delete(firestore);
232
+ }
233
+ }
234
+ var PersistenceManager = class {
235
+ constructor(firestore, store, mutations) {
236
+ this._networkState = "online";
237
+ this._flushing = false;
238
+ this.firestore = firestore;
239
+ this.store = store;
240
+ this.mutations = mutations;
241
+ }
242
+ // ===========================================================================
243
+ // ESTADO DE RED
244
+ // ===========================================================================
245
+ /** Si la red está habilitada */
246
+ get isOnline() {
247
+ return this._networkState === "online";
248
+ }
249
+ /** Habilita la red y comienza a sincronizar mutaciones pendientes */
250
+ async enableNetwork() {
251
+ this._networkState = "online";
252
+ await this.flushMutations();
253
+ }
254
+ /** Deshabilita la red — toda operación será local */
255
+ disableNetwork() {
256
+ this._networkState = "offline";
257
+ }
258
+ // ===========================================================================
259
+ // CACHE DE DOCUMENTOS
260
+ // ===========================================================================
261
+ /** Almacena un documento en cache (después de leerlo del servidor) */
262
+ async cacheDocument(path, data, exists, updateTime) {
263
+ await this.store.putDocument(path, data, exists, updateTime);
264
+ }
265
+ /** Lee un documento del cache */
266
+ async getCachedDocument(path) {
267
+ const cached = await this.store.getDocument(path);
268
+ if (!cached) return void 0;
269
+ return this.applyPendingMutations(path, cached.data, cached.exists);
270
+ }
271
+ /** Lee documentos de una colección del cache */
272
+ async getCachedCollection(collectionPath) {
273
+ const docs = await this.store.getDocumentsByCollection(collectionPath);
274
+ const results = [];
275
+ const seenPaths = /* @__PURE__ */ new Set();
276
+ for (const doc of docs) {
277
+ seenPaths.add(doc.path);
278
+ const applied = await this.applyPendingMutations(doc.path, doc.data, doc.exists);
279
+ if (applied.exists && applied.data) {
280
+ results.push({ path: doc.path, data: applied.data, exists: true });
281
+ }
282
+ }
283
+ const collectionMutations = await this.mutations.getForCollection(collectionPath);
284
+ for (const mutation of collectionMutations) {
285
+ if (!seenPaths.has(mutation.path) && mutation.type !== "delete" && mutation.data) {
286
+ results.push({ path: mutation.path, data: mutation.data, exists: true });
287
+ }
288
+ }
289
+ return results;
290
+ }
291
+ /** Almacena resultados de query en cache */
292
+ async cacheQuery(key, documentPaths) {
293
+ await this.store.putQuery(key, documentPaths);
294
+ }
295
+ /** Lee resultados de query del cache */
296
+ async getCachedQuery(key) {
297
+ const cached = await this.store.getQuery(key);
298
+ return _optionalChain([cached, 'optionalAccess', _ => _.documentPaths]);
299
+ }
300
+ // ===========================================================================
301
+ // COLA DE MUTACIONES
302
+ // ===========================================================================
303
+ /** Registra una escritura local (optimistic update + queue) */
304
+ async addLocalWrite(type, path, data, options) {
305
+ if (type === "delete") {
306
+ await this.store.markDeleted(path);
307
+ } else if (type === "set" && !_optionalChain([options, 'optionalAccess', _2 => _2.merge]) && !_optionalChain([options, 'optionalAccess', _3 => _3.mergeFields])) {
308
+ await this.store.putDocument(path, data, true);
309
+ } else {
310
+ const existing = await this.store.getDocument(path);
311
+ const mergedData = this.mergeData(_nullishCoalesce(_optionalChain([existing, 'optionalAccess', _4 => _4.data]), () => ( {})), _nullishCoalesce(data, () => ( {})), options);
312
+ await this.store.putDocument(path, mergedData, true);
313
+ }
314
+ await this.mutations.add(type, path, data, options);
315
+ }
316
+ /** Remueve una mutación completada de la cola */
317
+ async completeMutation(id) {
318
+ await this.mutations.remove(id);
319
+ }
320
+ /** Verifica si un documento tiene escrituras pendientes */
321
+ async hasPendingWrites(path) {
322
+ return this.mutations.hasPendingForPath(path);
323
+ }
324
+ /** Espera a que todas las escrituras pendientes se sincronicen */
325
+ waitForPendingWrites() {
326
+ return this.mutations.waitForEmpty();
327
+ }
328
+ // ===========================================================================
329
+ // SINCRONIZACIÓN
330
+ // ===========================================================================
331
+ /**
332
+ * Intenta sincronizar todas las mutaciones pendientes con el servidor.
333
+ * Procesa en orden FIFO. Si una falla con error de red, para y reintenta después.
334
+ */
335
+ async flushMutations() {
336
+ const empty = await this.mutations.isEmpty;
337
+ if (this._flushing || !this.isOnline || empty) return;
338
+ this._flushing = true;
339
+ try {
340
+ const client = _chunk6J3LNKUQjs.getHttpClient.call(void 0, this.firestore);
341
+ let pending = !await this.mutations.isEmpty;
342
+ while (pending && this.isOnline) {
343
+ const mutation = await this.mutations.peek();
344
+ if (!mutation) break;
345
+ try {
346
+ await this.executeMutation(client, mutation);
347
+ await this.mutations.shift();
348
+ } catch (error) {
349
+ const code = _optionalChain([error, 'optionalAccess', _5 => _5.code]);
350
+ if (code === "unavailable" || code === "deadline-exceeded") {
351
+ break;
352
+ }
353
+ await this.mutations.shift();
354
+ await this.rollbackDocument(mutation.path);
355
+ }
356
+ }
357
+ } finally {
358
+ this._flushing = false;
359
+ }
360
+ }
361
+ // ===========================================================================
362
+ // LIMPIEZA
363
+ // ===========================================================================
364
+ /** Limpia todo (cache + cola) */
365
+ async clear() {
366
+ await this.store.clear();
367
+ await this.mutations.clear();
368
+ }
369
+ /** Destruye el manager */
370
+ async destroy() {
371
+ await this.clear();
372
+ this._networkState = "offline";
373
+ }
374
+ // ===========================================================================
375
+ // HELPERS PRIVADOS
376
+ // ===========================================================================
377
+ /**
378
+ * Aplica mutaciones pendientes a un documento cacheado.
379
+ * Esto es la "compensación de latencia" — el usuario ve sus cambios inmediatamente.
380
+ */
381
+ async applyPendingMutations(path, baseData, baseExists) {
382
+ const pending = await this.mutations.getForPath(path);
383
+ if (pending.length === 0) return { data: baseData, exists: baseExists };
384
+ let data = baseData ? { ...baseData } : null;
385
+ let exists = baseExists;
386
+ for (const mutation of pending) {
387
+ switch (mutation.type) {
388
+ case "set":
389
+ if (!_optionalChain([mutation, 'access', _6 => _6.options, 'optionalAccess', _7 => _7.merge]) && !_optionalChain([mutation, 'access', _8 => _8.options, 'optionalAccess', _9 => _9.mergeFields])) {
390
+ data = mutation.data ? { ...mutation.data } : null;
391
+ } else {
392
+ data = this.mergeData(_nullishCoalesce(data, () => ( {})), _nullishCoalesce(mutation.data, () => ( {})), mutation.options);
393
+ }
394
+ exists = true;
395
+ break;
396
+ case "update":
397
+ if (exists && data) {
398
+ data = { ...data, ..._nullishCoalesce(mutation.data, () => ( {})) };
399
+ }
400
+ break;
401
+ case "delete":
402
+ data = null;
403
+ exists = false;
404
+ break;
405
+ }
406
+ }
407
+ return { data, exists };
408
+ }
409
+ /** Fusiona datos para set con merge o update */
410
+ mergeData(existing, incoming, options) {
411
+ if (_optionalChain([options, 'optionalAccess', _10 => _10.mergeFields])) {
412
+ const result = { ...existing };
413
+ for (const field of options.mergeFields) {
414
+ if (field in incoming) {
415
+ result[field] = incoming[field];
416
+ }
417
+ }
418
+ return result;
419
+ }
420
+ return { ...existing, ...incoming };
421
+ }
422
+ /**
423
+ * Ejecuta una mutación contra el servidor.
424
+ */
425
+ async executeMutation(client, mutation) {
426
+ const fields = mutation.data ? _chunkBXV7KTHBjs.toFirestoreFields.call(void 0, mutation.data) : {};
427
+ switch (mutation.type) {
428
+ case "set": {
429
+ if (_optionalChain([mutation, 'access', _11 => _11.options, 'optionalAccess', _12 => _12.merge]) || _optionalChain([mutation, 'access', _13 => _13.options, 'optionalAccess', _14 => _14.mergeFields])) {
430
+ const fieldPaths = mutation.options.mergeFields || Object.keys(_nullishCoalesce(mutation.data, () => ( {})));
431
+ await client.patch(`/documents/${mutation.path}`, {
432
+ fields,
433
+ updateMask: { fieldPaths }
434
+ });
435
+ } else {
436
+ const parts = mutation.path.split("/");
437
+ const parentPath = parts.slice(0, -1).join("/");
438
+ const documentId = parts[parts.length - 1];
439
+ await client.post(`/documents/${parentPath}?documentId=${documentId}`, { fields });
440
+ }
441
+ break;
442
+ }
443
+ case "update": {
444
+ const fieldPaths = Object.keys(_nullishCoalesce(mutation.data, () => ( {})));
445
+ await client.patch(`/documents/${mutation.path}`, {
446
+ fields,
447
+ updateMask: { fieldPaths }
448
+ });
449
+ break;
450
+ }
451
+ case "delete": {
452
+ await client.delete(`/documents/${mutation.path}`);
453
+ break;
454
+ }
455
+ }
456
+ }
457
+ /**
458
+ * Rollback: refresca el documento del servidor para corregir el cache.
459
+ * Si falla, simplemente remueve del cache.
460
+ */
461
+ async rollbackDocument(path) {
462
+ try {
463
+ const client = _chunk6J3LNKUQjs.getHttpClient.call(void 0, this.firestore);
464
+ const doc = await client.get(`/documents/${path}`);
465
+ if (_optionalChain([doc, 'optionalAccess', _15 => _15.fields])) {
466
+ await this.store.putDocument(path, doc.fields, true, doc.updateTime);
467
+ } else {
468
+ await this.store.removeDocument(path);
469
+ }
470
+ } catch (e2) {
471
+ await this.store.removeDocument(path);
472
+ }
473
+ }
474
+ };
475
+
476
+ // src/firestore/firestore.ts
477
+ var firestoreInstances = /* @__PURE__ */ new Map();
478
+ var authProviders = /* @__PURE__ */ new Map();
479
+ var FirestoreImpl = class {
480
+ constructor(app, settings) {
481
+ this.app = app;
482
+ this.type = "firestore";
483
+ this._terminated = false;
484
+ this._emulatorConfig = null;
485
+ this._authUnsubscribe = null;
486
+ const defaultHost = app.options.baseUrl ? new URL(app.options.baseUrl).host : "localhost:3000";
487
+ this._config = {
488
+ host: _optionalChain([settings, 'optionalAccess', _16 => _16.host]) || defaultHost,
489
+ ssl: _nullishCoalesce(_optionalChain([settings, 'optionalAccess', _17 => _17.ssl]), () => ( (defaultHost.includes("https") || defaultHost.includes("443")))),
490
+ timeout: _optionalChain([settings, 'optionalAccess', _18 => _18.timeout]) || 12e3,
491
+ authToken: _optionalChain([settings, 'optionalAccess', _19 => _19.authToken]),
492
+ authTokenProvider: _optionalChain([settings, 'optionalAccess', _20 => _20.authTokenProvider]),
493
+ allowFlexibleQueries: _nullishCoalesce(_optionalChain([settings, 'optionalAccess', _21 => _21.allowFlexibleQueries]), () => ( false)),
494
+ maxRetries: _nullishCoalesce(_optionalChain([settings, 'optionalAccess', _22 => _22.maxRetries]), () => ( 2)),
495
+ retryInitialDelayMs: _nullishCoalesce(_optionalChain([settings, 'optionalAccess', _23 => _23.retryInitialDelayMs]), () => ( 150)),
496
+ retryMaxDelayMs: _nullishCoalesce(_optionalChain([settings, 'optionalAccess', _24 => _24.retryMaxDelayMs]), () => ( 2e3))
497
+ };
498
+ this._projectId = app.options.projectId;
499
+ this._databaseId = app.options.databaseId || "(default)";
500
+ const provider = authProviders.get(app.name);
501
+ if (provider) {
502
+ this._setupAuthProvider(provider);
503
+ }
504
+ }
505
+ /**
506
+ * Configura un proveedor de autenticación
507
+ * @internal
508
+ */
509
+ _setupAuthProvider(provider) {
510
+ this._config.authTokenProvider = provider;
511
+ if (provider.onAuthStateChanged) {
512
+ this._authUnsubscribe = provider.onAuthStateChanged((token) => {
513
+ this._config.authToken = _nullishCoalesce(token, () => ( void 0));
514
+ });
515
+ }
516
+ }
517
+ /**
518
+ * Configura el emulador
519
+ * @internal
520
+ */
521
+ _useEmulator(host, port) {
522
+ this._emulatorConfig = { host, port };
523
+ this._config.host = `${host}:${port}`;
524
+ this._config.ssl = false;
525
+ }
526
+ /**
527
+ * Obtiene la configuración del emulador
528
+ */
529
+ get emulatorConfig() {
530
+ return this._emulatorConfig;
531
+ }
532
+ /**
533
+ * Obtiene la configuración actual
534
+ */
535
+ get settings() {
536
+ return { ...this._config };
537
+ }
538
+ /**
539
+ * Construye la URL base para peticiones HTTP
540
+ */
541
+ get baseUrl() {
542
+ const protocol = this._config.ssl ? "https" : "http";
543
+ return `${protocol}://${this._config.host}/v1/projects/${this._projectId}/databases/${this._databaseId}`;
544
+ }
545
+ /**
546
+ * Construye la URL para WebSocket
547
+ */
548
+ get wsUrl() {
549
+ const protocol = this._config.ssl ? "wss" : "ws";
550
+ return `${protocol}://${this._config.host}/ws/projects/${this._projectId}/databases/${this._databaseId}`;
551
+ }
552
+ /**
553
+ * Token de autenticación actual
554
+ */
555
+ get authToken() {
556
+ return this._config.authToken;
557
+ }
558
+ /**
559
+ * Actualiza el token de autenticación
560
+ */
561
+ setAuthToken(token) {
562
+ this._config.authToken = token;
563
+ }
564
+ /**
565
+ * Verifica si la instancia está terminada
566
+ */
567
+ get terminated() {
568
+ return this._terminated;
569
+ }
570
+ /**
571
+ * Obtiene el token de autenticación actual.
572
+ * Prioridad: 1) Auth provider (si retorna token), 2) Token estático (setAuthToken).
573
+ * Compatible con Firebase: auth module y token manual coexisten.
574
+ */
575
+ async getToken() {
576
+ if (this._config.authTokenProvider) {
577
+ const providerToken = await this._config.authTokenProvider.getToken();
578
+ if (providerToken) {
579
+ return providerToken;
580
+ }
581
+ }
582
+ return _nullishCoalesce(this._config.authToken, () => ( null));
583
+ }
584
+ /**
585
+ * Termina la instancia de Firestore
586
+ */
587
+ terminate() {
588
+ if (this._authUnsubscribe) {
589
+ this._authUnsubscribe();
590
+ this._authUnsubscribe = null;
591
+ }
592
+ this._terminated = true;
593
+ firestoreInstances.delete(this.app.name);
594
+ }
595
+ };
596
+ function _registerAuthProvider(app, provider) {
597
+ authProviders.set(app.name, provider);
598
+ const instance = firestoreInstances.get(app.name);
599
+ if (instance) {
600
+ instance._setupAuthProvider(provider);
601
+ }
602
+ }
603
+ function getFirestore(app) {
604
+ if (!app) {
605
+ const { getApp } = (_chunk57XXMSJAjs.init_app.call(void 0, ), _chunk4CV4JOE5js.__toCommonJS.call(void 0, _chunk57XXMSJAjs.app_exports));
606
+ app = getApp();
607
+ }
608
+ const existing = firestoreInstances.get(app.name);
609
+ if (existing) {
610
+ return existing;
611
+ }
612
+ const instance = new FirestoreImpl(app);
613
+ firestoreInstances.set(app.name, instance);
614
+ return instance;
615
+ }
616
+ function initializeFirestore(app, settings) {
617
+ if (firestoreInstances.has(app.name)) {
618
+ throw new Error(
619
+ `Firestore ya ha sido inicializado para la app '${app.name}'. Usa getFirestore() para obtener la instancia existente.`
620
+ );
621
+ }
622
+ const instance = new FirestoreImpl(app, settings);
623
+ firestoreInstances.set(app.name, instance);
624
+ return instance;
625
+ }
626
+ async function terminate(firestore) {
627
+ firestore.terminate();
628
+ }
629
+ async function clearIndexedDbPersistence(firestore) {
630
+ await removePersistenceManager(firestore);
631
+ if (typeof indexedDB !== "undefined") {
632
+ const projectId = firestore._projectId;
633
+ const { IndexedDBStore } = await Promise.resolve().then(() => _interopRequireWildcard(require("./indexeddb-store-DNWBZUQE.js")));
634
+ const { IndexedDBMutationQueue } = await Promise.resolve().then(() => _interopRequireWildcard(require("./indexeddb-mutation-queue-5EB7C2D5.js")));
635
+ await IndexedDBStore.deleteDatabase(projectId);
636
+ await IndexedDBMutationQueue.deleteDatabase(projectId);
637
+ }
638
+ }
639
+ async function enableIndexedDbPersistence(firestore) {
640
+ if (getPersistenceManager(firestore)) {
641
+ return;
642
+ }
643
+ if (typeof indexedDB !== "undefined") {
644
+ const { IndexedDBStore } = await Promise.resolve().then(() => _interopRequireWildcard(require("./indexeddb-store-DNWBZUQE.js")));
645
+ const { IndexedDBMutationQueue } = await Promise.resolve().then(() => _interopRequireWildcard(require("./indexeddb-mutation-queue-5EB7C2D5.js")));
646
+ const projectId = firestore._projectId;
647
+ const store = new IndexedDBStore(projectId);
648
+ const mutations = new IndexedDBMutationQueue(projectId);
649
+ await store.init();
650
+ await mutations.init();
651
+ createPersistenceManagerWithStores(firestore, store, mutations);
652
+ } else {
653
+ createPersistenceManager(firestore);
654
+ }
655
+ }
656
+ async function enableMultiTabIndexedDbPersistence(firestore) {
657
+ if (getPersistenceManager(firestore)) {
658
+ return;
659
+ }
660
+ createPersistenceManager(firestore);
661
+ }
662
+ async function enableNetwork(firestore) {
663
+ const pm = getPersistenceManager(firestore);
664
+ if (pm) {
665
+ await pm.enableNetwork();
666
+ }
667
+ }
668
+ async function disableNetwork(firestore) {
669
+ const pm = getPersistenceManager(firestore);
670
+ if (pm) {
671
+ pm.disableNetwork();
672
+ }
673
+ }
674
+ async function waitForPendingWrites(firestore) {
675
+ const pm = getPersistenceManager(firestore);
676
+ if (pm) {
677
+ await pm.waitForPendingWrites();
678
+ }
679
+ }
680
+ function connectFirestoreEmulator(firestore, host, port, options) {
681
+ const impl = firestore;
682
+ if (impl.terminated) {
683
+ throw new Error("Firestore has already been terminated.");
684
+ }
685
+ if (impl.emulatorConfig) {
686
+ throw new Error("Firestore emulator has already been connected.");
687
+ }
688
+ impl._useEmulator(host, port);
689
+ if (_optionalChain([options, 'optionalAccess', _25 => _25.mockUserToken])) {
690
+ const token = typeof options.mockUserToken === "string" ? options.mockUserToken : JSON.stringify(options.mockUserToken);
691
+ impl.setAuthToken(token);
692
+ }
693
+ }
694
+ function setAuthToken(firestore, token) {
695
+ const impl = firestore;
696
+ impl.setAuthToken(_nullishCoalesce(token, () => ( void 0)));
697
+ }
698
+ function getAuthToken(firestore) {
699
+ const impl = firestore;
700
+ return impl.authToken;
701
+ }
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+ exports.getPersistenceManager = getPersistenceManager; exports._registerAuthProvider = _registerAuthProvider; exports.getFirestore = getFirestore; exports.initializeFirestore = initializeFirestore; exports.terminate = terminate; exports.clearIndexedDbPersistence = clearIndexedDbPersistence; exports.enableIndexedDbPersistence = enableIndexedDbPersistence; exports.enableMultiTabIndexedDbPersistence = enableMultiTabIndexedDbPersistence; exports.enableNetwork = enableNetwork; exports.disableNetwork = disableNetwork; exports.waitForPendingWrites = waitForPendingWrites; exports.connectFirestoreEmulator = connectFirestoreEmulator; exports.setAuthToken = setAuthToken; exports.getAuthToken = getAuthToken;
719
+ //# sourceMappingURL=chunk-2RQUHE2K.js.map