go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/sw/root_sw.ts (about)

     1  // Copyright 2021 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  /**
    16   * @fileoverview
    17   * This service worker redirects milo links to ResultUI links.
    18   * This is 200-400ms faster than redirecting on the server side.
    19   */
    20  
    21  // Tell TSC that this is a ServiceWorker script.
    22  declare const self: ServiceWorkerGlobalScope;
    23  // Add a dummy export so signal this file a module.
    24  // Otherwise TSC won't allow us to re-declare `self`.
    25  export {};
    26  
    27  self.addEventListener('fetch', (e) => {
    28    if (e.request.mode !== 'navigate') {
    29      return;
    30    }
    31  
    32    const url = new URL(e.request.url);
    33  
    34    const isSPA =
    35      // Project selector.
    36      url.pathname === '/' ||
    37      // Short build link.
    38      url.pathname.match(/^\/b\//) ||
    39      // Long build link.
    40      url.pathname.match(/^\/p\/[^/]+\/builders\/[^/]+\/[^/]+\//) ||
    41      // Consoles link.
    42      url.pathname.match(/^\/p\/[^/]+(\/)?$/) ||
    43      // Builders link.
    44      url.pathname.match(/^\/p\/[^/]+(\/g\/[^/]+)?\/builders(\/)?$/) ||
    45      // Invocation link.
    46      url.pathname.match(/^\/inv\//) ||
    47      // Artifact link.
    48      url.pathname.match(/^\/artifact\//) ||
    49      // Search page.
    50      url.pathname.match(/^\/search(\/|$)/);
    51  
    52    if (isSPA) {
    53      url.pathname = '/ui' + url.pathname;
    54      e.respondWith(Response.redirect(url.toString()));
    55      return;
    56    }
    57  });
    58  
    59  // Ensures that the redirection logic takes effect immediately so users won't be
    60  // redirected to broken pages (e.g. when app is rolled back to a previous
    61  // version).
    62  self.addEventListener('install', () => self.skipWaiting());
    63  self.addEventListener('activate', (e) => e.waitUntil(self.clients.claim()));