File size: 4,287 Bytes
8fd7a1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// MistWarp Performance Service Worker - Aggressive caching for 2x speedup
const CACHE_NAME = 'mistwarp-performance-v1';
const CACHE_URLS = [
  // Critical block media
  '/static/blocks-media/default/green-flag.svg',
  '/static/blocks-media/default/stop.svg',
  '/static/blocks-media/default/arrow.svg',
  '/static/blocks-media/default/rotate-left.svg',
  '/static/blocks-media/default/rotate-right.svg',
  
  // Common assets
  '/static/assets/scratch-cat.svg',
  '/static/assets/pop.wav',
  '/static/assets/meow.wav',
  
  // Fonts
  'https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap'
];

// Install event - preload critical resources
self.addEventListener('install', event => {
  console.log('πŸš€ MistWarp Service Worker installing...');
  
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('πŸ“¦ Preloading critical resources');
        return cache.addAll(CACHE_URLS);
      })
      .then(() => {
        console.log('βœ… Service Worker installed and critical resources cached');
        return self.skipWaiting();
      })
      .catch(error => {
        console.error('❌ Service Worker install failed:', error);
      })
  );
});

// Activate event - clean up old caches
self.addEventListener('activate', event => {
  console.log('πŸ”„ MistWarp Service Worker activating...');
  
  event.waitUntil(
    caches.keys()
      .then(cacheNames => {
        return Promise.all(
          cacheNames.map(cacheName => {
            if (cacheName !== CACHE_NAME) {
              console.log('πŸ—‘οΈ Deleting old cache:', cacheName);
              return caches.delete(cacheName);
            }
          })
        );
      })
      .then(() => {
        console.log('βœ… Service Worker activated');
        return self.clients.claim();
      })
  );
});

// Fetch event - cache strategy for performance
self.addEventListener('fetch', event => {
  const url = new URL(event.request.url);
  
  // Only handle GET requests
  if (event.request.method !== 'GET') {
    return;
  }
  
  // Strategy: Cache First for static assets, Network First for everything else
  if (shouldCacheResource(url)) {
    event.respondWith(cacheFirstStrategy(event.request));
  } else {
    event.respondWith(networkFirstStrategy(event.request));
  }
});

/**
 * Determine if a resource should be cached
 */
function shouldCacheResource(url) {
  const pathname = url.pathname;
  
  // Cache static assets
  return pathname.includes('/static/') ||
         pathname.includes('/blocks-media/') ||
         pathname.includes('/assets/') ||
         pathname.endsWith('.svg') ||
         pathname.endsWith('.png') ||
         pathname.endsWith('.jpg') ||
         pathname.endsWith('.wav') ||
         pathname.endsWith('.mp3') ||
         url.hostname === 'fonts.googleapis.com' ||
         url.hostname === 'fonts.gstatic.com';
}

/**
 * Cache First strategy - Check cache first, fallback to network
 */
async function cacheFirstStrategy(request) {
  try {
    const cachedResponse = await caches.match(request);
    if (cachedResponse) {
      return cachedResponse;
    }
    
    const networkResponse = await fetch(request);
    
    // Cache successful responses
    if (networkResponse.status === 200) {
      const cache = await caches.open(CACHE_NAME);
      cache.put(request, networkResponse.clone());
    }
    
    return networkResponse;
  } catch (error) {
    console.warn('Cache first strategy failed:', error);
    return new Response('Network error', { status: 503 });
  }
}

/**
 * Network First strategy - Try network first, fallback to cache
 */
async function networkFirstStrategy(request) {
  try {
    const networkResponse = await fetch(request);
    
    // Cache successful responses for future use
    if (networkResponse.status === 200) {
      const cache = await caches.open(CACHE_NAME);
      cache.put(request, networkResponse.clone());
    }
    
    return networkResponse;
  } catch (error) {
    // Fallback to cache if network fails
    const cachedResponse = await caches.match(request);
    if (cachedResponse) {
      return cachedResponse;
    }
    
    console.warn('Network first strategy failed, no cache available:', error);
    return new Response('Network error', { status: 503 });
  }
}