Migrate OSM cache to localForage/IndexedDB

We don't want to hit limits with localStorage, and it's non-blocking
This commit is contained in:
2026-08-19 10:39:58 -06:00
parent 45f6f898fa
commit 61242420d1
10 changed files with 1421 additions and 1231 deletions
+4
View File
@@ -4,6 +4,7 @@ import {
setupTest as upstreamSetupTest,
} from 'ember-qunit';
import { setupNostrMocks } from './mock-nostr';
import { setupLocalForageMock } from './mock-local-forage';
import sinon from 'sinon';
function setupMapStyleMocks(hooks) {
@@ -98,6 +99,7 @@ function setupMapStyleMocks(hooks) {
function setupApplicationTest(hooks, options) {
upstreamSetupApplicationTest(hooks, options);
setupNostrMocks(hooks);
setupLocalForageMock(hooks);
setupMapStyleMocks(hooks);
// Additional setup for application tests can be done here.
@@ -119,6 +121,7 @@ function setupApplicationTest(hooks, options) {
function setupRenderingTest(hooks, options) {
upstreamSetupRenderingTest(hooks, options);
setupNostrMocks(hooks);
setupLocalForageMock(hooks);
// Additional setup for rendering tests can be done here.
}
@@ -126,6 +129,7 @@ function setupRenderingTest(hooks, options) {
function setupTest(hooks, options) {
upstreamSetupTest(hooks, options);
setupNostrMocks(hooks);
setupLocalForageMock(hooks);
// Additional setup for unit tests can be done here.
}
+59
View File
@@ -0,0 +1,59 @@
import Service from '@ember/service';
/**
* In-memory mock of the `localForage` service for tests. Uses per-store
* `Map`s so tests stay isolated from real IndexedDB state and stay
* deterministic.
*
* Mirrors the real service's interface: `get/set/remove/keys/clear/iterate`.
*/
export class MockLocalForageService extends Service {
_stores = new Map();
_store(name) {
let store = this._stores.get(name);
if (!store) {
store = new Map();
this._stores.set(name, store);
}
return store;
}
async get(storeName, key) {
const store = this._store(storeName);
return store.has(key) ? store.get(key) : null;
}
async set(storeName, key, value) {
this._store(storeName).set(key, value);
return value;
}
async remove(storeName, key) {
this._store(storeName).delete(key);
}
async keys(storeName) {
return [...this._store(storeName).keys()];
}
async clear(storeName) {
this._store(storeName).clear();
}
async iterate(storeName, fn) {
let result;
let idx = 0;
for (const [key, value] of this._store(storeName)) {
result = fn(value, key, idx);
idx++;
}
return result;
}
}
export function setupLocalForageMock(hooks) {
hooks.beforeEach(function () {
this.owner.register('service:localForage', MockLocalForageService);
});
}