@openmrs/esm-app-shell 5.3.3-pre.1231 → 5.3.3-pre.1247

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.turbo/turbo-build.log +98 -98
  2. package/dist/9c276181fc6599f8.js.map +1 -0
  3. package/dist/d81faa62d5818f52.js.map +1 -0
  4. package/dist/index.html +1 -1
  5. package/dist/{openmrs.954886865de0b85a.js → openmrs.6213811dbd70a295.js} +2 -2
  6. package/dist/openmrs.6213811dbd70a295.js.map +1 -0
  7. package/dist/openmrs.c9c4fe7ea57e9920.css.map +1 -1
  8. package/dist/service-worker.js +1 -1
  9. package/dist/service-worker.js.map +1 -1
  10. package/lib/{3975decbab0164f3.js → 9b51c0739002f900.js} +1 -1
  11. package/lib/{f29978db163aaa3d.js → c074b9133e91fad3.js} +5 -5
  12. package/lib/esm-devtools-app/68.js.map +1 -1
  13. package/lib/esm-devtools-app/889.js +1 -1
  14. package/lib/esm-devtools-app/988.js.map +1 -1
  15. package/lib/esm-devtools-app/main.js +1 -1
  16. package/lib/esm-devtools-app/main.js.map +1 -1
  17. package/lib/esm-devtools-app/openmrs-esm-devtools-app.js +1 -1
  18. package/lib/esm-devtools-app/openmrs-esm-devtools-app.js.buildmanifest.json +5 -5
  19. package/lib/esm-devtools-app/routes.json +1 -1
  20. package/lib/esm-implementer-tools-app/426.js.map +1 -1
  21. package/lib/esm-implementer-tools-app/560.js +1 -1
  22. package/lib/esm-implementer-tools-app/560.js.map +1 -1
  23. package/lib/esm-implementer-tools-app/587.js.map +1 -1
  24. package/lib/esm-implementer-tools-app/727.js +1 -1
  25. package/lib/esm-implementer-tools-app/727.js.map +1 -1
  26. package/lib/esm-implementer-tools-app/main.js +1 -1
  27. package/lib/esm-implementer-tools-app/main.js.map +1 -1
  28. package/lib/esm-implementer-tools-app/openmrs-esm-implementer-tools-app.js +1 -1
  29. package/lib/esm-implementer-tools-app/openmrs-esm-implementer-tools-app.js.buildmanifest.json +13 -13
  30. package/lib/esm-implementer-tools-app/routes.json +1 -1
  31. package/lib/esm-login-app/370.js +1 -1
  32. package/lib/esm-login-app/370.js.map +1 -1
  33. package/lib/esm-login-app/main.js +1 -1
  34. package/lib/esm-login-app/main.js.map +1 -1
  35. package/lib/esm-login-app/openmrs-esm-login-app.js +1 -1
  36. package/lib/esm-login-app/openmrs-esm-login-app.js.buildmanifest.json +8 -8
  37. package/lib/esm-login-app/routes.json +1 -1
  38. package/lib/esm-offline-tools-app/102.js +1 -1
  39. package/lib/esm-offline-tools-app/102.js.map +1 -1
  40. package/lib/esm-offline-tools-app/main.js +1 -1
  41. package/lib/esm-offline-tools-app/main.js.map +1 -1
  42. package/lib/esm-offline-tools-app/openmrs-esm-offline-tools-app.js +1 -1
  43. package/lib/esm-offline-tools-app/openmrs-esm-offline-tools-app.js.buildmanifest.json +8 -8
  44. package/lib/esm-offline-tools-app/routes.json +1 -1
  45. package/lib/esm-primary-navigation-app/735.js +1 -1
  46. package/lib/esm-primary-navigation-app/735.js.map +1 -1
  47. package/lib/esm-primary-navigation-app/main.js +1 -1
  48. package/lib/esm-primary-navigation-app/main.js.map +1 -1
  49. package/lib/esm-primary-navigation-app/openmrs-esm-primary-navigation-app.js +1 -1
  50. package/lib/esm-primary-navigation-app/openmrs-esm-primary-navigation-app.js.buildmanifest.json +8 -8
  51. package/lib/esm-primary-navigation-app/routes.json +1 -1
  52. package/lib/index.html +1 -1
  53. package/lib/openmrs.js +135 -135
  54. package/lib/service-worker.js +9 -9
  55. package/package.json +3 -3
  56. package/src/apps.ts +32 -72
  57. package/src/declarations.d.ts +3 -6
  58. package/src/helpers.ts +2 -4
  59. package/src/index.ts +13 -15
  60. package/src/locale.ts +24 -34
  61. package/src/run.ts +53 -87
  62. package/src/service-worker/caching.ts +14 -22
  63. package/src/service-worker/constants.ts +8 -13
  64. package/src/service-worker/http-header-utils.ts +5 -15
  65. package/src/service-worker/import-map-utils.ts +14 -25
  66. package/src/service-worker/index.ts +8 -8
  67. package/src/service-worker/message.ts +9 -15
  68. package/src/service-worker/routing.ts +23 -50
  69. package/src/service-worker/storage.ts +5 -5
  70. package/src/service-worker/types.ts +1 -1
  71. package/src/ui/breadcrumbs.tsx +14 -29
  72. package/src/ui/index.ts +6 -6
  73. package/tools/helpers.js +3 -7
  74. package/webpack.config.js +95 -117
  75. package/dist/966c4dfec919951f.js.map +0 -1
  76. package/dist/fca8d09359d3b887.js.map +0 -1
  77. package/dist/openmrs.954886865de0b85a.js.map +0 -1
  78. /package/dist/{fca8d09359d3b887.js → 9c276181fc6599f8.js} +0 -0
  79. /package/dist/{966c4dfec919951f.js → d81faa62d5818f52.js} +0 -0
  80. /package/dist/{openmrs.954886865de0b85a.js.LICENSE.txt → openmrs.6213811dbd70a295.js.LICENSE.txt} +0 -0
