aboutsummaryrefslogtreecommitdiff
path: root/webAO/utils/fileExists.ts
diff options
context:
space:
mode:
authorDavid Skoland <davidskoland@gmail.com>2026-04-01 13:59:13 +0200
committerDavid Skoland <davidskoland@gmail.com>2026-04-01 13:59:13 +0200
commit10b413c0f0a31bc9476eed86812b6bb90f82caed (patch)
tree94ac6676fcad76dc76e901e2889a30f7ba611d8d /webAO/utils/fileExists.ts
parentd6163543f483c35737da52b7e307cf6f65828f82 (diff)
Add asset preloading system for IC message rendering
Fix rendering race conditions where character sprites, pre-animations, and paired character assets were displayed before being downloaded. All assets referenced in an MS packet are now resolved and preloaded into the browser cache before the animation timeline starts. - Add unified assetCache module with session-wide promise caching - Add preloadMessageAssets orchestrator for parallel asset resolution - Cache fileExists HEAD requests so missing files aren't re-probed - Preload all SFX (emote, shout, realization, stab) alongside sprites - Use synchronous setEmoteFromUrl at all render transition points - Graceful fallback to legacy setEmote if preloading times out Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'webAO/utils/fileExists.ts')
-rw-r--r--webAO/utils/fileExists.ts18
1 files changed, 11 insertions, 7 deletions
diff --git a/webAO/utils/fileExists.ts b/webAO/utils/fileExists.ts
index 1dceb72..748bc1f 100644
--- a/webAO/utils/fileExists.ts
+++ b/webAO/utils/fileExists.ts
@@ -1,14 +1,15 @@
-export default async function fileExists(url: string): Promise<boolean> {
- return new Promise((resolve) => {
+const cache = new Map<string, Promise<boolean>>();
+
+export default function fileExists(url: string): Promise<boolean> {
+ const cached = cache.get(url);
+ if (cached !== undefined) return cached;
+
+ const promise = new Promise<boolean>((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open("HEAD", url);
xhr.onload = function checkLoad() {
if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- resolve(true);
- } else {
- resolve(false);
- }
+ resolve(xhr.status === 200);
}
};
xhr.onerror = function checkError() {
@@ -16,4 +17,7 @@ export default async function fileExists(url: string): Promise<boolean> {
};
xhr.send(null);
});
+
+ cache.set(url, promise);
+ return promise;
}