TypeScript-এ সার্ভিস ওয়ার্কার

TypeScript-এ সার্ভিস ওয়ার্কার

এই নিবন্ধে TypeScript-এ সার্ভিস ওয়ার্কার ব্যাখ্যা করা হয়েছে।

আমরা TypeScript-এ সার্ভিস ওয়ার্কার সম্পর্কে ব্যবহারিক উদাহরণসহ ব্যাখ্যা করব।

YouTube Video

TypeScript-এ সার্ভিস ওয়ার্কার

একটি সার্ভিস ওয়ার্কার হল একটি "অনুরোধ প্রক্সি" যা ব্রাউজার ও নেটওয়ার্কের মধ্যে বসে। এটি ফেচ ইন্টারসেপ্ট, ক্যাশ কন্ট্রোল, অফলাইন সাপোর্ট এবং ব্যাকগ্রাউন্ড প্রসেসিং (সিঙ্ক এবং পুশ) সক্ষম করে। TypeScript ব্যবহার টাইপ সেফটি ও রক্ষণাবেক্ষণযোগ্যতা বৃদ্ধি করে।

TypeScript সেটআপ করা

tsconfig.json (WebWorker টাইপ চালু করা)

tsconfig.json-এ WebWorker টাইপ সক্রিয় করার একটি উদাহরণ দেখা যাক।

 1{
 2  "compilerOptions": {
 3    "target": "ES2020",
 4    "module": "ES2020",
 5    "lib": ["ES2020", "WebWorker"],
 6    "moduleResolution": "Bundler",
 7    "strict": true,
 8    "noEmitOnError": true,
 9    "outDir": "out",
10    "skipLibCheck": true
11  },
12  "include": ["sw.ts"]
13}
  • lib অ্যারেতে WebWorker যোগ করলে আপনি ServiceWorkerGlobalScope-এর মতো টাইপ ব্যবহার করতে পারবেন।
  • DOM এবং WebWorker-এর টাইপ আলাদা, তাই ব্রাউজার (মূল অ্যাপ) ও Service Worker-এর জন্য tsconfig.json সেটিং আলাদা করা সাধারণ প্র্যাকটিস।
  • Service Worker ফাইলগুলি শেষ পর্যন্ত স্কোপের সাথে মিলে যায় এমন একটি পথ-এ আউটপুট হয় (সাধারণত সাইটের মূল /sw.js)।
  • নিরাপত্তার স্বার্থে, সার্ভিস ওয়ার্কার কেবল HTTPS (বা localhost)-এ চলে।

ব্রাউজার পাশে রেজিস্ট্রেশনের কোড

register-sw.ts

