Repository: microsoft/playwright
File: packages/trace-viewer/src/sw/main.ts (TypeScript)

Code before:
      const pageOrFrameId = relativePath.substring('/snapshotInfo/'.length);
      return loadedTrace!.snapshotServer.serveSnapshotInfo(pageOrFrameId, url.searchParams);
    }

    if (relativePath?.startsWith('/closest-screenshot/')) {
      const pageOrFrameId = relativePath.substring('/closest-screenshot/'.length);
      return loadedTrace!.snapshotServer.serveClosestScreenshot(pageOrFrameId, url.searchParams);
    }

    if (relativePath?.startsWith('/sha1/')) {
      const blob = await loadedTrace!.traceModel.resourceForSha1(relativePath.slice('/sha1/'.length));
      if (blob)
        return new Response(blob, { status: 200, headers: downloadHeaders(url.searchParams) });
      return new Response(null, { status: 404 });
    }
  }

  // Pass through to the server for file requests.
  if (relativePath?.startsWith('/file/')) {
    const path = url.searchParams.get('path')!;
    return await fetch(traceFileURL(path));
  }

  // Static content for sub-resource.
  return fetch(event.request);
}

function downloadHeaders(searchParams: URLSearchParams): Headers | undefined {
  const name = searchParams.get('dn');
  const contentType = searchParams.get('dct');
  if (!name)
    return;
  const headers = new Headers();
  headers.set('Content-Disposition', `attachment; filename="attachment"; filename*=UTF-8''${encodeURIComponent(name)}`);
  if (contentType)
    headers.set('Content-Type', contentType);
  return headers;
}

async function gc() {
  const clients = await self.clients.matchAll();
  const usedTraces = new Set<string>();

  for (const [clientId, traceUrl] of clientIdToTraceUrls) {
    // @ts-ignore
    if (!clients.find(c => c.id === clientId)) {
      clientIdToTraceUrls.delete(clientId);
      continue;
    }
    usedTraces.add(traceUrl);
  }

Review comment (suggestion):
I think the `@ts-ignore` inside `gc` can now also be removed

Code after:
      const pageOrFrameId = relativePath.substring('/snapshotInfo/'.length);
      return loadedTrace!.snapshotServer.serveSnapshotInfo(pageOrFrameId, url.searchParams);
    }

    if (relativePath.startsWith('/closest-screenshot/')) {
      const pageOrFrameId = relativePath.substring('/closest-screenshot/'.length);
      return loadedTrace!.snapshotServer.serveClosestScreenshot(pageOrFrameId, url.searchParams);
    }

    if (relativePath.startsWith('/sha1/')) {
      const blob = await loadedTrace!.traceModel.resourceForSha1(relativePath.slice('/sha1/'.length));
      if (blob)
        return new Response(blob, { status: 200, headers: downloadHeaders(url.searchParams) });
      return new Response(null, { status: 404 });
    }
  }

  // Pass through to the server for file requests.
  if (relativePath?.startsWith('/file/')) {
    const path = url.searchParams.get('path')!;
    return await fetch(traceFileURL(path));
  }

  // Static content for sub-resource.
  return fetch(event.request);
}

function downloadHeaders(searchParams: URLSearchParams): Headers | undefined {
  const name = searchParams.get('dn');
  const contentType = searchParams.get('dct');
  if (!name)
    return;
  const headers = new Headers();
  headers.set('Content-Disposition', `attachment; filename="attachment"; filename*=UTF-8''${encodeURIComponent(name)}`);
  if (contentType)
    headers.set('Content-Type', contentType);
  return headers;
}

async function gc() {
  const clients = await self.clients.matchAll();
  const usedTraces = new Set<string>();

  for (const [clientId, traceUrl] of clientIdToTraceUrls) {
    if (!clients.find(c => c.id === clientId)) {
      clientIdToTraceUrls.delete(clientId);
      continue;
    }
    usedTraces.add(traceUrl);
  }