package/src/run.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { start, triggerAppChange } from "single-spa";
1
+ import { start, triggerAppChange } from 'single-spa';
2
2
  import {
3
3
  setupApiModule,
4
4
  renderLoadingSpinner,
@@ -31,19 +31,15 @@ import {
31
31
  OpenmrsRoutes,
32
32
  getCurrentImportMap,
33
33
  importDynamic,
34
- } from "@openmrs/esm-framework/src/internal";
35
- import {
36
- finishRegisteringAllApps,
37
- registerApp,
38
- tryRegisterExtension,
39
- } from "./apps";
40
- import { setupI18n } from "./locale";
41
- import { appName, getCoreExtensions } from "./ui";
34
+ } from '@openmrs/esm-framework/src/internal';
35
+ import { finishRegisteringAllApps, registerApp, tryRegisterExtension } from './apps';
36
+ import { setupI18n } from './locale';
37
+ import { appName, getCoreExtensions } from './ui';
42
38
 
43
39
  // @internal
44
40
  // used to track when the window.installedModules global is finalised
45
41
  // so we can pre-load all modules
46
- const REGISTRATION_PROMISES = Symbol("openmrs_registration_promises");
42
+ const REGISTRATION_PROMISES = Symbol('openmrs_registration_promises');
47
43
 
48
44
  /**
49
45
  * Sets up the frontend modules (apps). Uses the defined export
@@ -52,9 +48,7 @@ const REGISTRATION_PROMISES = Symbol("openmrs_registration_promises");
52
48
  * as the registry of all apps in the application.
53
49
  */
54
50
  async function setupApps() {
55
- const scriptTags = document.querySelectorAll<HTMLScriptElement>(
56
- "script[type='openmrs-routes']"
57
- );
51
+ const scriptTags = document.querySelectorAll<HTMLScriptElement>("script[type='openmrs-routes']");
58
52
 
59
53
  const promises: Array<Promise<OpenmrsRoutes>> = [];
60
54
  for (let i = 0; i < scriptTags.length; i++) {
@@ -68,33 +62,26 @@ async function setupApps() {
68
62
  routes = (await openmrsFetch<OpenmrsRoutes>(scriptTag.src)).data;
69
63
  }
70
64
  } catch (e) {
71
- console.error(
72
- `Caught error while loading routes from ${
73
- scriptTag.src ?? "JSON script tag content"
74
- }`,
75
- e
76
- );
65
+ console.error(`Caught error while loading routes from ${scriptTag.src ?? 'JSON script tag content'}`, e);
77
66
 
78
67
  return {};
79
68
  }
80
69
 
81
70
  return Promise.resolve(routes ?? {});
82
- })(scriptTags.item(i))
71
+ })(scriptTags.item(i)),
83
72
  );
84
73
  }
85
74
 
86
75
  const routes = (await Promise.all(promises)).reduce(
87
76
  (accumulatedRoutes, routes) => ({ ...accumulatedRoutes, ...routes }),
88
- {}
77
+ {},
89
78
  );
90
79
 
91
80
  const modules: typeof window.installedModules = [];