1// register-sw.ts
2async function registerServiceWorker() {
3  if (!('serviceWorker' in navigator)) return;
4
5  try {
6    const registration = await navigator.serviceWorker.register(
7      '/sw.js', { scope: '/' }
8    );
  • এই প্রক্রিয়াটি একটি Service Worker নিবন্ধন করে। scope বলতে বোঝানো হয় যে পথগুলিকে Service Worker নিয়ন্ত্রণ করতে পারে সেই পরিসর। উদাহরণস্বরূপ, আপনি যদি /sw.js-কে মূল ডিরেক্টরির নিচে রাখেন এবং scope-কে মূল ডিরেক্টরি (/)-তে সেট করেন, তাহলে আপনি সম্পূর্ণ সাইটের সমস্ত রিসোর্স নিয়ন্ত্রণ করতে পারবেন। অন্যদিকে, আপনি যদি /app/ এর মতো একটি নির্দিষ্ট ডিরেক্টরি নির্ধারণ করেন, তাহলে শুধুমাত্র সেই ডিরেক্টরির অধীনে থাকা বিষয়বস্তু নিয়ন্ত্রিত হবে।
1    // If there's a waiting worker, notify the user.
2    if (registration.waiting) {
3      promptUserToUpdate(registration);
4    }
  • waiting নির্দেশ করে যে অবস্থায় একটি নতুন Service Worker ইনস্টল হয়েছে এবং অ্যাক্টিভেট হওয়ার জন্য অপেক্ষা করছে। এই পর্যায়ে, বিদ্যমান পেজগুলো এখনও পুরানো Service Worker দ্বারা নিয়ন্ত্রিত হয়, তাই সাধারণত ব্যবহারকারীর অনুমতি চাইতে হয় এবং অনুমতি পাওয়ার পর skipWaiting() কল করে নতুন Service Worker-টি সাথে সাথে অ্যাক্টিভেট করা হয়। এতে আপনি পরবর্তী পেজ রিলোডের জন্য অপেক্ষা না করেই সর্বশেষ প্রসেসিং প্রতিফলিত করতে পারবেন।
 1    // When a new SW is installing, monitor its state changes
 2    registration.addEventListener('updatefound', () => {
 3      const newWorker = registration.installing;
 4      if (!newWorker) return;
 5      newWorker.addEventListener('statechange', () => {
 6        if (newWorker.state === 'installed' &&
 7            navigator.serviceWorker.controller) {
 8          // New content available, prompt the user
 9          promptUserToUpdate(registration);
10        }
11      });
12    });
  • updatefound ট্রিগার হয় যখন একটি নতুন Service Worker ইনস্টলেশনের শুরু হয়। এই ইভেন্টটি ঘটলে, একটি নতুন Worker registration.installing-এ সেট হয়, তাই তার statechange পর্যবেক্ষণ করে ইনস্টলেশন কখন সম্পূর্ণ হয়েছে (installed) তা শনাক্ত করা যায়। এছাড়াও, যদি navigator.serviceWorker.controller বিদ্যমান থাকে, তাহলে এর মানে একটি পুরনো Service Worker ইতিমধ্যে পেজ নিয়ন্ত্রণ করছে, তাই এটি ব্যবহারকারীকে নতুন ভার্সনের অস্তিত্ব জানানোর একটি উপযুক্ত সুযোগ।
1    // When the active worker changes (e.g., after skipWaiting), reload if desired
2    navigator.serviceWorker.addEventListener('controllerchange', () => {
3      // Optionally reload to let the new SW take over
4      window.location.reload();
5    });
6  } catch (err) {
7    console.error('Service Worker registration failed: ', err);
8  }
9}
  • controllerchange ইভেন্টটি যখন নতুন Service Worker বর্তমান পেজ নিয়ন্ত্রণ শুরু করে, ঠিক তখনই ট্রিগার হয়। এই সময়ে রিলোড করলে সাথে সাথে নতুন ক্যাশ কৌশল ও প্রসেসিং কার্যকর হবে। তবে, স্বয়ংক্রিয় রিলোড ব্যবহারকারীর অভিজ্ঞতা খারাপ করতে পারে, তাই ব্যবহারকারীর সম্মতি পাওয়ার পর রিলোড করাটাই উত্তম
1function promptUserToUpdate(reg: ServiceWorkerRegistration) {
2  // Show UI to user. If user accepts:
3  if (reg.waiting) {
4    reg.waiting.postMessage({ type: 'SKIP_WAITING' });
5  }
6}
7
8registerServiceWorker();
  • ক্লায়েন্ট থেকে Service Worker-এ postMessage({ type: 'SKIP_WAITING' }) পাঠিয়ে এবং তারপর self.skipWaiting() কল করে, আপনি আপডেটের জন্য অনুরোধ জানাতে পারেন।

sw.ts-এ স্কোপ ঘোষণা

এরপর, অ্যাপ শেল ক্যাশিংয়ের একটি সাধারণ সার্ভিস ওয়ার্কার উদাহরণ দেখা যাক।

TypeScript-এ সার্ভিস ওয়ার্কার ব্যবহারে self-এ সঠিক টাইপ নির্ধারণ করা সুবিধাজনক।

1// sw.ts
2export default null;
3declare const self: ServiceWorkerGlobalScope;
  • TypeScript-এ self ডিফল্টভাবে any হিসাবে বিবেচনা করা হয়, তাই অতিরিক্ত টাইপ নির্দিষ্ট না করলে, Service Worker-নির্দিষ্ট API যেমন skipWaiting() বা clients-এর জন্য টাইপ কমপ্লিশন বা টাইপ চেকিং পাবেন না।
  • ServiceWorkerGlobalScope নির্ধারণ করলে স্বয়ংক্রিয় কমপ্লিশন, ভুল ব্যবহার রোধ এবং সাধারণ DOM স্ক্রিপ্ট থেকে আলাদাভাবে আরও নিরাপদ ডেভেলপমেন্ট সম্ভব হয়।

