@geolonia/geonicdb-sdk 0.12.0 → 0.14.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/README.md +60 -1
- package/geonicdb.cjs +302 -2
- package/geonicdb.cjs.map +3 -3
- package/geonicdb.iife.js +302 -2
- package/geonicdb.iife.js.map +3 -3
- package/geonicdb.mjs +302 -2
- package/geonicdb.mjs.map +3 -3
- package/ngsi-v2/index.cjs +3 -0
- package/ngsi-v2/index.cjs.map +2 -2
- package/ngsi-v2/index.d.ts +6 -0
- package/ngsi-v2/index.mjs +3 -0
- package/ngsi-v2/index.mjs.map +2 -2
- package/package.json +1 -1
package/geonicdb.iife.js
CHANGED
|
@@ -85,6 +85,9 @@ var GeonicDBModule = (() => {
|
|
|
85
85
|
var DPOP_IDB_NAME = "geonicdb-sdk";
|
|
86
86
|
var DPOP_IDB_STORE = "dpop-sessions";
|
|
87
87
|
var DPOP_IDB_VERSION = 1;
|
|
88
|
+
var SDK_CACHE_IDB_NAME = "geonicdb-sdk-cache";
|
|
89
|
+
var SDK_CACHE_IDB_STORE = "responses";
|
|
90
|
+
var SDK_CACHE_IDB_VERSION = 1;
|
|
88
91
|
|
|
89
92
|
// src/sdk/dpop.ts
|
|
90
93
|
var dpopSupported = typeof crypto !== "undefined" && !!crypto.subtle && !!crypto.subtle.generateKey;
|
|
@@ -364,11 +367,97 @@ var GeonicDBModule = (() => {
|
|
|
364
367
|
constructor(maxEntries = SDK_CACHE_MAX_ENTRIES_DEFAULT) {
|
|
365
368
|
__publicField(this, "_store", /* @__PURE__ */ new Map());
|
|
366
369
|
__publicField(this, "_maxEntries");
|
|
370
|
+
/**
|
|
371
|
+
* Optional persistent backing store (IndexedDB) so cached validators survive
|
|
372
|
+
* a page reload (#1262). `null` in non-browser runtimes — the cache then
|
|
373
|
+
* behaves as a pure in-memory LRU.
|
|
374
|
+
*/
|
|
375
|
+
__publicField(this, "_persistence", null);
|
|
376
|
+
/**
|
|
377
|
+
* Auth-scope namespace for persisted entries. The auth layer sets this to a
|
|
378
|
+
* tenant + authenticated-principal identifier so that entries written by one
|
|
379
|
+
* principal are never read back by another sharing the same origin/tenant
|
|
380
|
+
* (different tabs / SDK instances each scope to their own principal).
|
|
381
|
+
*/
|
|
382
|
+
__publicField(this, "_scope", "");
|
|
383
|
+
/**
|
|
384
|
+
* Whether write-through persistence is currently active. Driven by the auth
|
|
385
|
+
* layer: enabled only for remembered sessions, so persisted entries belong to
|
|
386
|
+
* exactly one principal and are dropped on every credential change.
|
|
387
|
+
*/
|
|
388
|
+
__publicField(this, "_persistEnabled", false);
|
|
389
|
+
/**
|
|
390
|
+
* Serialises persistence writes so they complete in call order (#1262
|
|
391
|
+
* review). `set`/`delete`/`clearPersisted` are otherwise independent
|
|
392
|
+
* fire-and-forget ops; if a late `put()` resolved after a `remove()` /
|
|
393
|
+
* `clearScope()`, an evicted/deleted/logged-out entry could reappear in
|
|
394
|
+
* IndexedDB. Chaining them keeps the persisted store consistent with the
|
|
395
|
+
* in-memory state and with the auth-boundary flush.
|
|
396
|
+
*/
|
|
397
|
+
__publicField(this, "_persistQueue", Promise.resolve());
|
|
367
398
|
if (!Number.isInteger(maxEntries) || maxEntries <= 0) {
|
|
368
399
|
throw new Error(`SdkCache maxEntries must be a positive integer, got ${String(maxEntries)}`);
|
|
369
400
|
}
|
|
370
401
|
this._maxEntries = maxEntries;
|
|
371
402
|
}
|
|
403
|
+
/** Wire a persistence backend (called once at construction when available). */
|
|
404
|
+
attachPersistence(persistence) {
|
|
405
|
+
this._persistence = persistence;
|
|
406
|
+
}
|
|
407
|
+
/** Whether a persistence backend is attached. */
|
|
408
|
+
hasPersistence() {
|
|
409
|
+
return this._persistence !== null;
|
|
410
|
+
}
|
|
411
|
+
/** Set the auth-scope namespace used for persisted reads/writes. */
|
|
412
|
+
setScope(scope) {
|
|
413
|
+
this._scope = scope;
|
|
414
|
+
}
|
|
415
|
+
/** Enable or disable write-through persistence (driven by `rememberSession`). */
|
|
416
|
+
setPersistEnabled(enabled) {
|
|
417
|
+
this._persistEnabled = enabled && this._persistence !== null;
|
|
418
|
+
}
|
|
419
|
+
/** True when set/delete should propagate to the persistent store. */
|
|
420
|
+
get _persisting() {
|
|
421
|
+
return this._persistEnabled && this._persistence !== null;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Append a persistence operation to the serialised queue. The backend and
|
|
425
|
+
* scope are captured at enqueue time so a later scope change cannot retarget
|
|
426
|
+
* an already-queued op. A failing op is swallowed (persistence is
|
|
427
|
+
* best-effort) and does not stall the chain. Returns the tail so callers that
|
|
428
|
+
* need ordering (`clearPersisted`) can await it.
|
|
429
|
+
*/
|
|
430
|
+
_enqueuePersist(op) {
|
|
431
|
+
const persistence = this._persistence;
|
|
432
|
+
if (!persistence) return this._persistQueue;
|
|
433
|
+
const scope = this._scope;
|
|
434
|
+
this._persistQueue = this._persistQueue.catch(() => void 0).then(() => op(persistence, scope)).catch(() => void 0);
|
|
435
|
+
return this._persistQueue;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Load persisted entries for the current scope into memory, oldest first so
|
|
439
|
+
* the in-memory LRU recency order is preserved. Best-effort and idempotent —
|
|
440
|
+
* a no-op when no backend is attached. Called after a remembered session is
|
|
441
|
+
* restored so the very first request after a reload can send `If-None-Match`.
|
|
442
|
+
*/
|
|
443
|
+
async hydrate() {
|
|
444
|
+
if (!this._persistence) return;
|
|
445
|
+
const entries = await this._persistence.loadScope(this._scope, this._maxEntries);
|
|
446
|
+
for (const { key, entry } of entries) {
|
|
447
|
+
if (this._store.has(key)) this._store.delete(key);
|
|
448
|
+
this._store.set(key, entry);
|
|
449
|
+
}
|
|
450
|
+
while (this._store.size > this._maxEntries) {
|
|
451
|
+
const oldest = this._store.keys().next().value;
|
|
452
|
+
if (oldest === void 0) break;
|
|
453
|
+
this._store.delete(oldest);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/** Drop every persisted entry for the current scope (auth change / flush). */
|
|
457
|
+
async clearPersisted() {
|
|
458
|
+
if (!this._persistence) return;
|
|
459
|
+
await this._enqueuePersist((persistence, scope) => persistence.clearScope(scope));
|
|
460
|
+
}
|
|
372
461
|
/** Build a stable cache key. Method is upper-cased so casing differences do not produce duplicate entries. */
|
|
373
462
|
static keyFor(method, path) {
|
|
374
463
|
return `${method.toUpperCase()}:${path}`;
|
|
@@ -387,15 +476,27 @@ var GeonicDBModule = (() => {
|
|
|
387
476
|
this._store.delete(key);
|
|
388
477
|
}
|
|
389
478
|
this._store.set(key, entry);
|
|
479
|
+
const evicted = [];
|
|
390
480
|
while (this._store.size > this._maxEntries) {
|
|
391
481
|
const oldest = this._store.keys().next().value;
|
|
392
482
|
if (oldest === void 0) break;
|
|
393
483
|
this._store.delete(oldest);
|
|
484
|
+
evicted.push(oldest);
|
|
485
|
+
}
|
|
486
|
+
if (this._persisting) {
|
|
487
|
+
void this._enqueuePersist(async (persistence, scope) => {
|
|
488
|
+
await persistence.put(scope, key, entry);
|
|
489
|
+
if (evicted.length > 0) await persistence.remove(scope, evicted);
|
|
490
|
+
});
|
|
394
491
|
}
|
|
395
492
|
}
|
|
396
493
|
/** Delete a specific entry. Returns whether anything was removed. */
|
|
397
494
|
delete(key) {
|
|
398
|
-
|
|
495
|
+
const removed = this._store.delete(key);
|
|
496
|
+
if (removed && this._persisting) {
|
|
497
|
+
void this._enqueuePersist((persistence, scope) => persistence.remove(scope, [key]));
|
|
498
|
+
}
|
|
499
|
+
return removed;
|
|
399
500
|
}
|
|
400
501
|
/**
|
|
401
502
|
* Delete every entry whose key matches a predicate. Returns the array of
|
|
@@ -533,6 +634,49 @@ var GeonicDBModule = (() => {
|
|
|
533
634
|
/** Wire an SdkCache instance (called by GeonicDB constructor when caching is enabled). */
|
|
534
635
|
setCache(cache) {
|
|
535
636
|
this._cache = cache;
|
|
637
|
+
cache?.setScope(this._cacheScope());
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* #1262: persistence scope for the SDK cache — tenant + authenticated
|
|
641
|
+
* principal (email when available). Keying on the principal, not just the
|
|
642
|
+
* tenant, prevents a different subject sharing the same origin/tenant (another
|
|
643
|
+
* tab, another SDK instance, a later login) from reading entries written by a
|
|
644
|
+
* previous principal. The principal segment is empty for sessions without a
|
|
645
|
+
* known email; such sessions never persist (persistence is gated on a
|
|
646
|
+
* remembered DPoP session that always carries an email), so the empty segment
|
|
647
|
+
* is not reachable as a write scope in practice.
|
|
648
|
+
*/
|
|
649
|
+
_cacheScope() {
|
|
650
|
+
return `${this._tenant}${this._email ?? ""}`;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* #1262: enable write-through persistence for the SDK cache so it survives a
|
|
654
|
+
* reload. Always re-scopes to the current tenant + principal first.
|
|
655
|
+
*
|
|
656
|
+
* `clearFirst` drops any persisted entries left by a previous session of the
|
|
657
|
+
* same principal — used on a fresh `login()`. It is `false` on
|
|
658
|
+
* `restoreSession()`, where the persisted entries belong to the very session
|
|
659
|
+
* being restored and are about to be rehydrated.
|
|
660
|
+
*/
|
|
661
|
+
async _enablePersistentCache(clearFirst) {
|
|
662
|
+
if (!this._cache) return;
|
|
663
|
+
this._cache.setScope(this._cacheScope());
|
|
664
|
+
if (clearFirst) await this._cache.clearPersisted();
|
|
665
|
+
this._cache.setPersistEnabled(true);
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* #1262: disable write-through persistence and drop the persisted cache for
|
|
669
|
+
* the current principal. Called on credential changes that do not persist a
|
|
670
|
+
* session (`setCredentials()`, non-remembered `login()`, `logout()`),
|
|
671
|
+
* mirroring the in-memory invalidation so a stale body can never outlive its
|
|
672
|
+
* principal. Callers that null out `_email` must invoke this **before** doing
|
|
673
|
+
* so, otherwise the scope no longer resolves to the principal being dropped.
|
|
674
|
+
*/
|
|
675
|
+
_disablePersistentCache() {
|
|
676
|
+
if (!this._cache) return;
|
|
677
|
+
this._cache.setScope(this._cacheScope());
|
|
678
|
+
this._cache.setPersistEnabled(false);
|
|
679
|
+
void this._cache.clearPersisted();
|
|
536
680
|
}
|
|
537
681
|
/** Provide the cache event emitter (forwarded to the GeonicDB EventEmitter). */
|
|
538
682
|
setCacheEventEmitter(emitter) {
|
|
@@ -587,6 +731,7 @@ var GeonicDBModule = (() => {
|
|
|
587
731
|
this._email = email;
|
|
588
732
|
this._rememberSession = wantsRemember;
|
|
589
733
|
this._invalidateAuthScopedState();
|
|
734
|
+
this._cache?.setPersistEnabled(false);
|
|
590
735
|
if (!wantsRemember && this._tenant) {
|
|
591
736
|
void clearDPoPSession(this._tenant);
|
|
592
737
|
}
|
|
@@ -596,6 +741,9 @@ var GeonicDBModule = (() => {
|
|
|
596
741
|
const bound = await this._bindDpopSession();
|
|
597
742
|
if (this._rememberSession) {
|
|
598
743
|
await this._persistDpopSession();
|
|
744
|
+
await this._enablePersistentCache(true);
|
|
745
|
+
} else {
|
|
746
|
+
this._disablePersistentCache();
|
|
599
747
|
}
|
|
600
748
|
return bound;
|
|
601
749
|
} catch (err) {
|
|
@@ -604,12 +752,18 @@ var GeonicDBModule = (() => {
|
|
|
604
752
|
this._tokenType = "Bearer";
|
|
605
753
|
this._refreshToken = null;
|
|
606
754
|
this._tokenPromise = null;
|
|
755
|
+
this._invalidateAuthScopedState();
|
|
756
|
+
this._disablePersistentCache();
|
|
607
757
|
this._rememberSession = false;
|
|
608
758
|
this._email = null;
|
|
609
|
-
this._invalidateAuthScopedState();
|
|
610
759
|
throw err;
|
|
611
760
|
}
|
|
612
761
|
}
|
|
762
|
+
this._rememberSession = false;
|
|
763
|
+
if (this._tenant) {
|
|
764
|
+
void clearDPoPSession(this._tenant);
|
|
765
|
+
}
|
|
766
|
+
this._disablePersistentCache();
|
|
613
767
|
return data;
|
|
614
768
|
}
|
|
615
769
|
/**
|
|
@@ -694,6 +848,12 @@ var GeonicDBModule = (() => {
|
|
|
694
848
|
this._refreshToken = opts.refreshToken || null;
|
|
695
849
|
this._tokenPromise = null;
|
|
696
850
|
this._invalidateAuthScopedState();
|
|
851
|
+
this._disablePersistentCache();
|
|
852
|
+
this._rememberSession = false;
|
|
853
|
+
this._email = null;
|
|
854
|
+
if (this._tenant) {
|
|
855
|
+
void clearDPoPSession(this._tenant);
|
|
856
|
+
}
|
|
697
857
|
}
|
|
698
858
|
/** Clear all credentials. */
|
|
699
859
|
logout() {
|
|
@@ -701,6 +861,7 @@ var GeonicDBModule = (() => {
|
|
|
701
861
|
this._tokenExpiry = 0;
|
|
702
862
|
this._refreshToken = null;
|
|
703
863
|
this._tokenPromise = null;
|
|
864
|
+
this._disablePersistentCache();
|
|
704
865
|
this._email = null;
|
|
705
866
|
if (this._tenant) {
|
|
706
867
|
void clearDPoPSession(this._tenant);
|
|
@@ -746,6 +907,8 @@ var GeonicDBModule = (() => {
|
|
|
746
907
|
this._email = persisted.email ?? null;
|
|
747
908
|
this._tokenPromise = null;
|
|
748
909
|
this._invalidateAuthScopedState();
|
|
910
|
+
await this._enablePersistentCache(false);
|
|
911
|
+
await this._cache?.hydrate();
|
|
749
912
|
return true;
|
|
750
913
|
}
|
|
751
914
|
/**
|
|
@@ -1368,6 +1531,140 @@ var GeonicDBModule = (() => {
|
|
|
1368
1531
|
}
|
|
1369
1532
|
};
|
|
1370
1533
|
|
|
1534
|
+
// src/sdk/cache-persistence.ts
|
|
1535
|
+
var cachePersistenceSupported = typeof globalThis.indexedDB !== "undefined" && typeof structuredClone !== "undefined";
|
|
1536
|
+
var SCOPE_SEP = "\0";
|
|
1537
|
+
var SCOPE_RANGE_END = "\uFFFF";
|
|
1538
|
+
function openCacheDB() {
|
|
1539
|
+
return new Promise((resolve, reject) => {
|
|
1540
|
+
const req = globalThis.indexedDB.open(
|
|
1541
|
+
SDK_CACHE_IDB_NAME,
|
|
1542
|
+
SDK_CACHE_IDB_VERSION
|
|
1543
|
+
);
|
|
1544
|
+
req.onupgradeneeded = () => {
|
|
1545
|
+
const db = req.result;
|
|
1546
|
+
if (!db.objectStoreNames.contains(SDK_CACHE_IDB_STORE)) {
|
|
1547
|
+
db.createObjectStore(SDK_CACHE_IDB_STORE, { keyPath: "id" });
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1550
|
+
req.onsuccess = () => {
|
|
1551
|
+
resolve(req.result);
|
|
1552
|
+
};
|
|
1553
|
+
req.onerror = () => {
|
|
1554
|
+
reject(req.error ?? new Error("IndexedDB open failed"));
|
|
1555
|
+
};
|
|
1556
|
+
req.onblocked = () => {
|
|
1557
|
+
reject(req.error ?? new Error("IndexedDB open blocked"));
|
|
1558
|
+
};
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
function recordId(scope, key) {
|
|
1562
|
+
return scope + SCOPE_SEP + key;
|
|
1563
|
+
}
|
|
1564
|
+
var IdbCachePersistence = class {
|
|
1565
|
+
async loadScope(scope, limit) {
|
|
1566
|
+
let db = null;
|
|
1567
|
+
try {
|
|
1568
|
+
db = await openCacheDB();
|
|
1569
|
+
const records = await new Promise((resolve, reject) => {
|
|
1570
|
+
const tx = db.transaction(SDK_CACHE_IDB_STORE, "readonly");
|
|
1571
|
+
const range = globalThis.IDBKeyRange.bound(
|
|
1572
|
+
scope + SCOPE_SEP,
|
|
1573
|
+
scope + SCOPE_SEP + SCOPE_RANGE_END
|
|
1574
|
+
);
|
|
1575
|
+
const req = tx.objectStore(SDK_CACHE_IDB_STORE).getAll(range);
|
|
1576
|
+
req.onsuccess = () => {
|
|
1577
|
+
resolve(req.result ?? []);
|
|
1578
|
+
};
|
|
1579
|
+
req.onerror = () => {
|
|
1580
|
+
reject(req.error ?? new Error("IndexedDB getAll failed"));
|
|
1581
|
+
};
|
|
1582
|
+
});
|
|
1583
|
+
return records.filter((r) => r && r.scope === scope && typeof r.key === "string" && r.entry).sort((a, b) => (a.entry.cachedAt ?? 0) - (b.entry.cachedAt ?? 0)).slice(-limit).map((r) => ({ key: r.key, entry: r.entry }));
|
|
1584
|
+
} catch {
|
|
1585
|
+
return [];
|
|
1586
|
+
} finally {
|
|
1587
|
+
db?.close();
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
async put(scope, key, entry) {
|
|
1591
|
+
let db = null;
|
|
1592
|
+
try {
|
|
1593
|
+
db = await openCacheDB();
|
|
1594
|
+
await new Promise((resolve, reject) => {
|
|
1595
|
+
const tx = db.transaction(SDK_CACHE_IDB_STORE, "readwrite");
|
|
1596
|
+
const record = { id: recordId(scope, key), scope, key, entry };
|
|
1597
|
+
tx.objectStore(SDK_CACHE_IDB_STORE).put(record);
|
|
1598
|
+
tx.oncomplete = () => {
|
|
1599
|
+
resolve();
|
|
1600
|
+
};
|
|
1601
|
+
tx.onerror = () => {
|
|
1602
|
+
reject(tx.error ?? new Error("IndexedDB put failed"));
|
|
1603
|
+
};
|
|
1604
|
+
tx.onabort = () => {
|
|
1605
|
+
reject(tx.error ?? new Error("IndexedDB transaction aborted"));
|
|
1606
|
+
};
|
|
1607
|
+
});
|
|
1608
|
+
} catch {
|
|
1609
|
+
} finally {
|
|
1610
|
+
db?.close();
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
async remove(scope, keys) {
|
|
1614
|
+
if (keys.length === 0) return;
|
|
1615
|
+
let db = null;
|
|
1616
|
+
try {
|
|
1617
|
+
db = await openCacheDB();
|
|
1618
|
+
await new Promise((resolve, reject) => {
|
|
1619
|
+
const tx = db.transaction(SDK_CACHE_IDB_STORE, "readwrite");
|
|
1620
|
+
const store = tx.objectStore(SDK_CACHE_IDB_STORE);
|
|
1621
|
+
for (const key of keys) store.delete(recordId(scope, key));
|
|
1622
|
+
tx.oncomplete = () => {
|
|
1623
|
+
resolve();
|
|
1624
|
+
};
|
|
1625
|
+
tx.onerror = () => {
|
|
1626
|
+
reject(tx.error ?? new Error("IndexedDB delete failed"));
|
|
1627
|
+
};
|
|
1628
|
+
tx.onabort = () => {
|
|
1629
|
+
reject(tx.error ?? new Error("IndexedDB transaction aborted"));
|
|
1630
|
+
};
|
|
1631
|
+
});
|
|
1632
|
+
} catch {
|
|
1633
|
+
} finally {
|
|
1634
|
+
db?.close();
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
async clearScope(scope) {
|
|
1638
|
+
let db = null;
|
|
1639
|
+
try {
|
|
1640
|
+
db = await openCacheDB();
|
|
1641
|
+
await new Promise((resolve, reject) => {
|
|
1642
|
+
const tx = db.transaction(SDK_CACHE_IDB_STORE, "readwrite");
|
|
1643
|
+
const range = globalThis.IDBKeyRange.bound(
|
|
1644
|
+
scope + SCOPE_SEP,
|
|
1645
|
+
scope + SCOPE_SEP + SCOPE_RANGE_END
|
|
1646
|
+
);
|
|
1647
|
+
tx.objectStore(SDK_CACHE_IDB_STORE).delete(range);
|
|
1648
|
+
tx.oncomplete = () => {
|
|
1649
|
+
resolve();
|
|
1650
|
+
};
|
|
1651
|
+
tx.onerror = () => {
|
|
1652
|
+
reject(tx.error ?? new Error("IndexedDB clear failed"));
|
|
1653
|
+
};
|
|
1654
|
+
tx.onabort = () => {
|
|
1655
|
+
reject(tx.error ?? new Error("IndexedDB transaction aborted"));
|
|
1656
|
+
};
|
|
1657
|
+
});
|
|
1658
|
+
} catch {
|
|
1659
|
+
} finally {
|
|
1660
|
+
db?.close();
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
function createCachePersistence() {
|
|
1665
|
+
return cachePersistenceSupported ? new IdbCachePersistence() : null;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1371
1668
|
// src/sdk/index.ts
|
|
1372
1669
|
var GeonicDB = class extends EventEmitter {
|
|
1373
1670
|
constructor(options) {
|
|
@@ -1397,6 +1694,8 @@ var GeonicDBModule = (() => {
|
|
|
1397
1694
|
};
|
|
1398
1695
|
if (opts.cache !== false) {
|
|
1399
1696
|
const cache = new SdkCache(opts.cacheMaxEntries ?? SDK_CACHE_MAX_ENTRIES_DEFAULT);
|
|
1697
|
+
const persistence = createCachePersistence();
|
|
1698
|
+
if (persistence) cache.attachPersistence(persistence);
|
|
1400
1699
|
this._auth.setCache(cache);
|
|
1401
1700
|
this._auth.setCacheEventEmitter((name, payload) => this.emit(name, payload));
|
|
1402
1701
|
}
|
|
@@ -1425,6 +1724,7 @@ var GeonicDBModule = (() => {
|
|
|
1425
1724
|
for (const key of removed) {
|
|
1426
1725
|
this._auth.emitCacheEvent("cacheInvalidated", { key, path: key.split(":").slice(1).join(":") });
|
|
1427
1726
|
}
|
|
1727
|
+
void cache.clearPersisted();
|
|
1428
1728
|
}
|
|
1429
1729
|
// --- Authentication ---
|
|
1430
1730
|
/**
|