92
- const registrationPromises = Object.entries(routes).map(
93
- async ([module, routes]) => {
94
- modules.push([module, routes]);
95
- registerApp(module, routes);
96
- }
97
- );
81
+ const registrationPromises = Object.entries(routes).map(async ([module, routes]) => {
82
+ modules.push([module, routes]);
83
+ registerApp(module, routes);
84
+ });
98
85
 
99
86
  window[REGISTRATION_PROMISES] = Promise.all(registrationPromises);
100
87
  window.installedModules = modules;
@@ -120,9 +107,9 @@ function connectivityChanged() {
120
107
  dispatchConnectivityChanged(online);
121
108
  showToast({
122
109
  critical: true,
123
- description: `Connection: ${online ? "online" : "offline"}`,
124
- title: "App",
125
- kind: online ? "success" : "warning",
110
+ description: `Connection: ${online ? 'online' : 'offline'}`,
111
+ title: 'App',
112
+ kind: online ? 'success' : 'warning',
126
113
  });
127
114
  }
128
115
 
@@ -130,18 +117,15 @@ function connectivityChanged() {
130
117
  * Runs the shell by importing the translations and starting single SPA.
131
118
  */
132
119
  function runShell() {
133
- window.addEventListener("offline", connectivityChanged);
134
- window.addEventListener("online", connectivityChanged);
120
+ window.addEventListener('offline', connectivityChanged);
121
+ window.addEventListener('online', connectivityChanged);
135
122
  return setupI18n()
136
123
  .catch((err) => console.error(`Failed to initialize translations`, err))
137
124
  .then(() => start());
138
125
  }
139
126
 
140
127
  async function preloadScripts() {
141
- const [, importMap] = await Promise.all([
142
- window[REGISTRATION_PROMISES],
143
- getCurrentImportMap(),
144
- ]);
128
+ const [, importMap] = await Promise.all([window[REGISTRATION_PROMISES], getCurrentImportMap()]);
145
129
 
146
130
  window.installedModules.map(async ([module]) => {
147
131
  // we simply swallow the error here since this is only a preload
@@ -155,28 +139,25 @@ function handleInitFailure(e: Error) {
155
139
  }
156
140
 
157
141
  function renderFatalErrorPage(e?: Error) {
158
- const template = document.querySelector<HTMLTemplateElement>("#app-error");
142
+ const template = document.querySelector<HTMLTemplateElement>('#app-error');
159
143
 
160
144
  if (template) {
161
145
  const fragment = template.content.cloneNode(true) as DocumentFragment;
162
146
  const messageContainer = fragment.querySelector('[data-var="message"]');
163
147
 
164
148
  if (messageContainer) {
165
- messageContainer.textContent =
166
- e?.message || "No additional information available.";
149
+ messageContainer.textContent = e?.message || 'No additional information available.';
167
150
  }
168
151
 
169
152
  if (
170
- localStorage.getItem("openmrs:devtools") &&
171
- Object.keys(localStorage).some((k) =>
172
- k.startsWith("import-map-override:")
173
- )
153
+ localStorage.getItem('openmrs:devtools') &&
154
+ Object.keys(localStorage).some((k) => k.startsWith('import-map-override:'))
174
155
  ) {
175
- const appErrorActionButtons = fragment?.querySelector("#buttons");
156
+ const appErrorActionButtons = fragment?.querySelector('#buttons');
176
157
  if (appErrorActionButtons) {
177
- const clearDevOverridesButton = document.createElement("button");
178
- clearDevOverridesButton.className = "cds--btn";
179
- clearDevOverridesButton.innerHTML = "Clear dev overrides";
158
+ const clearDevOverridesButton = document.createElement('button');
159
+ clearDevOverridesButton.className = 'cds--btn';
160
+ clearDevOverridesButton.innerHTML = 'Clear dev overrides';
180
161
  clearDevOverridesButton.onclick = clearDevOverrides;
181
162
  appErrorActionButtons.appendChild(clearDevOverridesButton);
182
163
  }
@@ -189,10 +170,8 @@ function renderFatalErrorPage(e?: Error) {
189
170
  function clearDevOverrides() {
190
171
  for (const key of Object.keys(localStorage)) {
191
172
  if (
192
- key.startsWith("import-map-override:") &&
193
- !["import-map-override:react", "import-map-override:react-dom"].includes(
194
- key
195
- )
173
+ key.startsWith('import-map-override:') &&
174
+ !['import-map-override:react', 'import-map-override:react-dom'].includes(key)
196
175
  ) {
197
176
  localStorage.removeItem(key);
198
177
  }
@@ -217,34 +196,30 @@ function createConfigLoader(configUrls: Array<string>) {
217
196
  value: {},
218
197
  };
219
198
  });
220
- })
199
+ }),
221
200
  );
222
201
  return () => loadingConfigs.then(loadConfigs);
223
202
  }
224
203
 
225
204
  function showNotifications() {
226
- renderInlineNotifications(
227
- document.querySelector(".omrs-inline-notifications-container")
228
- );
205
+ renderInlineNotifications(document.querySelector('.omrs-inline-notifications-container'));
229
206
  return;
230
207
  }
231
208
 
232
209
  function showActionableNotifications() {
233
- renderActionableNotifications(
234
- document.querySelector(".omrs-actionable-notifications-container")
235
- );
210
+ renderActionableNotifications(document.querySelector('.omrs-actionable-notifications-container'));
236
211
  }
237
212
 
238
213
  function showToasts() {
239
- renderToasts(document.querySelector(".omrs-toasts-container"));
214
+ renderToasts(document.querySelector('.omrs-toasts-container'));
240
215
  }
241
216
 
242
217
  function showSnackbars() {
243
- renderSnackbars(document.querySelector(".omrs-snackbars-container"));
218
+ renderSnackbars(document.querySelector('.omrs-snackbars-container'));
244
219
  }
245
220
 
246
221
  function showModals() {
247
- renderModals(document.querySelector(".omrs-modals-container"));
222
+ renderModals(document.querySelector('.omrs-modals-container'));
248
223
  }
249
224
 
250
225
  function showLoadingSpinner() {
@@ -263,16 +238,14 @@ function registerCoreExtensions() {
263
238
 
264
239
  async function setupOffline() {
265
240
  try {
266
- await registerOmrsServiceWorker(
267
- `${window.getOpenmrsSpaBase()}service-worker.js`
268
- );
241
+ await registerOmrsServiceWorker(`${window.getOpenmrsSpaBase()}service-worker.js`);
269
242
  await activateOfflineCapability();
270
243
  setupOfflineStaticDependencyPrecaching();
271
244
  } catch (error) {
272
- console.error("Error while setting up offline mode.", error);
245
+ console.error('Error while setting up offline mode.', error);
273
246
  showNotification({
274
- kind: "error",
275
- title: "Offline Setup Error",
247
+ kind: 'error',
248
+ title: 'Offline Setup Error',
276
249
  description: error.message,
277
250
  });
278
251
  }
@@ -283,9 +256,7 @@ function setupOfflineStaticDependencyPrecaching() {
283
256
  let lastPrecache: Date | null = null;
284
257
 
285
258
  subscribeOnlineAndLoginChange((online, hasLoggedInUser) => {
286
- const hasExceededPrecacheDelay =
287
- !lastPrecache ||
288
- new Date().getTime() - lastPrecache.getTime() > precacheDelay;
259
+ const hasExceededPrecacheDelay = !lastPrecache || new Date().getTime() - lastPrecache.getTime() > precacheDelay;
289
260
 
290
261
  if (hasLoggedInUser && online && hasExceededPrecacheDelay) {
291
262
  lastPrecache = new Date();
@@ -294,9 +265,7 @@ function setupOfflineStaticDependencyPrecaching() {
294
265
  });
295
266
  }
296
267
 
297
- function subscribeOnlineAndLoginChange(
298
- cb: (online: boolean, hasLoggedInUser: boolean) => void
299
- ) {
268
+ function subscribeOnlineAndLoginChange(cb: (online: boolean, hasLoggedInUser: boolean) => void) {
300
269
  let isOnline = false;
301
270
  let hasLoggedInUser = false;
302
271
 
@@ -316,40 +285,37 @@ async function precacheGlobalStaticDependencies() {
316
285
 
317
286
  // By default, cache the session endpoint.
318
287
  // This ensures that a lot of user/session related functions also work offline.
319
- const sessionPathUrl = new URL(
320
- `${window.openmrsBase}/ws/rest/v1/session`,
321
- window.location.origin
322
- ).href;
288
+ const sessionPathUrl = new URL(`${window.openmrsBase}/ws/rest/v1/session`, window.location.origin).href;
323
289
 
324
290
  await messageOmrsServiceWorker({
325
- type: "registerDynamicRoute",
291
+ type: 'registerDynamicRoute',
326
292
  url: sessionPathUrl,
327
- strategy: "network-first",
293
+ strategy: 'network-first',
328
294
  });
329
295
 
330
- await openmrsFetch("/ws/rest/v1/session").catch((e) =>
296
+ await openmrsFetch('/ws/rest/v1/session').catch((e) =>
331
297
  console.warn(
332
- "Failed to precache the user session data from the app shell. MFs depending on this data may run into problems while offline.",
333
- e
334
- )
298
+ 'Failed to precache the user session data from the app shell. MFs depending on this data may run into problems while offline.',
299
+ e,
300
+ ),
335
301
  );
336
302
  }
337
303
 
338
304
  async function precacheImportMap() {
339
305
  const importMap = await window.importMapOverrides.getCurrentPageMap();
340
306
  await messageOmrsServiceWorker({
341
- type: "onImportMapChanged",
307
+ type: 'onImportMapChanged',
342
308
  importMap,
343
309
  });
344
310
  }
345
311
 
346
312
  function setupOfflineCssClasses() {
347
313
  subscribeConnectivity(({ online }) => {
348
- const body = document.querySelector("body")!;
314
+ const body = document.querySelector('body')!;
349
315
  if (online) {
350
- body.classList.remove("omrs-offline");
316
+ body.classList.remove('omrs-offline');
351
317
  } else {
352
- body.classList.add("omrs-offline");
318
+ body.classList.add('omrs-offline');
353
319
  }
354
320
  });
355
321
  }
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable no-console */
2
- import type { ImportMap } from "@openmrs/esm-globals";
3
- import { retry } from "@openmrs/esm-utils";
4
- import { absoluteWbManifestUrls, omrsCacheName } from "./constants";
5
- import { fetchUrlsToCacheFromImportMap } from "./import-map-utils";
6
- import { ServiceWorkerDb } from "./storage";
2
+ import type { ImportMap } from '@openmrs/esm-globals';
3
+ import { retry } from '@openmrs/esm-utils';
4
+ import { absoluteWbManifestUrls, omrsCacheName } from './constants';
5
+ import { fetchUrlsToCacheFromImportMap } from './import-map-utils';
6
+ import { ServiceWorkerDb } from './storage';
7
7
 
8
8
  /**
9
9
  * Attempts to resolve cacheable files from the specified import map (files are retrieved via convention)
@@ -43,17 +43,13 @@ export async function addToOmrsCache(urls: Array<string>) {
43
43
  urls.map(async (url) => {
44
44
  try {
45
45
  await retry(() => cache.add(url), {
46
- onError: (e, attempt) =>
47
- console.debug(
48
- `[SW] Failure attempt ${attempt} at caching "${url}". Error: `,
49
- e
50
- ),
46
+ onError: (e, attempt) => console.debug(`[SW] Failure attempt ${attempt} at caching "${url}". Error: `, e),
51
47
  });
52
48
  return { url, success: true };
53
49
  } catch (e) {
54
50
  return { url, success: false };
55
51
  }
56
- })
52
+ }),
57
53
  );
58
54
 
59
55
  const cached = results.filter((r) => r.success);
@@ -62,14 +58,14 @@ export async function addToOmrsCache(urls: Array<string>) {
62
58
  if (cached.length > 0) {
63
59
  console.debug(
64
60
  `[SW] Successfully added ${cached.length} URLs to the OMRS cache. URLs: `,
65
- cached.map((r) => r.url)
61
+ cached.map((r) => r.url),
66
62
  );
67
63
  }
68
64
 
69
65
  if (failedToCache.length > 0) {
70
66
  console.error(
71
67
  `[SW] Failed to cache ${failedToCache.length} URLs. URLs: `,
72
- failedToCache.map((r) => r.url)
68
+ failedToCache.map((r) => r.url),
73
69
  );
74
70
  }
75
71
  }
@@ -77,27 +73,23 @@ export async function addToOmrsCache(urls: Array<string>) {
77
73
  async function invalidateObsoleteCacheEntries(newImportMapUrls: Array<string>) {
78
74
  const cache = await caches.open(omrsCacheName);
79
75
  const cachedUrls = (await cache.keys()).map((x) => x.url);
80
- const dynamicRoutes =
81
- await new ServiceWorkerDb().dynamicRouteRegistrations.toArray();
76
+ const dynamicRoutes = await new ServiceWorkerDb().dynamicRouteRegistrations.toArray();
82
77
 
83
78
  const urlsToInvalidate = cachedUrls.filter(
84
79
  (cachedUrl) =>
85
80
  !absoluteWbManifestUrls.includes(cachedUrl) &&
86
81
  !newImportMapUrls.includes(cachedUrl) &&
87
- !dynamicRoutes.some((route) => new RegExp(route.pattern).test(cachedUrl))
82
+ !dynamicRoutes.some((route) => new RegExp(route.pattern).test(cachedUrl)),
88
83
  );
89
84
 
90
- console.info(
91
- "[SW] Removing the following expired URLs from the cache: ",
92
- urlsToInvalidate
93
- );
85
+ console.info('[SW] Removing the following expired URLs from the cache: ', urlsToInvalidate);
94
86
 
95
87
  // eslint-disable-next-line no-console
96
88
  console.debug(
97
- "[SW] The following URLs were known and not invalidated: ",
89
+ '[SW] The following URLs were known and not invalidated: ',
98
90
  absoluteWbManifestUrls,
99
91
  newImportMapUrls,
100
- dynamicRoutes
92
+ dynamicRoutes,
101
93
  );
102
94
 
103
95
  await Promise.all(urlsToInvalidate.map((url) => cache.delete(url)));
@@ -1,23 +1,18 @@
1
- import uniq from "lodash-es/uniq";
1
+ import uniq from 'lodash-es/uniq';
2
2
 
3
3
  // note that these constants are also defined in @openmrs/esm-offline
4
- export const omrsOfflineResponseBodyHttpHeaderName =
5
- "x-omrs-offline-response-body";
6
- export const omrsOfflineResponseStatusHttpHeaderName =
7
- "x-omrs-offline-response-status";
8
- export const omrsOfflineCachingStrategyHttpHeaderName =
9
- "x-omrs-offline-caching-strategy";
4
+ export const omrsOfflineResponseBodyHttpHeaderName = 'x-omrs-offline-response-body';
5
+ export const omrsOfflineResponseStatusHttpHeaderName = 'x-omrs-offline-response-status';
6
+ export const omrsOfflineCachingStrategyHttpHeaderName = 'x-omrs-offline-caching-strategy';
10
7
 
11
- export const omrsCachePrefix = "omrs";
8
+ export const omrsCachePrefix = 'omrs';
12
9
  export const omrsCacheName = `${omrsCachePrefix}-spa-cache-v1`;
13
10
 
14
11
  export const wbManifest = self.__WB_MANIFEST;
15
- export const indexUrl = prefixWithServiceWorkerLocationIfRelative("index.html");
16
- export const absoluteWbManifestUrls = uniq(
17
- wbManifest.map(({ url }) => prefixWithServiceWorkerLocationIfRelative(url))
18
- );
12
+ export const indexUrl = prefixWithServiceWorkerLocationIfRelative('index.html');
13
+ export const absoluteWbManifestUrls = uniq(wbManifest.map(({ url }) => prefixWithServiceWorkerLocationIfRelative(url)));
19
14
 
20
- export const buildManifestSuffix = ".buildmanifest.json";
15
+ export const buildManifestSuffix = '.buildmanifest.json';
21
16
 
22
17
  function prefixWithServiceWorkerLocationIfRelative(path: string) {
23
18
  return new URL(path, self.location.href).href;
@@ -1,25 +1,15 @@
1
- import type {
2
- OmrsOfflineHttpHeaderNames,
3
- OmrsOfflineHttpHeaders,
4
- } from "@openmrs/esm-offline";
5
- import {
6
- omrsOfflineResponseBodyHttpHeaderName,
7
- omrsOfflineResponseStatusHttpHeaderName,
8
- } from "./constants";
1
+ import type { OmrsOfflineHttpHeaderNames, OmrsOfflineHttpHeaders } from '@openmrs/esm-offline';
2
+ import { omrsOfflineResponseBodyHttpHeaderName, omrsOfflineResponseStatusHttpHeaderName } from './constants';
9
3
 
10
4
  export function parseOmrsOfflineResponseBodyHeader(headers: Headers) {
11
5
  // The ?? undefined here is important as getOmrsHeader returns null by default when the header
12
6
  // is missing. undefined is different than null in this case since we want the body to be missing
13
7
  // if the header is not there (null is not missing).
14
- return (
15
- getOmrsHeader(headers, omrsOfflineResponseBodyHttpHeaderName) ?? undefined
16
- );
8
+ return getOmrsHeader(headers, omrsOfflineResponseBodyHttpHeaderName) ?? undefined;
17
9
  }
18
10
 
19
11
  export function parseOmrsOfflineResponseStatusHeader(headers: Headers) {
20
- const status = +(
21
- getOmrsHeader(headers, omrsOfflineResponseStatusHttpHeaderName) ?? ""
22
- );
12
+ const status = +(getOmrsHeader(headers, omrsOfflineResponseStatusHttpHeaderName) ?? '');
23
13
 
24
14
  // The Response API requires the status to be in the 200-599 range and throws otherwise.
25
15
  return isNaN(status) || status < 200 || status > 599 ? 503 : status;
@@ -27,7 +17,7 @@ export function parseOmrsOfflineResponseStatusHeader(headers: Headers) {
27
17
 
28
18
  export function getOmrsHeader<T extends OmrsOfflineHttpHeaderNames>(
29
19
  headers: Headers,
30
- name: T
20
+ name: T,
31
21
  ): OmrsOfflineHttpHeaders[T] | null {
32
22
  return headers.get(name) as OmrsOfflineHttpHeaders[T];
33
23
  }
@@ -1,25 +1,21 @@
1
- import type { ImportMap } from "@openmrs/esm-globals";
2
- import { buildManifestSuffix } from "./constants";
3
- import { BuildManifest } from "./types";
4
- import flatten from "lodash-es/flatten";
1
+ import type { ImportMap } from '@openmrs/esm-globals';
2
+ import { buildManifestSuffix } from './constants';
3
+ import { BuildManifest } from './types';
4
+ import flatten from 'lodash-es/flatten';
5
5
 
6
6
  /**
7
7
  * Given an import map object, resolves the URLs of all cacheable files defined in the import map.
8
8
  * Resolving relies on a build manifest file existing in the same location as the file referenced
9
9
  * in the import map.
10
10
  */
11
- export async function fetchUrlsToCacheFromImportMap({
12
- imports = {},
13
- }: ImportMap) {
11
+ export async function fetchUrlsToCacheFromImportMap({ imports = {} }: ImportMap) {
14
12
  const importMapUrlAddresses = Object.values(imports);
15
13
  const urlsToCache = await Promise.all(
16
14
  importMapUrlAddresses.map(async (importMapAddress) => {
17
15
  const buildManifestUrl = getBuildManifestUrl(importMapAddress);
18
16
  const buildManifest = await tryFetchBuildManifest(buildManifestUrl);
19
- return buildManifest
20
- ? getUrlsFromBuildManifests(importMapAddress, buildManifest)
21
- : [];
22
- })
17
+ return buildManifest ? getUrlsFromBuildManifests(importMapAddress, buildManifest) : [];
18
+ }),
23
19
  );
24
20
 
25
21
  return flatten(urlsToCache);
@@ -29,26 +25,19 @@ function getBuildManifestUrl(importMapAddress: string) {
29
25
  return importMapAddress + buildManifestSuffix;
30
26
  }
31
27
 
32
- function tryFetchBuildManifest(
33
- buildManifestUrl: string
34
- ): Promise<BuildManifest | null> {
28
+ function tryFetchBuildManifest(buildManifestUrl: string): Promise<BuildManifest | null> {
35
29
  return fetch(buildManifestUrl)
36
30
  .then((res) => res.json())
37
31
  .catch(() => null);
38
32
  }
39
33
 
40
- function getUrlsFromBuildManifests(
41
- importMapAddress: string,
42
- buildManifest: BuildManifest
43
- ) {
34
+ function getUrlsFromBuildManifests(importMapAddress: string, buildManifest: BuildManifest) {
44
35
  // The try here guards against malformed JSON responses.
45
36
  // While we do expect the build manifest to have the correct format, we cannot *rely* on it.
46
37
  // Using a try/catch here seems better to me than doing defensive checks on every field/type in the response.
47
38
  try {
48
39
  const results: Array<string> = [];
49
- const baseUrlForFiles = getUrlOfFileParentDir(
50
- new URL(importMapAddress, self.location.href)
51
- );
40
+ const baseUrlForFiles = getUrlOfFileParentDir(new URL(importMapAddress, self.location.href));
52
41
 
53
42
  for (const chunk of buildManifest.chunks ?? []) {
54
43
  for (const file of chunk.files ?? []) {
@@ -61,7 +50,7 @@ function getUrlsFromBuildManifests(
61
50
  console.error(
62
51
  "[SW] Failed to determine the dependencies of the module with the URL %s. Not precaching any of the module's assets. Error: ",
63
52
  importMapAddress,
64
- e
53
+ e,
65
54
  );
66
55
 
67
56
  return [];
@@ -70,7 +59,7 @@ function getUrlsFromBuildManifests(
70
59
 
71
60
  function getUrlOfFileParentDir(url: URL) {
72
61
  const fullPath = url.origin + url.pathname; // Removes params + hash.
73
- const parts = fullPath.split("/");
74
- parts[parts.length - 1] = "";
75
- return parts.join("/");
62
+ const parts = fullPath.split('/');
63
+ parts[parts.length - 1] = '';
64
+ return parts.join('/');
76
65
  }
@@ -1,8 +1,8 @@
1
- import { setCacheNameDetails } from "workbox-core";
2
- import { handleMessage } from "./message";
3
- import { precacheAppShell } from "./caching";
4
- import { registerAllOmrsRoutes } from "./routing";
5
- import { omrsCachePrefix } from "./constants";
1
+ import { setCacheNameDetails } from 'workbox-core';
2
+ import { handleMessage } from './message';
3
+ import { precacheAppShell } from './caching';
4
+ import { registerAllOmrsRoutes } from './routing';
5
+ import { omrsCachePrefix } from './constants';
6
6
 
7
7
  self.__WB_DISABLE_DEV_LOGS = true;
8
8
 
@@ -11,9 +11,9 @@ setCacheNameDetails({ prefix: omrsCachePrefix });
11
11
 
12
12
  registerAllOmrsRoutes();
13
13
 
14
- self.addEventListener("message", handleMessage);
14
+ self.addEventListener('message', handleMessage);
15
15
 
16
- self.addEventListener("install", (e) => {
16
+ self.addEventListener('install', (e) => {
17
17
  self.skipWaiting();
18
18
 
19
19
  // The app shell files are special in the sense that they can immediately be cached during SW installation.
@@ -22,6 +22,6 @@ self.addEventListener("install", (e) => {
22
22
  e.waitUntil(precacheAppShell());
23
23
  });
24
24
 
25
- self.addEventListener("activate", (e) => {
25
+ self.addEventListener('activate', (e) => {
26
26
  e.waitUntil(self.clients.claim());
27
27
  });
@@ -2,10 +2,10 @@ import type {
2
2
  MessageServiceWorkerResult,
3
3
  OnImportMapChangedMessage,
4
4
  RegisterDynamicRouteMessage,
5
- } from "@openmrs/esm-offline";
6
- import escapeRegExp from "lodash-es/escapeRegExp";
7
- import { cacheImportMapReferences } from "./caching";
8
- import { DynamicRouteRegistration, ServiceWorkerDb } from "./storage";
5
+ } from '@openmrs/esm-offline';
6
+ import escapeRegExp from 'lodash-es/escapeRegExp';
7
+ import { cacheImportMapReferences } from './caching';
8
+ import { DynamicRouteRegistration, ServiceWorkerDb } from './storage';
9
9
 
10
10
  const messageHandlers = {
11
11
  onImportMapChanged,
@@ -21,11 +21,7 @@ async function clearDynamicRoutes() {
21
21
  await new ServiceWorkerDb().dynamicRouteRegistrations.clear();
22
22
  }
23
23
 
24
- async function registerDynamicRoute({
25
- pattern,
26
- url,
27
- strategy,
28
- }: RegisterDynamicRouteMessage) {
24
+ async function registerDynamicRoute({ pattern, url, strategy }: RegisterDynamicRouteMessage) {
29
25
  let finalPattern = pattern;
30
26
  if (!finalPattern && url) {
31
27
  finalPattern = `^${escapeRegExp(url)}$`;
@@ -50,12 +46,10 @@ async function registerDynamicRoute({
50
46
  * @param event The event data containing the message dispatched to the Service Worker.
51
47
  */
52
48
  export async function handleMessage(event: ExtendableMessageEvent) {
53
- const handler = messageHandlers[event.data?.type?.toString() ?? ""];
49
+ const handler = messageHandlers[event.data?.type?.toString() ?? ''];
54
50
 
55
51
  if (!handler) {
56
- fail(
57
- `Received an unknown message of type "${event.data?.type} which cannot be handled.`
58
- );
52
+ fail(`Received an unknown message of type "${event.data?.type} which cannot be handled.`);
59
53
  return;
60
54
  }
61
55
 
@@ -66,11 +60,11 @@ export async function handleMessage(event: ExtendableMessageEvent) {
66
60
  result,
67
61
  });
68
62
  } catch (e) {
69
- fail(e?.message ?? e?.toString() ?? "Unknown error.");
63
+ fail(e?.message ?? e?.toString() ?? 'Unknown error.');
70
64
  }
71
65
 
72
66
  function fail(error: string) {
73
- console.warn("[SW] Handling a message resulted in an error.", error);
67
+ console.warn('[SW] Handling a message resulted in an error.', error);
74
68
  resolve({
75
69
  success: false,
76
70
  error,