প্রাথমিক সার্ভিস ওয়ার্কার (ইনস্টল/অ্যাক্টিভেট/ফেচ)

এটি সহজ ক্যাশ সংস্করণ পরিচালনা, ইনস্টলে প্রিক্যাশিং, অ্যাক্টিভেট করলে পুরনো ক্যাশ ডিলিট এবং ফেচে ক্যাশিং কৌশল (স্ট্যাটিক অ্যাসেটের জন্য cache-first, API-র জন্য network-first) দেখায়।

sw.ts (ন্যূনতম সেটআপ + ক্যাশ স্ট্রাকচার)

 1const CACHE_NAME = 'app-shell-v1';
 2const STATIC_ASSETS = [
 3  '/',
 4  '/index.html',
 5  '/styles.css',
 6  '/main.js',
 7  '/fallback.png'
 8];
 9
10self.addEventListener('install', (event: ExtendableEvent) => {
11  // Pre-cache application shell
12  event.waitUntil(
13    caches.open(CACHE_NAME)
14      .then(cache => cache.addAll(STATIC_ASSETS))
15      // Activate immediately (optional: coordinate with client)
16      .then(() => self.skipWaiting())
17  );
18});
  • install ইভেন্ট চলাকালে অ্যাপের স্ট্যাটিক রিসোর্স (App Shell) পূর্বেই ক্যাশ করা হয়। self.skipWaiting() কল করার মাধ্যমে, নতুন Service Worker সঙ্গে সঙ্গে এক্টিভ হয় এবং পরবর্তী প্রবেশের জন্য অপেক্ষা না করেই সর্বশেষ ক্যাশ ব্যবহারযোগ্য করে তোলে।
 1self.addEventListener('activate', (event: ExtendableEvent) => {
 2  // Clean up old caches and take control of clients immediately
 3  event.waitUntil(
 4    caches.keys().then(keys =>
 5      Promise.all(keys
 6        .filter(key => key !== CACHE_NAME)
 7        .map(key => caches.delete(key)))
 8    ).then(() => self.clients.claim())
 9  );
10});
  • activate ইভেন্টে, পুরনো ক্যাশ সংস্করণগুলো মুছে দেওয়া হয় এবং Service Worker আপডেটেড অবস্থায় রাখা হয়। এছাড়াও, self.clients.claim() কল করে, নতুন Service Worker পেজ রিলোডের জন্য অপেক্ষা না করেই সব ক্লায়েন্ট নিয়ন্ত্রণ করতে পারে।
 1self.addEventListener('fetch', (event: FetchEvent) => {
 2  const request = event.request;
 3  const url = new URL(request.url);
 4
 5  // Navigation requests (SPA) -> network-first with fallback to cached index.html
 6  if (request.mode === 'navigate') {
 7    event.respondWith(
 8      fetch(request).catch(() => caches.match('/index.html') as Promise<Response>)
 9    );
10    return;
11  }
12
13  // Simple API routing: network-first for /api/
14  if (url.pathname.startsWith('/api/')) {
15    event.respondWith(networkFirst(request));
16    return;
17  }
18
19  // Static assets: cache-first
20  event.respondWith(cacheFirst(request));
21});
  • fetch-এ আপনি অনুরোধ ইন্টারসেপ্ট ও রেসপন্স নিয়ন্ত্রণ করতে পারেন। আপনি cache-first বা network-first-এর মতো কৌশল প্রয়োগ করতে পারেন, যা অফলাইন সহায়তা ও পারফরম্যান্স বাড়াতে কার্যকর।
1self.addEventListener('message', (event: ExtendableMessageEvent) => {
2  const data = (event as any).data;
3  if (!data) return;
4
5  if (data.type === 'SKIP_WAITING') {
6    // Force the waiting service worker to become active
7    self.skipWaiting();
8  }
9});
  • যদি SKIP_WAITING পাওয়া যায়, তাহলে self.skipWaiting() কল করে আপনি অপেক্ষমাণ Service Worker-কে সাথে সাথে অ্যাক্টিভেট করতে পারেন। ফলে, পরবর্তী অনুরোধ থেকে নতুন সংস্করণটি পেজ রিলোড ছাড়াই কার্যকর হবে।

