PageSourceSearch

https://voiceofclaw.com/service-worker.js

js voiceofclaw.com collected 2026-10-02 01:47:54 UTC 4,940 bytes, 135 lines download raw bytes

1/**
2 * @license
3 * Copyright 2025 Google LLC
4 * SPDX-License-Identifier: Apache-2.0
5 */
6// service-worker.js
7
8// Define the target URL that we want to intercept and proxy.
9const TARGET_URL_PREFIX = 'https://generativelanguage.googleapis.com';
10
11// Installation event:
12self.addEventListener('install', (event) => {
13  try {
14    console.log('Service Worker: Installing...');
15    event.waitUntil(self.skipWaiting());
16  } catch (error) {
17    console.error('Service Worker: Error during install event:', error);
18    // If skipWaiting fails, the new SW might get stuck in a waiting state.
19  }
20});
21
22// Activation event:
23self.addEventListener('activate', (event) => {
24  try {
25    console.log('Service Worker: Activating...');
26    event.waitUntil(self.clients.claim());
27  } catch (error) {
28    console.error('Service Worker: Error during activate event:', error);
29    // If clients.claim() fails, the SW might not control existing pages until next nav.
30  }
31});
32
33// Fetch event:
34self.addEventListener('fetch', (event) => {
35  try {
36    const requestUrl = event.request.url;
37
38    if (requestUrl.startsWith(TARGET_URL_PREFIX)) {
39      console.log(`Service Worker: Intercepting request to ${requestUrl}`);
40
41      const remainingPathAndQuery = requestUrl.substring(TARGET_URL_PREFIX.length);
42      const proxyUrl = `${self.location.origin}/api-proxy${remainingPathAndQuery}`;
43
44      console.log(`Service Worker: Proxying to ${proxyUrl}`);
45
46      // Construct headers for the request to the proxy
47      const newHeaders = new Headers();
48      // Copy essential headers from the original request
49      // For OPTIONS (preflight) requests, Access-Control-Request-*  are critical.
50      // For actual requests (POST, GET), Content-Type, Accept etc.
51      const headersToCopy = [
52        'Content-Type', 
53        'Accept', 
54        'Access-Control-Request-Method', 
55        'Access-Control-Request-Headers',
56      ];
57
58      for (const headerName of headersToCopy) {
59        if (event.request.headers.has(headerName)) {
60          newHeaders.set(headerName, event.request.headers.get(headerName));
61        }
62      }
63
64      if (event.request.method === 'POST') {
65
66        // Ensure Content-Type is set for POST requests to the proxy, defaulting to application/json
67        if (!newHeaders.has('Content-Type')) {
68          console.warn("Service Worker: POST request to proxy was missing Content-Type in newHeaders. Defaulting to application/json.");
69          newHeaders.set('Content-Type', 'application/json');
70        } else {
71          console.log(`Service Worker: POST request to proxy has Content-Type: ${newHeaders.get('Content-Type')}`);
72        }
73      }
74
75      const createProxyRequest = async () => {
76        const body = event.request.method !== 'GET' && event.request.method !== 'HEAD' ? await event.request.arrayBuffer() : undefined;
77
78        const requestOptions = {
79          method: event.request.method,
80          headers: newHeaders,
81          body: body,
82          mode: event.request.mode,
83          credentials: event.request.credentials,
84          cache: event.request.cache,
85          redirect: event.request.redirect,
86          referrer: event.request.referrer,
87          integrity: event.request.integrity,
88        };
89
90        // Only set duplex if there's a body and it's a relevant method
91        if (body) {
92          requestOptions.duplex = 'half';
93        }
94
95        return new Request(proxyUrl, requestOptions);
96      };
97
98      const promise = createProxyRequest().then(proxyRequest => fetch(proxyRequest))
99        .then((response) => {
100          console.log(`Service Worker: Successfully proxied request to ${proxyUrl}, Status: ${response.status}`);
101          return response;
102        })
103        .catch((error) => {
104          // Log more error details
105          console.error(`Service Worker: Error proxying request to ${proxyUrl}. Message: ${error.message}, Name: ${error.name}, Stack: ${error.stack}`);
106          return new Response(
107            JSON.stringify({ error: 'Proxying failed', details: error.message, name: error.name, proxiedUrl: proxyUrl }),
108            {
109              status: 502, // Bad Gateway is appropriate for proxy errors
110              headers: { 'Content-Type': 'application/json' }
111            }
112          );
113        });
114
115      event.respondWith(promise);
116
117    } else {
118      // If the request URL doesn't match our target, let it proceed as normal.
119      event.respondWith(fetch(event.request));
120    }
121  } catch (error) {
122    // Log more error details for unhandled errors too
123    console.error('Service Worker: Unhandled error in fetch event handler. Message:', error.message, 'Name:', error.name, 'Stack:', error.stack);
124    event.respondWith(
125      new Response(
126        JSON.stringify({ error: 'Service worker fetch handler failed', details: error.message, name: error.name }),
127        {
128          status: 500,
129          headers: { 'Content-Type': 'application/json' }
130        }
131      )
132    );
133  }
134});
135

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.