PageSourceSearch

https://home.treasury.gov/sw.js

js treasury.gov collected 2026-10-01 06:14:43 UTC 4,402 bytes, 152 lines download raw bytes

1/**
2 * Service Worker for U.S. Department of the Treasury
3 * Provides offline caching and performance improvements
4 */
5
6const CACHE_VERSION = 'treasury-v1';
7const STATIC_CACHE = `${CACHE_VERSION}-static`;
8const PAGES_CACHE = `${CACHE_VERSION}-pages`;
9const IMAGES_CACHE = `${CACHE_VERSION}-images`;
10const RUNTIME_ARTIFACT_PREFIXES = [
11  '/api/rates/',
12  '/sites/default/files/interest-rates/',
13  '/resource-center/data-chart-center/interest-rates/TextView',
14  '/resource-center/data-chart-center/interest-rates/daily-treasury-rates.csv/',
15  '/resource-center/data-chart-center/interest-rates/pages/xml',
16  '/resource-center/data-chart-center/interest-rates/current-month/',
17  '/resource-center/data-chart-center/interest-rates/daily-treasury-rate-archives'
18];
19
20// Static assets to cache immediately
21const STATIC_ASSETS = [
22  '/',
23  '/news/press-releases/',
24  '/css/treasury.css',
25  '/js/treasury.js',
26  '/images/treasury-seal.svg',
27  '/images/treasury-seal.webp',
28  '/images/treasury-seal-green.webp',
29  '/images/favicon.png'
30];
31
32// Install event - cache static assets
33self.addEventListener('install', (event) => {
34  event.waitUntil(
35    caches.open(STATIC_CACHE)
36      .then((cache) => {
37        console.log('[SW] Caching static assets');
38        return cache.addAll(STATIC_ASSETS);
39      })
40      .then(() => self.skipWaiting())
41  );
42});
43
44// Activate event - clean up old caches
45self.addEventListener('activate', (event) => {
46  event.waitUntil(
47    caches.keys()
48      .then((cacheNames) => {
49        return Promise.all(
50          cacheNames
51            .filter((name) => name.startsWith('treasury-') && !name.startsWith(CACHE_VERSION))
52            .map((name) => {
53              console.log('[SW] Deleting old cache:', name);
54              return caches.delete(name);
55            })
56        );
57      })
58      .then(() => self.clients.claim())
59  );
60});
61
62// Fetch event - serve from cache, fallback to network
63self.addEventListener('fetch', (event) => {
64  const { request } = event;
65  const url = new URL(request.url);
66  
67  // Only handle same-origin requests
68  if (url.origin !== location.origin) {
69    return;
70  }
71  
72  // Skip non-GET requests
73  if (request.method !== 'GET') {
74    return;
75  }
76
77  if (isRuntimeArtifact(url.pathname)) {
78    event.respondWith(fetch(request, { cache: 'no-store' }));
79    return;
80  }
81  
82  // Strategy based on resource type
83  if (isStaticAsset(url.pathname)) {
84    // Cache-first for static assets
85    event.respondWith(cacheFirst(request, STATIC_CACHE));
86  } else if (isImage(url.pathname)) {
87    // Cache-first for images
88    event.respondWith(cacheFirst(request, IMAGES_CACHE));
89  } else if (isHTMLPage(request)) {
90    // Network-first for HTML pages (stale-while-revalidate)
91    event.respondWith(networkFirst(request, PAGES_CACHE));
92  }
93});
94
95// Cache-first strategy
96async function cacheFirst(request, cacheName) {
97  const cachedResponse = await caches.match(request);
98  if (cachedResponse) {
99    return cachedResponse;
100  }
101  
102  try {
103    const networkResponse = await fetch(request);
104    if (networkResponse.ok) {
105      const cache = await caches.open(cacheName);
106      cache.put(request, networkResponse.clone());
107    }
108    return networkResponse;
109  } catch (error) {
110    console.log('[SW] Fetch failed:', error);
111    return new Response('Offline', { status: 503 });
112  }
113}
114
115// Network-first strategy with cache fallback
116async function networkFirst(request, cacheName) {
117  try {
118    const networkResponse = await fetch(request);
119    if (networkResponse.ok) {
120      const cache = await caches.open(cacheName);
121      cache.put(request, networkResponse.clone());
122    }
123    return networkResponse;
124  } catch (error) {
125    console.log('[SW] Network failed, trying cache');
126    const cachedResponse = await caches.match(request);
127    if (cachedResponse) {
128      return cachedResponse;
129    }
130    // Return offline page
131    return caches.match('/');
132  }
133}
134
135// Helper functions
136function isStaticAsset(pathname) {
137  return /\.(css|js|woff2?|ttf|eot)$/i.test(pathname);
138}
139
140function isImage(pathname) {
141  return /\.(png|jpg|jpeg|gif|svg|webp|ico)$/i.test(pathname);
142}
143
144function isHTMLPage(request) {
145  return request.headers.get('accept')?.includes('text/html');
146}
147
148function isRuntimeArtifact(pathname) {
149  return pathname === '/api/x-feed.json' ||
150    pathname === '/api/x-feed.manifest.json' ||
151    RUNTIME_ARTIFACT_PREFIXES.some((prefix) => pathname.startsWith(prefix));
152}

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.