ব্যবহারিক ক্যাশ কৌশল সংক্ষেপ

cache-first

Cache-first প্রথমে ক্যাশ চেক করে এবং থাকলে সঙ্গে সঙ্গে রেসপন্স করে। না থাকলে নেটওয়ার্ক থেকে আনে ও ফল ক্যাশে রেখে দেয়। এটি স্ট্যাটিক ফাইলের জন্য উপযোগী।

 1async function cacheFirst(request: Request): Promise<Response> {
 2  const cache = await caches.open(CACHE_NAME);
 3  const cached = await cache.match(request);
 4  if (cached) {
 5    return cached;
 6  }
 7  const response = await fetch(request);
 8  if (response && response.ok) {
 9    cache.put(request, response.clone());
10  }
11  return response;
12}
  • এই কোডে cache-first ইমপ্লিমেন্টেশন দেখানো হয়েছে। ক্যাশে থাকলে ফেরত দেয়; না থাকলে নেটওয়ার্ক থেকে এনে ক্যাশে রেখে দেয়। এটি খুব কম পরিবর্তন হয় এমন স্ট্যাটিক রিসোর্স, যেমন ছবি বা CSS-এর জন্য উপযুক্ত।

network-first

Network-first প্রথমে নেটওয়ার্ক চেষ্টা করে, ব্যর্থতা হলে ক্যাশে ফিরে যায়। এটি API-র জন্য উপযুক্ত যেখানে নতুনতা জরুরি।

 1async function networkFirst(request: Request): Promise<Response> {
 2  const cache = await caches.open(CACHE_NAME);
 3  try {
 4    const response = await fetch(request);
 5    if (response && response.ok) {
 6      cache.put(request, response.clone());
 7    }
 8    return response;
 9  } catch (err) {
10    const cached = await cache.match(request);
11    if (cached) return cached;
12    return new Response(JSON.stringify({ error: 'offline' }), {
13      status: 503,
14      headers: { 'Content-Type': 'application/json' }
15    });
16  }
17}
  • এই কোডে network-first ইমপ্লিমেন্টেশন দেখানো হয়েছে। নেটওয়ার্ক রেসপন্স এলে ক্যাশে রেখে দেয়; ব্যর্থ হলে ক্যাশড সংস্করণ ফেরত দেয়। এটি এমন রিসোর্সের জন্য উপযুক্ত যেগুলো নতুন ডেটা চায়, যেমন সংবাদ আর্টিকেল বা API রেসপন্স।

stale-while-revalidate

stale-while-revalidate প্রথমে ক্যাশ ফেরত দেয় এবং একই সময়ে পটভূমিতে নেটওয়ার্ক থেকে আপডেট করে। এটি রেসপন্সের গতি ও নতুনতার মধ্যে ভারসাম্য আনে।

 1async function staleWhileRevalidate(request: Request, cacheName = CACHE_NAME): Promise<Response> {
 2  const cache = await caches.open(cacheName);
 3  const cachedResponse = await cache.match(request);
 4  const networkFetch = fetch(request).then(networkResponse => {
 5    if (networkResponse && networkResponse.ok) {
 6      cache.put(request, networkResponse.clone());
 7    }
 8    return networkResponse;
 9  }).catch(() => undefined);
10
11  // Return cached immediately if exists, otherwise wait network
12  return cachedResponse || (await networkFetch) || new Response('offline', { status: 503 });
13}
  • ক্যাশে থাকলে সঙ্গে সঙ্গে ফেরত দেয়, আর ব্যাকগ্রাউন্ডে নেটওয়ার্ক থেকে নতুন ডেটা এনে ক্যাশ আপডেট করে। এটি ব্যবহারকারীকে দ্রুত রেসপন্স দেয় এবং পরেরবার আপডেটেড কন্টেন্ট ব্যবহার করে, ফলে UI বা হালকা ডেটা ডেলিভারিতে উপযােগী।

আপডেট ফ্লো অপ্টিমাইজ করা (আপডেট নোটিফিকেশন এবং নিরাপদ রিলোড)

Service Worker আপডেটগুলো সঙ্গে সঙ্গে কার্যকর হয় না; নতুন সংস্করণটি অপেক্ষা করবে যতক্ষণ না বিদ্যমান ট্যাবগুলো বন্ধ হয়।

