@sudobility/di_web 0.1.95 → 0.1.99
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.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/initialize/initialize.d.ts +1 -1
- package/dist/initialize/initialize.d.ts.map +1 -1
- package/dist/initialize/initialize.js +5 -1
- package/dist/initialize/initialize.js.map +1 -1
- package/dist/sw/firebase-messaging-sw.js +108 -0
- package/dist/sw/index.d.ts +3 -0
- package/dist/sw/index.d.ts.map +1 -0
- package/dist/sw/index.js +3 -0
- package/dist/sw/index.js.map +1 -0
- package/dist/sw/register.d.ts +8 -0
- package/dist/sw/register.d.ts.map +1 -0
- package/dist/sw/register.js +36 -0
- package/dist/sw/register.js.map +1 -0
- package/dist/sw/sw.js +285 -0
- package/dist/sw/vite-plugin-service-worker.d.ts +30 -0
- package/dist/sw/vite-plugin-service-worker.d.ts.map +1 -0
- package/dist/sw/vite-plugin-service-worker.js +43 -0
- package/dist/sw/vite-plugin-service-worker.js.map +1 -0
- package/package.json +14 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { WebInfoService, createWebInfoService, initializeInfoService, getInfoService, resetInfoService, InfoBanner, useInfoBanner, type BannerState, type BannerStateListener, } from './info/index.js';
|
|
2
2
|
export { FirebaseAnalyticsService, initializeFirebaseAnalytics, getAnalyticsService, resetAnalyticsService, type AnalyticsEventParams, initializeWebApp, type WebAppInitOptions, type RevenueCatConfig, } from './initialize/index.js';
|
|
3
3
|
export { getFirebaseService, initializeFirebaseService, resetFirebaseService, WebFirebaseService, createWebFirebaseService, } from '@sudobility/di/web';
|
|
4
|
+
export { registerServiceWorker, unregisterServiceWorker, } from './sw/register.js';
|
|
4
5
|
export type { AnalyticsEvent as FirebaseAnalyticsEvent, AnalyticsService, RemoteConfigValue, RemoteConfigService, FCMNotificationPayload, FCMDataPayload, FCMMessage, FCMPermissionState, FCMState, FCMService, FirebaseService, FirebaseConfig, FirebaseInitOptions, } from '@sudobility/di/web';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,oBAAoB,EAEzB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,cAAc,IAAI,sBAAsB,EACxC,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,oBAAoB,EAEzB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EACV,cAAc,IAAI,sBAAsB,EACxC,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { WebInfoService, createWebInfoService, initializeInfoService, getInfoService, resetInfoService, InfoBanner, useInfoBanner, } from './info/index.js';
|
|
2
2
|
export { FirebaseAnalyticsService, initializeFirebaseAnalytics, getAnalyticsService, resetAnalyticsService, initializeWebApp, } from './initialize/index.js';
|
|
3
3
|
export { getFirebaseService, initializeFirebaseService, resetFirebaseService, WebFirebaseService, createWebFirebaseService, } from '@sudobility/di/web';
|
|
4
|
+
export { registerServiceWorker, unregisterServiceWorker, } from './sw/register.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EAGrB,gBAAgB,GAGjB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EAGrB,gBAAgB,GAGjB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC"}
|
|
@@ -13,7 +13,7 @@ export interface WebAppInitOptions {
|
|
|
13
13
|
firebaseConfig: FirebaseConfig;
|
|
14
14
|
revenueCatConfig?: RevenueCatConfig;
|
|
15
15
|
initializeI18n?: () => void;
|
|
16
|
-
registerServiceWorker?: () => void;
|
|
16
|
+
registerServiceWorker?: boolean | (() => void);
|
|
17
17
|
initWebVitals?: () => void;
|
|
18
18
|
}
|
|
19
19
|
export declare function initializeWebApp(options: WebAppInitOptions): Promise<FirebaseAnalyticsService>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/initialize/initialize.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,oBAAoB,GAC1B,CAAC;AASF,MAAM,WAAW,gBAAgB;IAE/B,MAAM,EAAE,MAAM,CAAC;IAGf,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,eAAe,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAKD,MAAM,WAAW,iBAAiB;IAEhC,cAAc,EAAE,cAAc,CAAC;IAG/B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAGpC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAG5B,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/initialize/initialize.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,oBAAoB,GAC1B,CAAC;AASF,MAAM,WAAW,gBAAgB;IAE/B,MAAM,EAAE,MAAM,CAAC;IAGf,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,eAAe,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAKD,MAAM,WAAW,iBAAiB;IAEhC,cAAc,EAAE,cAAc,CAAC;IAG/B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAGpC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAG5B,qBAAqB,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;IAG/C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAsBD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,wBAAwB,CAAC,CAqEnC"}
|
|
@@ -31,7 +31,11 @@ export async function initializeWebApp(options) {
|
|
|
31
31
|
if (initializeI18n) {
|
|
32
32
|
initializeI18n();
|
|
33
33
|
}
|
|
34
|
-
if (registerServiceWorker) {
|
|
34
|
+
if (registerServiceWorker === true) {
|
|
35
|
+
const { registerServiceWorker: register } = await import('../sw/register.js');
|
|
36
|
+
register();
|
|
37
|
+
}
|
|
38
|
+
else if (typeof registerServiceWorker === 'function') {
|
|
35
39
|
registerServiceWorker();
|
|
36
40
|
}
|
|
37
41
|
if (initWebVitals) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize.js","sourceRoot":"","sources":["../../src/initialize/initialize.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,GAEtB,CAAC;AA+DF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA0B;IAE1B,MAAM,EACJ,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,aAAa,GACd,GAAG,OAAO,CAAC;IAGZ,wBAAwB,EAAE,CAAC;IAG3B,yBAAyB,CAAC,cAAc,CAAC,CAAC;IAG1C,MAAM,SAAS,GAAG,2BAA2B,EAAE,CAAC;IAKhD,wBAAwB,EAAE,CAAC;IAG3B,qBAAqB,EAAE,CAAC;IAGxB,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,IAAI,IAAI,CAAC;YAC3D,MAAM,MAAM,GAAG,YAAY;gBACzB,CAAC,CAAC,gBAAgB,CAAC,MAAM;gBACzB,CAAC,CAAC,gBAAgB,CAAC,aAAa,IAAI,gBAAgB,CAAC,MAAM,CAAC;YAE9D,eAAe,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;YACnD,eAAe,CAAC,sBAAsB,CAAC;gBACrC,OAAO,EAAE,eAAe,CAAC,uBAAuB,EAAE;gBAClD,QAAQ,EAAE,gBAAgB,CAAC,eAAe,IAAI;oBAC5C,SAAS,EAAE,MAAM;oBACjB,IAAI,EAAE,MAAM;iBACb;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,uFAAuF,EACvF,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAGD,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,EAAE,CAAC;IACnB,CAAC;IAGD,IAAI,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"initialize.js","sourceRoot":"","sources":["../../src/initialize/initialize.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,GAEtB,CAAC;AA+DF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA0B;IAE1B,MAAM,EACJ,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,aAAa,GACd,GAAG,OAAO,CAAC;IAGZ,wBAAwB,EAAE,CAAC;IAG3B,yBAAyB,CAAC,cAAc,CAAC,CAAC;IAG1C,MAAM,SAAS,GAAG,2BAA2B,EAAE,CAAC;IAKhD,wBAAwB,EAAE,CAAC;IAG3B,qBAAqB,EAAE,CAAC;IAGxB,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,IAAI,IAAI,CAAC;YAC3D,MAAM,MAAM,GAAG,YAAY;gBACzB,CAAC,CAAC,gBAAgB,CAAC,MAAM;gBACzB,CAAC,CAAC,gBAAgB,CAAC,aAAa,IAAI,gBAAgB,CAAC,MAAM,CAAC;YAE9D,eAAe,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;YACnD,eAAe,CAAC,sBAAsB,CAAC;gBACrC,OAAO,EAAE,eAAe,CAAC,uBAAuB,EAAE;gBAClD,QAAQ,EAAE,gBAAgB,CAAC,eAAe,IAAI;oBAC5C,SAAS,EAAE,MAAM;oBACjB,IAAI,EAAE,MAAM;iBACb;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,uFAAuF,EACvF,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAGD,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,EAAE,CAAC;IACnB,CAAC;IAGD,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,EAAE,qBAAqB,EAAE,QAAQ,EAAE,GACvC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QACpC,QAAQ,EAAE,CAAC;IACb,CAAC;SAAM,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;QACvD,qBAAqB,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,aAAa,EAAE,CAAC;QAClB,aAAa,EAAE,CAAC;IAClB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Firebase Cloud Messaging Service Worker
|
|
2
|
+
// This file must be served from the root domain for FCM to work properly
|
|
3
|
+
|
|
4
|
+
// Import Firebase scripts for the service worker
|
|
5
|
+
importScripts('https://www.gstatic.com/firebasejs/10.7.1/firebase-app-compat.js');
|
|
6
|
+
importScripts('https://www.gstatic.com/firebasejs/10.7.1/firebase-messaging-compat.js');
|
|
7
|
+
|
|
8
|
+
// Initialize Firebase in the service worker
|
|
9
|
+
// Note: This configuration should match your main app's Firebase config
|
|
10
|
+
const firebaseConfig = {
|
|
11
|
+
apiKey: process.env.VITE_FIREBASE_API_KEY,
|
|
12
|
+
authDomain: process.env.VITE_FIREBASE_AUTH_DOMAIN,
|
|
13
|
+
projectId: process.env.VITE_FIREBASE_PROJECT_ID,
|
|
14
|
+
storageBucket: process.env.VITE_FIREBASE_STORAGE_BUCKET,
|
|
15
|
+
messagingSenderId: process.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
|
|
16
|
+
appId: process.env.VITE_FIREBASE_APP_ID,
|
|
17
|
+
measurementId: process.env.VITE_FIREBASE_MEASUREMENT_ID,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Check if Firebase is already initialized
|
|
21
|
+
if (!firebase.apps.length) {
|
|
22
|
+
firebase.initializeApp(firebaseConfig);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Initialize Firebase Cloud Messaging
|
|
26
|
+
const messaging = firebase.messaging();
|
|
27
|
+
|
|
28
|
+
// Handle background messages
|
|
29
|
+
messaging.onBackgroundMessage(payload => {
|
|
30
|
+
const notificationTitle = payload.notification?.title || 'New Email';
|
|
31
|
+
const notificationOptions = {
|
|
32
|
+
body: payload.notification?.body || 'You have received a new email',
|
|
33
|
+
icon: '/favicon.ico',
|
|
34
|
+
badge: '/favicon.ico',
|
|
35
|
+
tag: 'email-notification',
|
|
36
|
+
data: {
|
|
37
|
+
url: payload.data?.url || '/mail',
|
|
38
|
+
emailId: payload.data?.emailId,
|
|
39
|
+
timestamp: Date.now(),
|
|
40
|
+
},
|
|
41
|
+
actions: [
|
|
42
|
+
{
|
|
43
|
+
action: 'view',
|
|
44
|
+
title: 'View Email',
|
|
45
|
+
icon: '/favicon.ico',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
action: 'dismiss',
|
|
49
|
+
title: 'Dismiss',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
requireInteraction: true,
|
|
53
|
+
silent: false,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Show notification
|
|
57
|
+
self.registration.showNotification(notificationTitle, notificationOptions);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Handle notification clicks
|
|
61
|
+
self.addEventListener('notificationclick', event => {
|
|
62
|
+
event.notification.close();
|
|
63
|
+
|
|
64
|
+
if (event.action === 'view') {
|
|
65
|
+
// Open or focus the email app
|
|
66
|
+
const urlToOpen = event.notification.data?.url || '/mail';
|
|
67
|
+
|
|
68
|
+
event.waitUntil(
|
|
69
|
+
clients
|
|
70
|
+
.matchAll({
|
|
71
|
+
type: 'window',
|
|
72
|
+
includeUncontrolled: true,
|
|
73
|
+
})
|
|
74
|
+
.then(clientList => {
|
|
75
|
+
// Check if app is already open
|
|
76
|
+
for (const client of clientList) {
|
|
77
|
+
if (client.url.includes(self.location.origin)) {
|
|
78
|
+
client.focus();
|
|
79
|
+
client.navigate(urlToOpen);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Open new window if app isn't open
|
|
85
|
+
if (clients.openWindow) {
|
|
86
|
+
return clients.openWindow(urlToOpen);
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
} else if (event.action === 'dismiss') {
|
|
91
|
+
// Just close the notification (already closed above)
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Handle notification close events
|
|
96
|
+
self.addEventListener('notificationclose', event => {
|
|
97
|
+
// Notification closed
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Optional: Handle push events directly (if using custom push server)
|
|
101
|
+
self.addEventListener('push', event => {
|
|
102
|
+
if (event.data) {
|
|
103
|
+
const data = event.data.json();
|
|
104
|
+
|
|
105
|
+
// Handle custom push notifications if needed
|
|
106
|
+
// This is typically handled by FCM automatically
|
|
107
|
+
}
|
|
108
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sw/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,MAAM,iCAAiC,CAAC"}
|
package/dist/sw/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sw/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,mBAAmB,GAEpB,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface ImportMeta {
|
|
3
|
+
readonly env: Record<string, string | boolean | undefined>;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export declare function registerServiceWorker(): void;
|
|
7
|
+
export declare function unregisterServiceWorker(): void;
|
|
8
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/sw/register.ts"],"names":[],"mappings":"AAKA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;KAC5D;CACF;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAkC5C;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function registerServiceWorker() {
|
|
2
|
+
if ('serviceWorker' in navigator && import.meta.env['PROD']) {
|
|
3
|
+
window.addEventListener('load', async () => {
|
|
4
|
+
try {
|
|
5
|
+
const registration = await navigator.serviceWorker.register('/sw.js', {
|
|
6
|
+
scope: '/',
|
|
7
|
+
});
|
|
8
|
+
setInterval(() => {
|
|
9
|
+
registration.update();
|
|
10
|
+
}, 24 * 60 * 60 * 1000);
|
|
11
|
+
registration.addEventListener('updatefound', () => {
|
|
12
|
+
const newWorker = registration.installing;
|
|
13
|
+
if (newWorker) {
|
|
14
|
+
newWorker.addEventListener('statechange', () => {
|
|
15
|
+
if (newWorker.state === 'installed' &&
|
|
16
|
+
navigator.serviceWorker.controller) {
|
|
17
|
+
console.info('New content available, refresh to update');
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.error('Service worker registration failed:', error);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function unregisterServiceWorker() {
|
|
30
|
+
if ('serviceWorker' in navigator) {
|
|
31
|
+
navigator.serviceWorker.ready.then((registration) => {
|
|
32
|
+
registration.unregister();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/sw/register.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,qBAAqB;IACnC,IAAI,eAAe,IAAI,SAAS,IAAK,MAAM,CAAC,IAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5E,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;YACzC,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,EAAE;oBACpE,KAAK,EAAE,GAAG;iBACX,CAAC,CAAC;gBAGH,WAAW,CACT,GAAG,EAAE;oBACH,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxB,CAAC,EACD,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CACpB,CAAC;gBAEF,YAAY,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE;oBAChD,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC;oBAC1C,IAAI,SAAS,EAAE,CAAC;wBACd,SAAS,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE;4BAC7C,IACE,SAAS,CAAC,KAAK,KAAK,WAAW;gCAC/B,SAAS,CAAC,aAAa,CAAC,UAAU,EAClC,CAAC;gCACD,OAAO,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;4BAC3D,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,IAAI,eAAe,IAAI,SAAS,EAAE,CAAC;QACjC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE;YAClD,YAAY,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
package/dist/sw/sw.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Service Worker for Sudobility Web Apps
|
|
3
|
+
* Implements caching strategies with TTL-based expiration and size limits
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const CACHE_VERSION = 'v1';
|
|
7
|
+
const STATIC_CACHE = `sudobility-static-${CACHE_VERSION}`;
|
|
8
|
+
const DYNAMIC_CACHE = `sudobility-dynamic-${CACHE_VERSION}`;
|
|
9
|
+
const IMAGE_CACHE = `sudobility-images-${CACHE_VERSION}`;
|
|
10
|
+
|
|
11
|
+
// TTL per cache type
|
|
12
|
+
const CACHE_TTL = {
|
|
13
|
+
[STATIC_CACHE]: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
14
|
+
[DYNAMIC_CACHE]: 24 * 60 * 60 * 1000, // 1 day
|
|
15
|
+
[IMAGE_CACHE]: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Cache size limits
|
|
19
|
+
const CACHE_LIMITS = {
|
|
20
|
+
[STATIC_CACHE]: 100,
|
|
21
|
+
[DYNAMIC_CACHE]: 50,
|
|
22
|
+
[IMAGE_CACHE]: 30,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Files to precache on install
|
|
26
|
+
const PRECACHE_URLS = ['/', '/manifest.json'];
|
|
27
|
+
|
|
28
|
+
// CDN domains allowed for caching
|
|
29
|
+
const ALLOWED_CDN_DOMAINS = ['cdn.jsdelivr.net', 'unpkg.com'];
|
|
30
|
+
|
|
31
|
+
// Install event - precache essential files
|
|
32
|
+
self.addEventListener('install', event => {
|
|
33
|
+
event.waitUntil(
|
|
34
|
+
caches.open(STATIC_CACHE).then(cache => {
|
|
35
|
+
return cache.addAll(PRECACHE_URLS);
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
self.skipWaiting();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Activate event - clean up old caches
|
|
42
|
+
self.addEventListener('activate', event => {
|
|
43
|
+
const CURRENT_CACHES = [STATIC_CACHE, DYNAMIC_CACHE, IMAGE_CACHE];
|
|
44
|
+
const LEGACY_PREFIXES = ['web3mail-', 'shapeshyft-'];
|
|
45
|
+
|
|
46
|
+
event.waitUntil(
|
|
47
|
+
caches
|
|
48
|
+
.keys()
|
|
49
|
+
.then(cacheNames => {
|
|
50
|
+
return Promise.all(
|
|
51
|
+
cacheNames
|
|
52
|
+
.filter(name => {
|
|
53
|
+
// Remove old sudobility caches
|
|
54
|
+
if (name.startsWith('sudobility-') && !CURRENT_CACHES.includes(name)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
// Remove legacy app-specific caches
|
|
58
|
+
return LEGACY_PREFIXES.some(prefix => name.startsWith(prefix));
|
|
59
|
+
})
|
|
60
|
+
.map(name => caches.delete(name))
|
|
61
|
+
);
|
|
62
|
+
})
|
|
63
|
+
.then(() => self.clients.claim())
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Trim cache to limit size
|
|
68
|
+
async function trimCache(cacheName, maxItems) {
|
|
69
|
+
const cache = await caches.open(cacheName);
|
|
70
|
+
const keys = await cache.keys();
|
|
71
|
+
if (keys.length > maxItems) {
|
|
72
|
+
await cache.delete(keys[0]);
|
|
73
|
+
return trimCache(cacheName, maxItems);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Check if a cached response has expired
|
|
78
|
+
function isExpired(response, cacheName) {
|
|
79
|
+
const maxAge = CACHE_TTL[cacheName];
|
|
80
|
+
if (!maxAge) return false;
|
|
81
|
+
|
|
82
|
+
const dateHeader = response.headers.get('date');
|
|
83
|
+
if (!dateHeader) return false;
|
|
84
|
+
|
|
85
|
+
return Date.now() - new Date(dateHeader).getTime() > maxAge;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Fetch event - implement caching strategies
|
|
89
|
+
self.addEventListener('fetch', event => {
|
|
90
|
+
const { request } = event;
|
|
91
|
+
const url = new URL(request.url);
|
|
92
|
+
|
|
93
|
+
// Skip non-GET requests
|
|
94
|
+
if (request.method !== 'GET') return;
|
|
95
|
+
|
|
96
|
+
// Skip chrome-extension and other non-http(s) requests
|
|
97
|
+
if (!url.protocol.startsWith('http')) return;
|
|
98
|
+
|
|
99
|
+
// Skip Google Fonts - they have their own caching and SW intercept causes CSP issues
|
|
100
|
+
if (
|
|
101
|
+
url.hostname.includes('fonts.googleapis.com') ||
|
|
102
|
+
url.hostname.includes('fonts.gstatic.com')
|
|
103
|
+
) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Skip non-same-origin requests unless on CDN allowlist
|
|
108
|
+
if (
|
|
109
|
+
url.origin !== location.origin &&
|
|
110
|
+
!ALLOWED_CDN_DOMAINS.some(domain => url.hostname.includes(domain))
|
|
111
|
+
) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Skip API requests
|
|
116
|
+
if (url.pathname.startsWith('/api/') || url.hostname.startsWith('api.')) return;
|
|
117
|
+
|
|
118
|
+
// Strategy: Cache First for static assets (JS, CSS, fonts)
|
|
119
|
+
if (
|
|
120
|
+
url.pathname.match(/\.(js|css|woff2?|ttf|eot)$/) ||
|
|
121
|
+
url.pathname.startsWith('/assets/')
|
|
122
|
+
) {
|
|
123
|
+
event.respondWith(cacheFirst(request, STATIC_CACHE));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Strategy: Cache First for images
|
|
128
|
+
if (url.pathname.match(/\.(png|jpg|jpeg|svg|webp|gif|ico)$/)) {
|
|
129
|
+
event.respondWith(cacheFirst(request, IMAGE_CACHE));
|
|
130
|
+
event.waitUntil(trimCache(IMAGE_CACHE, CACHE_LIMITS[IMAGE_CACHE]));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Strategy: Stale While Revalidate for locale files
|
|
135
|
+
if (url.pathname.startsWith('/locales/')) {
|
|
136
|
+
event.respondWith(staleWhileRevalidate(request, DYNAMIC_CACHE));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Strategy: Network First for HTML pages
|
|
141
|
+
if (
|
|
142
|
+
request.headers.get('accept')?.includes('text/html') ||
|
|
143
|
+
url.pathname === '/' ||
|
|
144
|
+
!url.pathname.includes('.')
|
|
145
|
+
) {
|
|
146
|
+
event.respondWith(networkFirst(request, DYNAMIC_CACHE));
|
|
147
|
+
event.waitUntil(trimCache(DYNAMIC_CACHE, CACHE_LIMITS[DYNAMIC_CACHE]));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Default: Network First
|
|
152
|
+
event.respondWith(networkFirst(request, DYNAMIC_CACHE));
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Cache First strategy - with TTL expiration
|
|
156
|
+
async function cacheFirst(request, cacheName) {
|
|
157
|
+
const cache = await caches.open(cacheName);
|
|
158
|
+
const cached = await cache.match(request);
|
|
159
|
+
|
|
160
|
+
if (cached && !isExpired(cached, cacheName)) {
|
|
161
|
+
return cached;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
const response = await fetch(request);
|
|
166
|
+
if (response.ok) {
|
|
167
|
+
cache.put(request, response.clone());
|
|
168
|
+
}
|
|
169
|
+
return response;
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (cached) return cached;
|
|
172
|
+
return caches.match('/');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Network First strategy
|
|
177
|
+
async function networkFirst(request, cacheName) {
|
|
178
|
+
const cache = await caches.open(cacheName);
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const response = await fetch(request);
|
|
182
|
+
if (response.ok) {
|
|
183
|
+
cache.put(request, response.clone());
|
|
184
|
+
}
|
|
185
|
+
return response;
|
|
186
|
+
} catch (error) {
|
|
187
|
+
const cached = await cache.match(request);
|
|
188
|
+
if (cached) return cached;
|
|
189
|
+
if (request.headers.get('accept')?.includes('text/html')) {
|
|
190
|
+
return caches.match('/');
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Stale While Revalidate strategy
|
|
197
|
+
async function staleWhileRevalidate(request, cacheName) {
|
|
198
|
+
const cache = await caches.open(cacheName);
|
|
199
|
+
const cached = await cache.match(request);
|
|
200
|
+
|
|
201
|
+
const fetchPromise = fetch(request).then(response => {
|
|
202
|
+
if (response.ok) {
|
|
203
|
+
cache.put(request, response.clone());
|
|
204
|
+
}
|
|
205
|
+
return response;
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
return cached || fetchPromise;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Handle messages from the main thread
|
|
212
|
+
self.addEventListener('message', event => {
|
|
213
|
+
if (event.data?.type === 'SKIP_WAITING') {
|
|
214
|
+
self.skipWaiting();
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Background sync for failed requests
|
|
219
|
+
self.addEventListener('sync', event => {
|
|
220
|
+
if (event.tag === 'background-sync') {
|
|
221
|
+
event.waitUntil(doBackgroundSync());
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
async function doBackgroundSync() {
|
|
226
|
+
const cache = await caches.open(DYNAMIC_CACHE);
|
|
227
|
+
const requests = await cache.keys();
|
|
228
|
+
|
|
229
|
+
for (const request of requests) {
|
|
230
|
+
try {
|
|
231
|
+
await fetch(request);
|
|
232
|
+
await cache.delete(request);
|
|
233
|
+
} catch (error) {
|
|
234
|
+
// Will retry on next sync
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Push notification handler
|
|
240
|
+
self.addEventListener('push', event => {
|
|
241
|
+
if (!event.data) return;
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
const data = event.data.json();
|
|
245
|
+
const { title, body, icon, badge, data: notificationData } = data;
|
|
246
|
+
|
|
247
|
+
event.waitUntil(
|
|
248
|
+
self.registration.showNotification(title || 'Notification', {
|
|
249
|
+
body,
|
|
250
|
+
icon: icon || '/favicon-192.png',
|
|
251
|
+
badge: badge || '/favicon-96.png',
|
|
252
|
+
data: notificationData,
|
|
253
|
+
requireInteraction: true,
|
|
254
|
+
actions: [
|
|
255
|
+
{ action: 'open', title: 'Open App' },
|
|
256
|
+
{ action: 'dismiss', title: 'Dismiss' },
|
|
257
|
+
],
|
|
258
|
+
})
|
|
259
|
+
);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.error('[SW] Push notification error:', error);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Notification click handler
|
|
266
|
+
self.addEventListener('notificationclick', event => {
|
|
267
|
+
event.notification.close();
|
|
268
|
+
|
|
269
|
+
if (event.action === 'dismiss') return;
|
|
270
|
+
|
|
271
|
+
const urlToOpen = event.notification.data?.url || '/';
|
|
272
|
+
|
|
273
|
+
event.waitUntil(
|
|
274
|
+
self.clients.matchAll({ type: 'window' }).then(clients => {
|
|
275
|
+
for (const client of clients) {
|
|
276
|
+
if (client.url === urlToOpen && 'focus' in client) {
|
|
277
|
+
return client.focus();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (self.clients.openWindow) {
|
|
281
|
+
return self.clients.openWindow(urlToOpen);
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
);
|
|
285
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface ServiceWorkerPluginOptions {
|
|
2
|
+
includeFirebaseMessaging?: boolean;
|
|
3
|
+
}
|
|
4
|
+
interface MiddlewareRequest {
|
|
5
|
+
url?: string;
|
|
6
|
+
}
|
|
7
|
+
interface MiddlewareResponse {
|
|
8
|
+
setHeader: (k: string, v: string) => void;
|
|
9
|
+
end: (s: string) => void;
|
|
10
|
+
}
|
|
11
|
+
interface ViteDevServer {
|
|
12
|
+
middlewares: {
|
|
13
|
+
use: (fn: (req: MiddlewareRequest, res: MiddlewareResponse, next: () => void) => void) => void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
interface EmitContext {
|
|
17
|
+
emitFile: (file: {
|
|
18
|
+
type: string;
|
|
19
|
+
fileName: string;
|
|
20
|
+
source: string;
|
|
21
|
+
}) => void;
|
|
22
|
+
}
|
|
23
|
+
interface VitePlugin {
|
|
24
|
+
name: string;
|
|
25
|
+
configureServer: (server: ViteDevServer) => void;
|
|
26
|
+
generateBundle: (this: EmitContext) => void;
|
|
27
|
+
}
|
|
28
|
+
export declare function serviceWorkerPlugin(options?: ServiceWorkerPluginOptions): VitePlugin;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=vite-plugin-service-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin-service-worker.d.ts","sourceRoot":"","sources":["../../src/sw/vite-plugin-service-worker.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,0BAA0B;IAEzC,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,UAAU,iBAAiB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,WAAW,EAAE;QACX,GAAG,EAAE,CACH,EAAE,EAAE,CACF,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,MAAM,IAAI,KACb,IAAI,KACN,IAAI,CAAC;KACX,CAAC;CACH;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9E;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;CAC7C;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,UAAU,CAgDZ"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { resolve, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
export function serviceWorkerPlugin(options = {}) {
|
|
5
|
+
const { includeFirebaseMessaging = false } = options;
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const swPath = resolve(__dirname, 'sw.js');
|
|
8
|
+
const firebaseSwPath = resolve(__dirname, 'firebase-messaging-sw.js');
|
|
9
|
+
return {
|
|
10
|
+
name: 'sudobility-service-worker',
|
|
11
|
+
configureServer(server) {
|
|
12
|
+
server.middlewares.use((req, res, next) => {
|
|
13
|
+
if (req.url === '/sw.js') {
|
|
14
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
15
|
+
res.end(readFileSync(swPath, 'utf-8'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (includeFirebaseMessaging &&
|
|
19
|
+
req.url === '/firebase-messaging-sw.js') {
|
|
20
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
21
|
+
res.end(readFileSync(firebaseSwPath, 'utf-8'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
next();
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
generateBundle() {
|
|
28
|
+
this.emitFile({
|
|
29
|
+
type: 'asset',
|
|
30
|
+
fileName: 'sw.js',
|
|
31
|
+
source: readFileSync(swPath, 'utf-8'),
|
|
32
|
+
});
|
|
33
|
+
if (includeFirebaseMessaging) {
|
|
34
|
+
this.emitFile({
|
|
35
|
+
type: 'asset',
|
|
36
|
+
fileName: 'firebase-messaging-sw.js',
|
|
37
|
+
source: readFileSync(firebaseSwPath, 'utf-8'),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=vite-plugin-service-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin-service-worker.js","sourceRoot":"","sources":["../../src/sw/vite-plugin-service-worker.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAsCpC,MAAM,UAAU,mBAAmB,CACjC,UAAsC,EAAE;IAExC,MAAM,EAAE,wBAAwB,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAGrD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,EAAE,0BAA0B,CAAC,CAAC;IAEtE,OAAO;QACL,IAAI,EAAE,2BAA2B;QAEjC,eAAe,CAAC,MAAqB;YACnC,MAAM,CAAC,WAAW,CAAC,GAAG,CACpB,CAAC,GAAsB,EAAE,GAAuB,EAAE,IAAgB,EAAE,EAAE;gBACpE,IAAI,GAAG,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACzB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;oBACxD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;oBACvC,OAAO;gBACT,CAAC;gBACD,IACE,wBAAwB;oBACxB,GAAG,CAAC,GAAG,KAAK,2BAA2B,EACvC,CAAC;oBACD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;oBACxD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;oBAC/C,OAAO;gBACT,CAAC;gBACD,IAAI,EAAE,CAAC;YACT,CAAC,CACF,CAAC;QACJ,CAAC;QAED,cAAc;YACZ,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC;aACtC,CAAC,CAAC;YAEH,IAAI,wBAAwB,EAAE,CAAC;gBAC7B,IAAI,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,0BAA0B;oBACpC,MAAM,EAAE,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sudobility/di_web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.99",
|
|
4
4
|
"description": "Web implementations of dependency injection services for Sudobility",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,10 +9,14 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"import": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./vite": {
|
|
14
|
+
"import": "./dist/sw/vite-plugin-service-worker.js",
|
|
15
|
+
"types": "./dist/sw/vite-plugin-service-worker.d.ts"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"scripts": {
|
|
15
|
-
"build": "tsc",
|
|
19
|
+
"build": "tsc && cp src/sw/sw.js dist/sw/sw.js && cp src/sw/firebase-messaging-sw.js dist/sw/firebase-messaging-sw.js",
|
|
16
20
|
"build:watch": "tsc --watch",
|
|
17
21
|
"clean": "rm -rf dist",
|
|
18
22
|
"test": "vitest run",
|
|
@@ -38,10 +42,11 @@
|
|
|
38
42
|
"author": "Sudobility Inc",
|
|
39
43
|
"license": "BUSL-1.1",
|
|
40
44
|
"peerDependencies": {
|
|
41
|
-
"@sudobility/components": "^5.0.
|
|
45
|
+
"@sudobility/components": "^5.0.7",
|
|
42
46
|
"@sudobility/di": "^1.5.34",
|
|
43
47
|
"@sudobility/types": "^1.9.50",
|
|
44
|
-
"react": "^18.0.0 || ^19.0.0"
|
|
48
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
49
|
+
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
45
50
|
},
|
|
46
51
|
"repository": {
|
|
47
52
|
"type": "git",
|
|
@@ -50,11 +55,14 @@
|
|
|
50
55
|
"peerDependenciesMeta": {
|
|
51
56
|
"@sudobility/subscription_lib": {
|
|
52
57
|
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"vite": {
|
|
60
|
+
"optional": true
|
|
53
61
|
}
|
|
54
62
|
},
|
|
55
63
|
"devDependencies": {
|
|
56
64
|
"@eslint/js": "^9.38.0",
|
|
57
|
-
"@sudobility/components": "^5.0.
|
|
65
|
+
"@sudobility/components": "^5.0.7",
|
|
58
66
|
"@sudobility/di": "^1.5.34",
|
|
59
67
|
"@sudobility/subscription_lib": "^0.0.14",
|
|
60
68
|
"@sudobility/types": "^1.9.50",
|
|
@@ -70,6 +78,7 @@
|
|
|
70
78
|
"prettier": "^3.6.2",
|
|
71
79
|
"react": "^19.1.0",
|
|
72
80
|
"typescript": "^5.9.3",
|
|
81
|
+
"vite": "^7.1.12",
|
|
73
82
|
"vitest": "^3.2.4"
|
|
74
83
|
},
|
|
75
84
|
"publishConfig": {
|