PageSourceSearch

https://bhapi.ai/sw.js

js bhapi.ai collected 2026-10-02 01:11:20 UTC 2,612 bytes, 100 lines download raw bytes

1const CACHE_VERSION = "bhapi-v1";
2const STATIC_CACHE = `static-${CACHE_VERSION}`;
3const RUNTIME_CACHE = `runtime-${CACHE_VERSION}`;
4
5const STATIC_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot)$/;
6
7const OFFLINE_PAGE = "/offline.html";
8
9// Install: precache the offline fallback page
10self.addEventListener("install", (event) => {
11  event.waitUntil(
12    caches
13      .open(STATIC_CACHE)
14      .then((cache) => cache.add(OFFLINE_PAGE))
15      .then(() => self.skipWaiting())
16  );
17});
18
19// Activate: clean up old caches
20self.addEventListener("activate", (event) => {
21  event.waitUntil(
22    caches
23      .keys()
24      .then((keys) =>
25        Promise.all(
26          keys
27            .filter(
28              (key) => key !== STATIC_CACHE && key !== RUNTIME_CACHE
29            )
30            .map((key) => caches.delete(key))
31        )
32      )
33      .then(() => self.clients.claim())
34  );
35});
36
37// Fetch: cache-first for static assets, network-first for API calls
38self.addEventListener("fetch", (event) => {
39  const { request } = event;
40  const url = new URL(request.url);
41
42  // Only handle GET requests
43  if (request.method !== "GET") return;
44
45  // Skip cross-origin requests
46  if (url.origin !== self.location.origin) return;
47
48  // Network-first for API calls
49  if (url.pathname.startsWith("/api/")) {
50    event.respondWith(networkFirst(request));
51    return;
52  }
53
54  // Cache-first for static assets
55  if (STATIC_EXTENSIONS.test(url.pathname)) {
56    event.respondWith(cacheFirst(request));
57    return;
58  }
59
60  // Network-first for HTML navigation (pages)
61  event.respondWith(networkFirst(request));
62});
63
64async function cacheFirst(request) {
65  const cached = await caches.match(request);
66  if (cached) return cached;
67
68  try {
69    const response = await fetch(request);
70    if (response.ok) {
71      const cache = await caches.open(STATIC_CACHE);
72      cache.put(request, response.clone());
73    }
74    return response;
75  } catch {
76    return new Response("", { status: 408, statusText: "Offline" });
77  }
78}
79
80async function networkFirst(request) {
81  try {
82    const response = await fetch(request);
83    if (response.ok) {
84      const cache = await caches.open(RUNTIME_CACHE);
85      cache.put(request, response.clone());
86    }
87    return response;
88  } catch {
89    const cached = await caches.match(request);
90    if (cached) return cached;
91
92    // For navigation requests, show offline page
93    if (request.mode === "navigate") {
94      const offlinePage = await caches.match(OFFLINE_PAGE);
95      if (offlinePage) return offlinePage;
96    }
97
98    return new Response("", { status: 408, statusText: "Offline" });
99  }
100}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.