এখানে, নতুন সংস্করণ প্রস্তুত হলে ক্লায়েন্টকে জানিয়ে ব্যবহারকারীর একশনে নিরাপদে পৃষ্ঠা রিলোড করার একটি ব্যবস্থা করা হয়েছে।

নতুন সংস্করণ প্রস্তুত হলে Service Worker পাশ থেকে ক্লায়েন্টকে জানান।

 1// In sw.ts: after 'activate' or when new version is ready, broadcast a message
 2async function notifyClientsUpdated() {
 3  const all = await self.clients.matchAll({ type: 'window' });
 4  for (const client of all) {
 5    client.postMessage({ type: 'SW_UPDATED' });
 6  }
 7}
 8
 9// e.g., call this at the end of 'activate'
10self.addEventListener('activate', (event) => {
11  event.waitUntil((async () => {
12    if ('navigationPreload' in self.registration) {
13      await self.registration.navigationPreload.enable();
14    }
15    // cache cleanup
16    const cacheNames = await caches.keys();
17    await Promise.all(
18      cacheNames.map((name) => {
19        if (name !== CACHE_NAME) {
20          return caches.delete(name);
21        }
22      })
23    );
24
25    await self.clients.claim();
26    await notifyClientsUpdated();
27  })());
28});
  • এই কোডে, activate ইভেন্ট শেষে notifyClientsUpdated কল করে সব যুক্ত ক্লায়েন্টকে নতুন সংস্করণ প্রস্তুত জানানো হয়। clients.claim() একটি মেথড যা বর্তমানে খোলা পেজগুলি (ক্লায়েন্ট) নতুন অ্যাক্টিভেট হওয়া Service Worker-এর নিয়ন্ত্রণে সাথে সাথে নিয়ে আসে। সাধারণত, একটি Service Worker পরবর্তী লোডেই পেজ নিয়ন্ত্রণ শুরু করে, তবে clients.claim() ব্যবহার করলে আপনি সাথে সাথে রিলোড ছাড়াই পেজ নিয়ন্ত্রণে আনতে পারেন।

ক্লায়েন্টে আপডেট UI দেখান, এবং ব্যবহারকারীর একশনে রিলোড করুন

1// in app startup
2navigator.serviceWorker.addEventListener('message', (e) => {
3  if (e.data?.type === 'SW_UPDATED') {
4    // Show a non-intrusive toast or banner: "New version available"
5    // When user clicks "Reload", call:
6    window.location.reload();
7  }
8});
  • ক্লায়েন্ট message ইভেন্টে SW_UPDATED পেয়ে UI-তে আপডেট নোটিফিকেশন দেখায়। ব্যবহারকারী যখন রিলোড করতে বেছে নেন, তখন window.location.reload() সম্পন্ন হয় এবং পৃষ্ঠার আগের HTML, CSS ও অন্যান্য রিসোর্স আপডেট হয়ে সর্বশেষ সংস্করণে রূপান্তরিত হয়। এটি নিশ্চিত করে যে ক্যাশ এবং clients.claim() দিয়ে নিয়ন্ত্রণ নেওয়া Service Worker-এর প্রতিফলন পুরো পেজে ঠিকভাবে হয়।

অফলাইন বিকল্প

গুরুত্বপূর্ণ ন্যাভিগেশনের জন্য /offline.html প্রস্তুত রাখুন, এবং ছবি বা ফন্ট ছাড়াও অর্থবহ সর্বনিম্ন UI দিন। API কল ব্যর্থ হলে সম্ভব হলে শেষ ক্যাশড অবস্থা দেখান এবং UX উন্নত করতে ব্যাকগ্রাউন্ডে নতুন করে আনার চেষ্টা করুন।

