From 8e3de549c13b5e5b2624ae7b7d51d9e419480aef Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 27 Dec 2023 13:57:48 -0600 Subject: [PATCH] feat(asset): rename getAsset to get --- src/lib/AssetManager.ts | 34 +++++++++++++++++----------------- src/spec/AssetManager.spec.ts | 24 ++++++++++++------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/lib/AssetManager.ts b/src/lib/AssetManager.ts index 4dbbfb1..f5e55ec 100644 --- a/src/lib/AssetManager.ts +++ b/src/lib/AssetManager.ts @@ -1,54 +1,54 @@ const normalizePath = (path: string) => path.trim().toLowerCase().replaceAll(/\\/g, '/'); /** - * AssetManager provides an in-memory cache for game assets. Outbound HTTP requests are coalesced + * AssetManager provides an in-memory cache for remote assets. Outbound HTTP requests are coalesced * into a single request for any given asset path. Assets are cached based on their normalized path * name. */ class AssetManager { #baseUrl: string; #normalizePath: boolean; - #cache = new globalThis.Map(); - #pendingRequests = new globalThis.Map>(); + #loaded = new globalThis.Map(); + #loading = new globalThis.Map>(); constructor(baseUrl: string, normalizePath = true) { this.#baseUrl = baseUrl; this.#normalizePath = normalizePath; } - getAsset(path: string) { + get(path: string) { const cacheKey = normalizePath(path); - const cachedAsset = this.#cache.get(cacheKey); - if (cachedAsset) { - return Promise.resolve(cachedAsset); + const loaded = this.#loaded.get(cacheKey); + if (loaded) { + return Promise.resolve(loaded); } - const pendingAssetRequest = this.#pendingRequests.get(cacheKey); - if (pendingAssetRequest) { - return pendingAssetRequest; + const alreadyLoading = this.#loading.get(cacheKey); + if (alreadyLoading) { + return alreadyLoading; } - const newAssetRequest = this.#getMissingAsset(path, cacheKey); - this.#pendingRequests.set(cacheKey, newAssetRequest); + const loading = this.#load(path, cacheKey); + this.#loading.set(cacheKey, loading); - return newAssetRequest; + return loading; } - async #getMissingAsset(path: string, cacheKey: string) { + async #load(path: string, cacheKey: string) { const response = await fetch(this.#getFullUrl(path)); // Handle non-2xx responses if (!response.ok) { - this.#pendingRequests.delete(cacheKey); + this.#loading.delete(cacheKey); throw new Error(`Error fetching asset: ${response.status} ${response.statusText}`); } const data = await response.arrayBuffer(); - this.#cache.set(cacheKey, data); + this.#loaded.set(cacheKey, data); - this.#pendingRequests.delete(cacheKey); + this.#loading.delete(cacheKey); return data; } diff --git a/src/spec/AssetManager.spec.ts b/src/spec/AssetManager.spec.ts index 39f56dc..f34b623 100644 --- a/src/spec/AssetManager.spec.ts +++ b/src/spec/AssetManager.spec.ts @@ -10,40 +10,40 @@ const createFetchResponse = (status: number, statusText: string, data: ArrayBuff describe('AssetManager', () => { describe('getAsset', () => { - test('should return expected asset buffer when fetch succeeds', async () => { + test('should return expected asset data when fetch succeeds', async () => { const assetManager = new AssetManager('http://example.local', true); - const assetBuffer = new ArrayBuffer(7); + const assetData = new ArrayBuffer(7); const mockFetch = vi.fn(); - mockFetch.mockResolvedValue(createFetchResponse(200, 'Okay', assetBuffer)); + mockFetch.mockResolvedValue(createFetchResponse(200, 'Okay', assetData)); globalThis.fetch = mockFetch; - const returnedAssetBuffer = await assetManager.getAsset('foo'); + const returnedAssetData = await assetManager.get('foo'); - expect(returnedAssetBuffer).toEqual(assetBuffer); + expect(returnedAssetData).toEqual(assetData); }); test('should throw when fetch fails', async () => { const assetManager = new AssetManager('http://example.local', true); - const assetBuffer = new ArrayBuffer(7); + const assetData = new ArrayBuffer(7); const mockFetch = vi.fn(); - mockFetch.mockResolvedValue(createFetchResponse(404, 'Not Found', assetBuffer)); + mockFetch.mockResolvedValue(createFetchResponse(404, 'Not Found', assetData)); globalThis.fetch = mockFetch; - await expect(assetManager.getAsset('foo')).rejects.toBeInstanceOf(Error); + await expect(assetManager.get('foo')).rejects.toBeInstanceOf(Error); }); test('should only fetch once for a given asset path', async () => { const assetManager = new AssetManager('http://example.local', true); - const assetBuffer = new ArrayBuffer(7); + const assetData = new ArrayBuffer(7); const mockFetch = vi.fn(); - mockFetch.mockResolvedValue(createFetchResponse(200, 'Okay', assetBuffer)); + mockFetch.mockResolvedValue(createFetchResponse(200, 'Okay', assetData)); globalThis.fetch = mockFetch; - await assetManager.getAsset('foo'); - await assetManager.getAsset('foo'); + await assetManager.get('foo'); + await assetManager.get('foo'); expect(mockFetch).toHaveBeenCalledOnce(); });