@stowkit/three-loader 0.1.33 → 0.1.34

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.
@@ -360,9 +360,14 @@ class MeshParser {
360
360
  * Create Three.js BufferGeometry from Draco compressed mesh data
361
361
  */
362
362
  static async createGeometry(geoInfo, dataBlob, dracoLoader, cacheKey, version) {
363
- // Try loading from IndexedDB cache first
363
+ // Try loading from IndexedDB cache first (non-blocking - don't await in parallel loads)
364
+ let cachePromise = null;
364
365
  if (cacheKey && version) {
365
- const cached = await AssetMemoryCache.getGeometry(cacheKey, version);
366
+ cachePromise = AssetMemoryCache.getGeometry(cacheKey, version);
367
+ }
368
+ // Check if cache resolved while we were starting
369
+ if (cachePromise) {
370
+ const cached = await cachePromise;
366
371
  if (cached) {
367
372
  const geometry = new THREE__namespace.BufferGeometry();
368
373
  geometry.setAttribute('position', new THREE__namespace.BufferAttribute(cached.positions, 3));
@@ -394,7 +399,7 @@ class MeshParser {
394
399
  reject(new Error(`Failed to decode Draco geometry: ${error}`));
395
400
  });
396
401
  });
397
- // Cache the decoded geometry
402
+ // Cache the decoded geometry (non-blocking)
398
403
  if (cacheKey && version) {
399
404
  const posAttr = geometry.getAttribute('position');
400
405
  const normAttr = geometry.getAttribute('normal');
@@ -406,9 +411,7 @@ class MeshParser {
406
411
  normals: (normAttr && 'array' in normAttr) ? normAttr.array : undefined,
407
412
  uvs: (uvAttr && 'array' in uvAttr) ? uvAttr.array : undefined,
408
413
  indices: indexAttr.array
409
- }).catch(() => {
410
- // Silent fail - caching is optional
411
- });
414
+ }).catch(() => { });
412
415
  }
413
416
  }
414
417
  return geometry;
@@ -1169,22 +1172,29 @@ class StowKitPack {
1169
1172
  return Array.from(uniqueTextures);
1170
1173
  }
1171
1174
  async loadKTX2Texture(data, textureName) {
1172
- // Try IndexedDB cache first
1175
+ // Start cache check but don't block on it
1173
1176
  const cacheKey = textureName ? `${this.packUrl}::${textureName}` : undefined;
1177
+ let cachePromise = null;
1174
1178
  if (cacheKey) {
1175
- const cached = await AssetMemoryCache.getTexture(cacheKey, this.packVersion);
1176
- if (cached) {
1177
- reader.PerfLogger.log(`[Perf] ✓ Texture "${textureName}": 0ms (IndexedDB cache)`);
1178
- const texture = new THREE__namespace.CompressedTexture([{ data: cached.data, width: cached.width, height: cached.height }], cached.width, cached.height, cached.format, THREE__namespace.UnsignedByteType);
1179
- texture.needsUpdate = true;
1180
- return texture;
1181
- }
1179
+ cachePromise = AssetMemoryCache.getTexture(cacheKey, this.packVersion);
1182
1180
  }
1183
- // Decode using Basis transcoder
1184
- const decodeStart = performance.now();
1181
+ // Check cache while starting decode
1185
1182
  const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
1186
1183
  const blob = new Blob([arrayBuffer]);
1187
1184
  const url = URL.createObjectURL(blob);
1185
+ const decodeStart = performance.now();
1186
+ // Race cache check vs decode start
1187
+ const [cached, _] = await Promise.all([
1188
+ cachePromise || Promise.resolve(null),
1189
+ Promise.resolve() // Start decode immediately
1190
+ ]);
1191
+ if (cached) {
1192
+ URL.revokeObjectURL(url);
1193
+ reader.PerfLogger.log(`[Perf] ✓ Texture "${textureName}": 0ms (IndexedDB cache)`);
1194
+ const texture = new THREE__namespace.CompressedTexture([{ data: cached.data, width: cached.width, height: cached.height }], cached.width, cached.height, cached.format, THREE__namespace.UnsignedByteType);
1195
+ texture.needsUpdate = true;
1196
+ return texture;
1197
+ }
1188
1198
  try {
1189
1199
  const texture = await new Promise((resolve, reject) => {
1190
1200
  this.ktx2Loader.load(url, (texture) => {
@@ -1198,7 +1208,7 @@ class StowKitPack {
1198
1208
  });
1199
1209
  const decodeTime = performance.now() - decodeStart;
1200
1210
  reader.PerfLogger.log(`[Perf] ✓ Texture "${textureName || 'unknown'}": ${decodeTime.toFixed(2)}ms (Basis decode ${texture.image?.width}x${texture.image?.height})`);
1201
- // Cache the transcoded texture data to IndexedDB
1211
+ // Cache the transcoded texture data to IndexedDB (non-blocking)
1202
1212
  if (cacheKey && texture.mipmaps && texture.mipmaps.length > 0) {
1203
1213
  const mipmap = texture.mipmaps[0];
1204
1214
  const dataArray = new Uint8Array(mipmap.data.buffer, mipmap.data.byteOffset, mipmap.data.byteLength);
@@ -1209,9 +1219,7 @@ class StowKitPack {
1209
1219
  format: texture.format,
1210
1220
  internalFormat: texture.format,
1211
1221
  compressed: true
1212
- }).catch(() => {
1213
- // Silent fail - caching is optional
1214
- });
1222
+ }).catch(() => { });
1215
1223
  }
1216
1224
  return texture;
1217
1225
  }