বাস্তবায়ন উদাহরণ

 1// sw.ts
 2const CACHE_NAME = 'app-cache-v1';
 3
 4// Cache offline.html during install
 5self.addEventListener('install', (event) => {
 6  event.waitUntil((async () => {
 7    const cache = await caches.open(CACHE_NAME);
 8    await cache.addAll(['/offline.html']);
 9  })());
10});
11
12// Handle fetch requests
13self.addEventListener('fetch', (event) => {
14  const request = event.request;
15
16  // Navigation requests (e.g., page transitions)
17  if (request.mode === 'navigate') {
18    event.respondWith((async () => {
19      try {
20        // Try to fetch from the network as usual
21        return await fetch(request);
22      } catch (err) {
23        // On failure, return offline fallback page
24        const cache = await caches.open(CACHE_NAME);
25        return await cache.match('/offline.html') as Response;
26      }
27    })());
28  }
29});
  • install ইভেন্টে /offline.html ক্যাশে রাখুন, যাতে নেটওয়ার্ক না থাকলে অন্তত একটি সহজ পৃষ্ঠা ফেরত দিতে পারেন।
  • fetch ইভেন্টে, আপনি request.mode === 'navigate' দিয়ে নেভিগেশন রিকুয়েস্ট পর্যবেক্ষণ করতে পারেন এবং নির্দিষ্টভাবে পেজ ট্রানজিশন লক্ষ্য করতে পারেন।
  • নেটওয়ার্ক ব্যর্থ হলে /offline.html দেখান, ताकि অফলাইনেও প্রদর্শিত হয়।

ক্লায়েন্ট এবং Service Worker-এর মধ্যে মেসেজিং

Service Worker পেজ লাইফসাইকেল থেকে স্বাধীনভাবে কাজ করে বলে, দ্বিমুখী মেসেজিং অবস্থা জানাতে ও কমান্ড এক্সিকিউট করতে গুরুত্বপূর্ণ। মেসেজের জন্য টাইপ নির্দিষ্ট করা ভুল মেসেজ পাঠানো এড়াতে, কোড কমপ্লিশনের সুবিধা দিতে এবং আপনার ইমপ্লিমেন্টেশনে আরও দৃঢ়তা আনতে সাহায্য করে।

কোড উদাহরণ

  1. মেসেজ টাইপের সংজ্ঞা
1type SwToClient =
2  | { type: 'SW_READY' }
3  | { type: 'SW_UPDATED' }
4  | { type: 'CACHE_CLEARED' }
5  | { type: 'PING'; ts: number };
6
7type ClientToSw =
8  | { type: 'CLEAR_CACHE' }
9  | { type: 'PING'; ts: number };
  • SwToClient হল সেই মেসেজ টাইপ যা সার্ভিস ওয়ার্কার থেকে ক্লায়েন্টে পাঠানো হয়।
  • ClientToSw হল সেই মেসেজ টাইপ যা ক্লায়েন্ট থেকে সার্ভিস ওয়ার্কারে পাঠানো হয়।
  • এতে দ্বিমুখী যোগাযোগের মাধ্যমে কোন কোন ধরনের ইভেন্ট বিনিময় করা যায় তা স্পষ্টভাবে নির্ধারণ করা যায়।
  1. সার্ভিস ওয়ার্কার পাশে প্রসেসিং
 1self.addEventListener('message', (event) => {
 2  const data = event.data as ClientToSw;
 3  if (data?.type === 'CLEAR_CACHE') {
 4    event.waitUntil((async () => {
 5      const keys = await caches.keys();
 6      await Promise.all(keys.map((k) => caches.delete(k)));
 7      await broadcast({ type: 'CACHE_CLEARED' });
 8    })());
 9  } else if (data?.type === 'PING') {
10    event.source?.postMessage({ type: 'PING', ts: data.ts } as SwToClient);
11  }
12});
  • সার্ভিস ওয়ার্কার ক্লায়েন্ট থেকে মেসেজ পেয়ে টাইপ অনুযায়ী প্রসেসিং করে।
  • CLEAR_CACHE পেলে এটি ক্যাশ ডিলিট করে এবং সব ক্লায়েন্টকে CACHE_CLEARED পাঠায়।
  • PING পেলে এটি টাইমস্ট্যাম্পসহ একটি PING মেসেজ দ্বারা মূল ক্লায়েন্টকে উত্তর দেয়।
  1. সার্ভিস ওয়ার্কার থেকে সব ক্লায়েন্টকে জানানো
1async function broadcast(msg: SwToClient) {
2  const clients = await self.clients.matchAll({ includeUncontrolled: true });
3  for (const c of clients) c.postMessage(msg);
4}
  • clients.matchAll ব্যবহার করে সব উইন্ডো ট্যাব নিন।
  • সবগুলোতে postMessage পাঠিয়ে একাধিক ক্লায়েন্টে বার্তা সম্প্রচার করতে পারেন।
  • এটি আপডেট নোটিফিকেশন (SW_UPDATED প্রভৃতি) ও এরর নোটিফিকেশনে ব্যবহার করা যেতে পারে।
  1. ক্লায়েন্ট পাশে প্রসেসিং
