Skip to content

Commit

Permalink
refactor(service-worker): review and enhance
Browse files Browse the repository at this point in the history
Co-authored-by: arashagp <arash.qardashpoor@gmail.com>
  • Loading branch information
njfamirm and arashagp committed Dec 17, 2024
1 parent fa1aad9 commit 466ca5b
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 91 deletions.
31 changes: 30 additions & 1 deletion packages/service-worker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Overview

`@nexim/service-worker` provides utility functions to enhance the usage of service workers in your web applications. It includes robust solutions for registering and managing service workers, with built-in logging and event signaling capabilities.
Utilities to simplify the usage of service workers in your web applications.

## Installation

Expand All @@ -20,3 +20,32 @@ npm install @nexim/service-worker
# Or using yarn
yarn add @nexim/service-worker
```

## Api

### registerServiceWorker

Register the service worker and handle updates.

```ts
import {registerServiceWorker} from '@nexim/service-worker';

const serviceWorkerPath = '/service-worker.js';
registerServiceWorker(serviceWorkerPath);
```

### serviceWorkerSignal

Signal for service worker events.

```ts
import {serviceWorkerSignal} from '@nexim/service-worker';

serviceWorkerSignal.subscribe(({event}) => {
console.log('Service worker event:', event);
});
```

### Type ServiceWorkerEvent

The events that can be emitted by the service worker.
3 changes: 1 addition & 2 deletions packages/service-worker/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@nexim/service-worker",
"version": "0.0.0",
"description": "Utility functions to enhance Alpine.js usage with backup support.",
"description": "Utilities to simplify the usage of service workers in your web applications.",
"keywords": [
"worker",
"service-worker",
Expand Down Expand Up @@ -64,7 +64,6 @@
"@alwatr/nano-build": "^5.0.0",
"@alwatr/type-helper": "^5.0.0",
"@nexim/typescript-config": "workspace:^",
"@types/alpinejs": "^3.13.11",
"ava": "^6.2.0",
"typescript": "^5.6.3"
},
Expand Down
3 changes: 0 additions & 3 deletions packages/service-worker/src/lib/logger.ts

This file was deleted.

83 changes: 0 additions & 83 deletions packages/service-worker/src/lib/service-worker.ts

This file was deleted.

103 changes: 102 additions & 1 deletion packages/service-worker/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,106 @@
import {AlwatrSignal} from '@alwatr/flux';
import {createLogger} from '@alwatr/logger';
import {packageTracer} from '@alwatr/package-tracer';

/**
* The events that can be emitted by the service worker.
*/
export type ServiceWorkerEvent =
| 'service_worker_registered'
| 'service_worker_register_failed'
| 'service_worker_first_install'
| 'service_worker_updated'
| 'service_worker_installed'
| 'service_worker_update_found';

__dev_mode__: packageTracer.add(__package_name__, __package_version__);

export * from './lib/service-worker.js';
const logger = /* @__PURE__ */ createLogger(__package_name__);

/**
* Signal for service worker events.
*
* @example
* import {serviceWorkerSignal} from '@nexim/service-worker';
*
* serviceWorkerSignal.subscribe(({event}) => {
* console.log('Service worker event:', event);
* });
*/
export const serviceWorkerSignal = /* @__PURE__ */ new AlwatrSignal<{event: ServiceWorkerEvent}>({
name: 'serviceWorker',
});

/**
* Register the service worker and handle updates.
*
* @param serviceWorkerPath The path to the service worker.
*
* @example
* import {registerServiceWorker} from '@nexim/service-worker';
*
* const serviceWorkerPath = '/service-worker.js';
* registerServiceWorker(serviceWorkerPath);
*/
export async function registerServiceWorker(serviceWorkerPath: string): Promise<void> {
logger.logMethodArgs?.('registerServiceWorker', {serviceWorkerPath});

try {
const swRegistration = await navigator.serviceWorker.register(serviceWorkerPath);
serviceWorkerSignal.notify({event: 'service_worker_registered'});
swRegistration.addEventListener('updatefound', () => serviceWorkerUpdateFoundHandler(swRegistration.installing));
logger.logOther?.('Service worker registered.');
}
catch (error) {
logger.error('registerServiceWorker', 'registration_failed ', {error});
serviceWorkerSignal.notify({event: 'service_worker_register_failed'});
}
}

/**
* Handle the 'updatefound' event
*
* @param serviceWorker The service worker
*/
function serviceWorkerUpdateFoundHandler(serviceWorker: ServiceWorker | null): void {
if (serviceWorker == null) return;
logger.logMethod?.('swUpdateFound');

// Only notify update found if there's an existing controller
if (navigator.serviceWorker.controller) {
serviceWorkerSignal.notify({event: 'service_worker_update_found'});
}
else {
serviceWorkerSignal.notify({event: 'service_worker_first_install'});
}

serviceWorker.addEventListener('statechange', () => serviceWorkerStateChangeHandler(serviceWorker));
}

/**
* Handle the 'statechange' event.
*
* If the service worker state is 'installed' then it is either a new install or an update.
* If the service worker state is 'redundant' then the service worker is redundant.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/state
*
* @param serviceWorker The service worker.
*/
function serviceWorkerStateChangeHandler(serviceWorker: ServiceWorker): void {
logger.logMethodArgs?.('serviceWorkerStateChangeHandler', {state: serviceWorker.state});

if (serviceWorker.state === 'installed') {
// if old controller available then its update else its new install
if (navigator.serviceWorker.controller) {
serviceWorkerSignal.notify({event: 'service_worker_updated'});
}
else {
serviceWorkerSignal.notify({event: 'service_worker_installed'});
}
}
else if (serviceWorker.state === 'redundant') {
logger.accident('serviceWorkerStateChangeHandler', 'sw_redundant', 'Service worker redundant');
serviceWorkerSignal.notify({event: 'service_worker_installed'});
}
}
10 changes: 9 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"extends": "@nexim/typescript-config/tsconfig.json",
"compilerOptions": {
"noEmit": true,
"types": ["node"]
"types": [
"node"
]
},
"files": [],
"exclude": [],
Expand All @@ -15,6 +17,12 @@
},
{
"path": "./packages/alpine"
},
{
"path": "./packages/service-worker"
},
{
"path": "./packages/snackbar"
}
]
}

0 comments on commit 466ca5b

Please sign in to comment.