-
Notifications
You must be signed in to change notification settings - Fork 115
/
ServiceWorkerHelper.ts
executable file
·103 lines (96 loc) · 3.72 KB
/
ServiceWorkerHelper.ts
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
import Log from '../libraries/Log';
import Path from '../models/Path';
import { InvalidStateError, InvalidStateReason } from '../errors/InvalidStateError';
import { OneSignalUtils } from '../utils/OneSignalUtils';
export default class ServiceWorkerHelper {
// Gets details on the service-worker (if any) that controls the current page
public static async getRegistration(): Promise<ServiceWorkerRegistration | null | undefined> {
try {
// location.href is used for <base> tag compatibility when it is set to a different origin
return await navigator.serviceWorker.getRegistration(location.href);
} catch (e) {
// This could be null in an HTTP context or error if the user doesn't accept cookies
Log.warn("[Service Worker Status] Error Checking service worker registration", location.href, e);
return null;
}
}
public static getServiceWorkerHref(
workerState: ServiceWorkerActiveState,
config: ServiceWorkerManagerConfig): string {
let workerFullPath = "";
// Determine which worker to install
if (workerState === ServiceWorkerActiveState.WorkerA)
workerFullPath = config.workerBPath.getFullPath();
else if (workerState === ServiceWorkerActiveState.WorkerB ||
workerState === ServiceWorkerActiveState.ThirdParty ||
workerState === ServiceWorkerActiveState.None)
workerFullPath = config.workerAPath.getFullPath();
else if (workerState === ServiceWorkerActiveState.Bypassed) {
/*
if the page is hard refreshed bypassing the cache, no service worker
will control the page.
It doesn't matter if we try to reinstall an existing worker; still no
service worker will control the page after installation.
*/
throw new InvalidStateError(InvalidStateReason.UnsupportedEnvironment);
}
return new URL(workerFullPath, OneSignalUtils.getBaseUrl()).href;
}
}
export enum ServiceWorkerActiveState {
/**
* OneSignalSDKWorker.js, or the equivalent custom file name, is active.
*/
WorkerA = 'Worker A (Main)',
/**
* OneSignalSDKUpdaterWorker.js, or the equivalent custom file name, is
* active.
*
* We no longer need to use this filename. We can update Worker A by appending
* a random query parameter to A.
*/
WorkerB = 'Worker B (Updater)',
/**
* A service worker is active, but it is neither OneSignalSDKWorker.js nor
* OneSignalSDKUpdaterWorker.js (or the equivalent custom file names as
* provided by user config).
*/
ThirdParty = '3rd Party',
/**
* A service worker is currently installing and we can't determine its final state yet. Wait until
* the service worker is finished installing by checking for a controllerchange property..
*/
Installing = 'Installing',
/**
* No service worker is installed.
*/
None = 'None',
/**
* A service worker is active but not controlling the page. This can occur if
* the page is hard-refreshed bypassing the cache, which also bypasses service
* workers.
*/
Bypassed = 'Bypassed',
/**
* Service workers are not supported in this environment. This status is used
* on HTTP pages where it isn't possible to know whether a service worker is
* installed or not or in any of the other states.
*/
Indeterminate = 'Indeterminate'
}
export interface ServiceWorkerManagerConfig {
/**
* The path and filename of the "main" worker (e.g. '/OneSignalSDKWorker.js');
*/
workerAPath: Path;
/**
* The path and filename to the "alternate" worker, used to update an existing
* service worker. (e.g. '/OneSignalSDKUpdaterWorer.js')
*/
workerBPath: Path;
/**
* Describes how much of the origin the service worker controls.
* This is currently always "/".
*/
registrationOptions: { scope: string };
}