1navigator.serviceWorker.controller?.postMessage({
2  type: 'PING',
3  ts: Date.now()
4} as ClientToSw);
  • ক্লায়েন্ট থেকে PING পাঠিয়ে এবং Service Worker থেকে রেসপন্স পেয়ে আপনি যাচাই করতে পারেন যে দ্বিমুখী যোগাযোগ ঠিকঠাক কাজ করছে কি না। এতে সংযোগের অবস্থা ও মেসেজ হ্যান্ডলিং পরীক্ষার কাজ সহজ হয়ে যায়।
 1navigator.serviceWorker.addEventListener('message', (e) => {
 2  const msg = e.data as SwToClient;
 3  switch (msg.type) {
 4    case 'SW_READY':
 5      console.log('Service Worker is ready');
 6      // Example: hide loading spinner or enable offline UI
 7      break;
 8    case 'SW_UPDATED':
 9      console.log('A new version of the Service Worker is available');
10      // Example: show update notification or reload prompt
11      const shouldReload = confirm('A new version is available. Reload now?');
12      if (shouldReload) {
13        window.location.reload();
14      }
15      break;
16    case 'CACHE_CLEARED':
17      console.log('Cache cleared');
18      // Example: show confirmation message to user
19      alert('Cache has been successfully cleared.');
20      break;
21    case 'PING':
22      console.log(`Received PING response, ts=${msg.ts}`);
23      break;
24  }
25});
  • {^ i18n_speak クライアント側では Service Worker から送信されるメッセージを受信し、種類に応じて処理を分岐します。SW_READY は初期化完了、SW_UPDATED は新バージョン検出、CACHE_CLEARED はキャッシュ削除完了、PING は通信確認を示します。各メッセージに応じて、UI の更新やリロード、通知表示などを行います。^}

টাইপড মেসেজিং-এর সুবিধা

  • টাইপ করা মেসেজ ব্যবহারে কোন কোন মেসেজ পাঠানো-গ্রহণ করা যাবে তা স্পষ্ট হয়, এবং অটো-কমপ্লিশন ও টাইপ চেকিংয়ে নিরাপত্তা বাড়ে।
  • postMessage ব্যবহারে এক-এক যোগাযোগ আর broadcast ব্যবহারে এক-একাধিক যোগাযোগ হয়।
  • আপনি সহজেই আপডেট নোটিফিকেশন (SW_UPDATED), ক্যাশ ম্যানেজমেন্ট (CACHE_CLEARED), ও হেলথ চেক (PING)-এর মতো প্রয়োজনীয় ফিচার ইমপ্লিমেন্ট করতে পারেন।

সারসংক্ষেপ

  • TypeScript ব্যবহারে সার্ভিস ওয়ার্কার API কল ও মেসেজিংয়ে টাইপ সেফটি যুক্ত হয়, যার ফলে উন্নয়ন দক্ষতা ও রক্ষণাবেক্ষণযোগ্যতা অনেক বাড়ে।
  • install, activate, ও fetch লাইফসাইকেল ইভেন্ট বুঝে এবং প্রতিটি পরিস্থিতিতে যথাযথ ক্যাশিং কৌশল (যেমন cache-first বা network-first) নির্বাচন করলে ব্যবহারকারীর অভিজ্ঞতা ভালো হয়।
  • অপারেশনের জন্য ক্যাশ ভার্সন ব্যবস্থাপনা ও আপডেট ফ্লো (updatefound, waiting, SKIP_WAITING ইত্যাদি) বোঝা অত্যন্ত জরুরি।
  • ক্লায়েন্ট-Service Worker যোগাযোগের জন্য টাইপড মেসেজিং গ্রহণ করে, আপনি ভুল ইমপ্লিমেন্টেশন প্রতিরোধ করতে এবং দীর্ঘমেয়াদে সহজে সম্প্রসারণ ও রক্ষণাবেক্ষণযোগ্য একটি ব্যবস্থা গড়ে তুলতে পারেন।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video