@asteby/metacore-pwa 0.3.0
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/LICENSE +201 -0
- package/README.md +127 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +5 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/install-prompt.d.ts +20 -0
- package/dist/components/install-prompt.d.ts.map +1 -0
- package/dist/components/install-prompt.js +45 -0
- package/dist/components/install-prompt.js.map +1 -0
- package/dist/components/notification-permission-prompt.d.ts +27 -0
- package/dist/components/notification-permission-prompt.d.ts.map +1 -0
- package/dist/components/notification-permission-prompt.js +84 -0
- package/dist/components/notification-permission-prompt.js.map +1 -0
- package/dist/components/offline-indicator.d.ts +6 -0
- package/dist/components/offline-indicator.d.ts.map +1 -0
- package/dist/components/offline-indicator.js +11 -0
- package/dist/components/offline-indicator.js.map +1 -0
- package/dist/components/update-prompt.d.ts +19 -0
- package/dist/components/update-prompt.d.ts.map +1 -0
- package/dist/components/update-prompt.js +27 -0
- package/dist/components/update-prompt.js.map +1 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +42 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/notification-manager.d.ts +29 -0
- package/dist/notification-manager.d.ts.map +1 -0
- package/dist/notification-manager.js +99 -0
- package/dist/notification-manager.js.map +1 -0
- package/dist/provider.d.ts +61 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +176 -0
- package/dist/provider.js.map +1 -0
- package/dist/push-service.d.ts +35 -0
- package/dist/push-service.d.ts.map +1 -0
- package/dist/push-service.js +142 -0
- package/dist/push-service.js.map +1 -0
- package/dist/vite-plugin.d.ts +23 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +83 -0
- package/dist/vite-plugin.js.map +1 -0
- package/package.json +72 -0
- package/templates/sw.js +142 -0
- package/templates/sw.ts +115 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-prompt.js","sourceRoot":"","sources":["../../src/components/update-prompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAsC,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAoB3C,MAAM,QAAQ,GAAmC;IAC/C,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,kCAAkC;IAC/C,WAAW,EAAE,YAAY;IACzB,YAAY,EAAE,SAAS;CACxB,CAAA;AAED,SAAS,aAAa,CAAC,EACrB,OAAO,EACP,QAAQ,EACR,OAAO,GAAG,SAAS,EACnB,IAAI,GAML;IACC,MAAM,IAAI,GACR,2LAA2L,CAAA;IAC7L,MAAM,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAA;IACzD,MAAM,YAAY,GAChB,OAAO,KAAK,SAAS;QACnB,CAAC,CAAC,gFAAgF;QAClF,CAAC,CAAC,wDAAwD,CAAA;IAC9D,OAAO,CACL,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,IAAI,SAAS,IAAI,YAAY,EAAE,YACtF,QAAQ,GACF,CACV,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAC9B,eAAe,GAAG,aAAa,EAC/B,QAAQ,EACR,SAAS,MACY,EAAE;IACvB,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CAAA;IACrE,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAA;IAEzC,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAA;IAE7B,OAAO,CACL,eACE,SAAS,EACP,SAAS;YACT,mFAAmF,aAGrF,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAC,0GAA0G,gBACzG,SAAS,YAEpB,KAAC,CAAC,IAAC,SAAS,EAAC,SAAS,GAAG,GAClB,EACT,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,SAAS,IAAC,SAAS,EAAC,gBAAgB,GAAG,EACxC,eAAK,SAAS,EAAC,QAAQ,aACrB,aAAI,SAAS,EAAC,eAAe,YAAE,IAAI,CAAC,KAAK,GAAM,EAC/C,YAAG,SAAS,EAAC,oCAAoC,YAAE,IAAI,CAAC,WAAW,GAAK,EACxE,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,eAAe,IAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAC,IAAI,YAC3C,IAAI,CAAC,WAAW,GACD,EAClB,KAAC,eAAe,IAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,YACrE,IAAI,CAAC,YAAY,GACF,IACd,IACF,IACF,IACF,CACP,CAAA;AACH,CAAC"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type PWAContextValue } from './provider';
|
|
2
|
+
import { type NotificationOptions } from './notification-manager';
|
|
3
|
+
/** Convenience re-export of the PWA context hook. */
|
|
4
|
+
export declare function usePWA(): PWAContextValue;
|
|
5
|
+
export interface UseNotificationsResult {
|
|
6
|
+
permission: NotificationPermission;
|
|
7
|
+
isSupported: boolean;
|
|
8
|
+
requestPermission: () => Promise<boolean>;
|
|
9
|
+
showNotification: (options: NotificationOptions) => Promise<void>;
|
|
10
|
+
isGranted: boolean;
|
|
11
|
+
isDenied: boolean;
|
|
12
|
+
isDefault: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* React hook around {@link NotificationManager} for browser notifications.
|
|
16
|
+
* Polls permission every second to reflect changes made outside the app.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useNotifications(): UseNotificationsResult;
|
|
19
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEtF,qDAAqD;AACrD,wBAAgB,MAAM,IAAI,eAAe,CAExC;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,sBAAsB,CAAA;IAClC,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACzC,gBAAgB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACjE,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,sBAAsB,CAoCzD"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { usePWAContext } from './provider';
|
|
3
|
+
import { notificationManager } from './notification-manager';
|
|
4
|
+
/** Convenience re-export of the PWA context hook. */
|
|
5
|
+
export function usePWA() {
|
|
6
|
+
return usePWAContext();
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* React hook around {@link NotificationManager} for browser notifications.
|
|
10
|
+
* Polls permission every second to reflect changes made outside the app.
|
|
11
|
+
*/
|
|
12
|
+
export function useNotifications() {
|
|
13
|
+
const [permission, setPermission] = useState(notificationManager.getPermission());
|
|
14
|
+
const [isSupported] = useState(notificationManager.isSupported());
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!isSupported)
|
|
17
|
+
return;
|
|
18
|
+
const updatePermission = () => {
|
|
19
|
+
setPermission(notificationManager.getPermission());
|
|
20
|
+
};
|
|
21
|
+
const interval = setInterval(updatePermission, 1000);
|
|
22
|
+
return () => clearInterval(interval);
|
|
23
|
+
}, [isSupported]);
|
|
24
|
+
const requestPermission = async () => {
|
|
25
|
+
const granted = await notificationManager.requestPermission();
|
|
26
|
+
setPermission(notificationManager.getPermission());
|
|
27
|
+
return granted;
|
|
28
|
+
};
|
|
29
|
+
const showNotification = async (options) => {
|
|
30
|
+
await notificationManager.show(options);
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
permission,
|
|
34
|
+
isSupported,
|
|
35
|
+
requestPermission,
|
|
36
|
+
showNotification,
|
|
37
|
+
isGranted: permission === 'granted',
|
|
38
|
+
isDenied: permission === 'denied',
|
|
39
|
+
isDefault: permission === 'default',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAwB,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,wBAAwB,CAAA;AAEtF,qDAAqD;AACrD,MAAM,UAAU,MAAM;IACpB,OAAO,aAAa,EAAE,CAAA;AACxB,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAC1C,mBAAmB,CAAC,aAAa,EAAE,CACpC,CAAA;IACD,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAU,mBAAmB,CAAC,WAAW,EAAE,CAAC,CAAA;IAE1E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,WAAW;YAAE,OAAM;QAExB,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC5B,aAAa,CAAC,mBAAmB,CAAC,aAAa,EAAE,CAAC,CAAA;QACpD,CAAC,CAAA;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAA;QACpD,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,MAAM,iBAAiB,GAAG,KAAK,IAAsB,EAAE;QACrD,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,EAAE,CAAA;QAC7D,aAAa,CAAC,mBAAmB,CAAC,aAAa,EAAE,CAAC,CAAA;QAClD,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,EAAE,OAA4B,EAAiB,EAAE;QAC7E,MAAM,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACzC,CAAC,CAAA;IAED,OAAO;QACL,UAAU;QACV,WAAW;QACX,iBAAiB;QACjB,gBAAgB;QAChB,SAAS,EAAE,UAAU,KAAK,SAAS;QACnC,QAAQ,EAAE,UAAU,KAAK,QAAQ;QACjC,SAAS,EAAE,UAAU,KAAK,SAAS;KACpC,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { PWAProvider, usePWAContext } from './provider';
|
|
2
|
+
export type { PWAContextValue, PWAProviderProps, PWAProviderMessages, } from './provider';
|
|
3
|
+
export { usePWA, useNotifications } from './hooks';
|
|
4
|
+
export type { UseNotificationsResult } from './hooks';
|
|
5
|
+
export { PushNotificationService, } from './push-service';
|
|
6
|
+
export type { PushApiClient, PushServiceOptions } from './push-service';
|
|
7
|
+
export { NotificationManager, notificationManager, } from './notification-manager';
|
|
8
|
+
export type { NotificationOptions, NotificationManagerOptions } from './notification-manager';
|
|
9
|
+
export { PWAInstallPrompt, PWAUpdatePrompt, OfflineIndicator, NotificationPermissionPrompt, } from './components';
|
|
10
|
+
export { metacorePWA } from './vite-plugin';
|
|
11
|
+
export type { MetacorePWAOptions } from './vite-plugin';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACvD,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAClD,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAErD,OAAO,EACL,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAEvE,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAA;AAE7F,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { PWAProvider, usePWAContext } from './provider';
|
|
2
|
+
export { usePWA, useNotifications } from './hooks';
|
|
3
|
+
export { PushNotificationService, } from './push-service';
|
|
4
|
+
export { NotificationManager, notificationManager, } from './notification-manager';
|
|
5
|
+
export { PWAInstallPrompt, PWAUpdatePrompt, OfflineIndicator, NotificationPermissionPrompt, } from './components';
|
|
6
|
+
export { metacorePWA } from './vite-plugin';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAOvD,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAGlD,OAAO,EACL,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAG/B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface NotificationOptions {
|
|
2
|
+
title: string;
|
|
3
|
+
body: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
badge?: string;
|
|
6
|
+
tag?: string;
|
|
7
|
+
data?: unknown;
|
|
8
|
+
requireInteraction?: boolean;
|
|
9
|
+
silent?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface NotificationManagerOptions {
|
|
12
|
+
/** Default icon used when an `options.icon` is not provided. */
|
|
13
|
+
defaultIcon?: string;
|
|
14
|
+
/** Default badge used when an `options.badge` is not provided. */
|
|
15
|
+
defaultBadge?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class NotificationManager {
|
|
18
|
+
private permission;
|
|
19
|
+
private readonly defaultIcon;
|
|
20
|
+
private readonly defaultBadge;
|
|
21
|
+
constructor(options?: NotificationManagerOptions);
|
|
22
|
+
requestPermission(): Promise<boolean>;
|
|
23
|
+
show(options: NotificationOptions): Promise<void>;
|
|
24
|
+
isSupported(): boolean;
|
|
25
|
+
getPermission(): NotificationPermission;
|
|
26
|
+
}
|
|
27
|
+
/** Shared default singleton. Uses no default icons/badges. */
|
|
28
|
+
export declare const notificationManager: NotificationManager;
|
|
29
|
+
//# sourceMappingURL=notification-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-manager.d.ts","sourceRoot":"","sources":["../src/notification-manager.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;gBAErC,OAAO,GAAE,0BAA+B;IAQ9C,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IA6BrC,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDvD,WAAW,IAAI,OAAO;IAItB,aAAa,IAAI,sBAAsB;CAGxC;AAED,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,qBAA4B,CAAA"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { toast } from 'sonner';
|
|
2
|
+
export class NotificationManager {
|
|
3
|
+
permission = 'default';
|
|
4
|
+
defaultIcon;
|
|
5
|
+
defaultBadge;
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
this.defaultIcon = options.defaultIcon;
|
|
8
|
+
this.defaultBadge = options.defaultBadge;
|
|
9
|
+
if (typeof window !== 'undefined' && 'Notification' in window) {
|
|
10
|
+
this.permission = Notification.permission;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async requestPermission() {
|
|
14
|
+
if (typeof window === 'undefined' || !('Notification' in window)) {
|
|
15
|
+
toast.error('Este navegador no soporta notificaciones');
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (this.permission === 'granted') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const permission = await Notification.requestPermission();
|
|
23
|
+
this.permission = permission;
|
|
24
|
+
if (permission === 'granted') {
|
|
25
|
+
toast.success('Notificaciones activadas');
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
toast.error('Permiso de notificaciones denegado');
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
// eslint-disable-next-line no-console
|
|
33
|
+
console.error('Error requesting notification permission:', error);
|
|
34
|
+
toast.error('Error al solicitar permisos');
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async show(options) {
|
|
39
|
+
if (typeof window === 'undefined' || !('Notification' in window)) {
|
|
40
|
+
toast(options.title, { description: options.body });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (this.permission !== 'granted') {
|
|
44
|
+
const granted = await this.requestPermission();
|
|
45
|
+
if (!granted) {
|
|
46
|
+
toast(options.title, { description: options.body });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const icon = options.icon ?? this.defaultIcon;
|
|
52
|
+
const badge = options.badge ?? this.defaultBadge;
|
|
53
|
+
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
|
|
54
|
+
const registration = await navigator.serviceWorker.ready;
|
|
55
|
+
await registration.showNotification(options.title, {
|
|
56
|
+
body: options.body,
|
|
57
|
+
icon,
|
|
58
|
+
badge,
|
|
59
|
+
tag: options.tag,
|
|
60
|
+
data: options.data,
|
|
61
|
+
requireInteraction: options.requireInteraction ?? false,
|
|
62
|
+
silent: options.silent ?? false,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const notification = new Notification(options.title, {
|
|
67
|
+
body: options.body,
|
|
68
|
+
icon,
|
|
69
|
+
tag: options.tag,
|
|
70
|
+
data: options.data,
|
|
71
|
+
requireInteraction: options.requireInteraction ?? false,
|
|
72
|
+
silent: options.silent ?? false,
|
|
73
|
+
});
|
|
74
|
+
notification.onclick = () => {
|
|
75
|
+
window.focus();
|
|
76
|
+
notification.close();
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
toast(options.title, {
|
|
80
|
+
description: options.body,
|
|
81
|
+
duration: 5000,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// eslint-disable-next-line no-console
|
|
86
|
+
console.error('Error showing notification:', error);
|
|
87
|
+
toast(options.title, { description: options.body });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
isSupported() {
|
|
91
|
+
return typeof window !== 'undefined' && 'Notification' in window;
|
|
92
|
+
}
|
|
93
|
+
getPermission() {
|
|
94
|
+
return this.permission;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Shared default singleton. Uses no default icons/badges. */
|
|
98
|
+
export const notificationManager = new NotificationManager();
|
|
99
|
+
//# sourceMappingURL=notification-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-manager.js","sourceRoot":"","sources":["../src/notification-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type PushApiClient, type PushServiceOptions } from './push-service';
|
|
3
|
+
export interface PWAContextValue {
|
|
4
|
+
isOnline: boolean;
|
|
5
|
+
isInstallable: boolean;
|
|
6
|
+
needRefresh: boolean;
|
|
7
|
+
isPushSupported: boolean;
|
|
8
|
+
isPushSubscribed: boolean;
|
|
9
|
+
installApp: () => Promise<boolean>;
|
|
10
|
+
updateApp: () => void;
|
|
11
|
+
closeUpdatePrompt: () => void;
|
|
12
|
+
subscribeToPush: () => Promise<boolean>;
|
|
13
|
+
unsubscribeFromPush: () => Promise<boolean>;
|
|
14
|
+
testPushNotification: () => Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
/** Narrow interface to the `beforeinstallprompt` event. */
|
|
17
|
+
interface BeforeInstallPromptEvent extends Event {
|
|
18
|
+
prompt: () => Promise<void>;
|
|
19
|
+
userChoice: Promise<{
|
|
20
|
+
outcome: 'accepted' | 'dismissed';
|
|
21
|
+
platform: string;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
declare global {
|
|
25
|
+
interface Window {
|
|
26
|
+
deferredPrompt: BeforeInstallPromptEvent | null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export interface PWAProviderMessages {
|
|
30
|
+
offlineReady?: string;
|
|
31
|
+
connectionRestored?: string;
|
|
32
|
+
offline?: string;
|
|
33
|
+
appInstalled?: string;
|
|
34
|
+
installCancelled?: string;
|
|
35
|
+
cannotInstall?: string;
|
|
36
|
+
installing?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface PWAProviderProps {
|
|
39
|
+
children: ReactNode;
|
|
40
|
+
/**
|
|
41
|
+
* Axios-like client used by the push service. Required for push support.
|
|
42
|
+
* If omitted, push-related methods will be no-ops and `isPushSupported` will be false.
|
|
43
|
+
*/
|
|
44
|
+
api?: PushApiClient;
|
|
45
|
+
/** Override push endpoint paths. */
|
|
46
|
+
pushOptions?: PushServiceOptions;
|
|
47
|
+
/** Override user-facing toast messages. */
|
|
48
|
+
messages?: PWAProviderMessages;
|
|
49
|
+
/** Interval in ms between SW update checks. Default: 1 hour. Set to 0 to disable. */
|
|
50
|
+
updateCheckIntervalMs?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Called with the registration once the SW is ready. Useful for instrumentation.
|
|
53
|
+
*/
|
|
54
|
+
onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void;
|
|
55
|
+
/** Called when SW registration fails. */
|
|
56
|
+
onRegisterError?: (error: unknown) => void;
|
|
57
|
+
}
|
|
58
|
+
export declare function PWAProvider({ children, api, pushOptions, messages, updateCheckIntervalMs, onRegistered, onRegisterError, }: PWAProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
export declare function usePWAContext(): PWAContextValue;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AAGd,OAAO,EAA2B,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAErG,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;IACtB,WAAW,EAAE,OAAO,CAAA;IACpB,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAClC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,iBAAiB,EAAE,MAAM,IAAI,CAAA;IAC7B,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACvC,mBAAmB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1C;AAID,2DAA2D;AAC3D,UAAU,wBAAyB,SAAQ,KAAK;IAC9C,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,UAAU,EAAE,OAAO,CAAC;QAAE,OAAO,EAAE,UAAU,GAAG,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC7E;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,cAAc,EAAE,wBAAwB,GAAG,IAAI,CAAA;KAChD;CACF;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAYD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,SAAS,CAAA;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,aAAa,CAAA;IACnB,oCAAoC;IACpC,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,yBAAyB,GAAG,SAAS,KAAK,IAAI,CAAA;IAC5E,yCAAyC;IACzC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CAC3C;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,GAAG,EACH,WAAW,EACX,QAAQ,EACR,qBAAsC,EACtC,YAAY,EACZ,eAAe,GAChB,EAAE,gBAAgB,2CAgLlB;AAED,wBAAgB,aAAa,IAAI,eAAe,CAM/C"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/// <reference types="vite-plugin-pwa/react" />
|
|
3
|
+
import { createContext, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
4
|
+
import { useRegisterSW } from 'virtual:pwa-register/react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { PushNotificationService } from './push-service';
|
|
7
|
+
const PWAContext = createContext(undefined);
|
|
8
|
+
const DEFAULT_MESSAGES = {
|
|
9
|
+
offlineReady: 'App lista para funcionar sin conexión',
|
|
10
|
+
connectionRestored: 'Conexión restaurada',
|
|
11
|
+
offline: 'Sin conexión a internet',
|
|
12
|
+
appInstalled: 'App instalada correctamente',
|
|
13
|
+
installCancelled: 'Instalación cancelada',
|
|
14
|
+
cannotInstall: 'La app ya está instalada o no se puede instalar',
|
|
15
|
+
installing: 'Instalando app...',
|
|
16
|
+
};
|
|
17
|
+
export function PWAProvider({ children, api, pushOptions, messages, updateCheckIntervalMs = 60 * 60 * 1000, onRegistered, onRegisterError, }) {
|
|
18
|
+
const msgs = useMemo(() => ({ ...DEFAULT_MESSAGES, ...messages }), [messages]);
|
|
19
|
+
const [isOnline, setIsOnline] = useState(typeof navigator !== 'undefined' ? navigator.onLine : true);
|
|
20
|
+
const [isInstallable, setIsInstallable] = useState(false);
|
|
21
|
+
const [deferredPrompt, setDeferredPrompt] = useState(null);
|
|
22
|
+
const [isPushSupported, setIsPushSupported] = useState(false);
|
|
23
|
+
const [isPushSubscribed, setIsPushSubscribed] = useState(false);
|
|
24
|
+
const pushServiceRef = useRef(null);
|
|
25
|
+
if (api && !pushServiceRef.current) {
|
|
26
|
+
pushServiceRef.current = new PushNotificationService(api, pushOptions);
|
|
27
|
+
}
|
|
28
|
+
const { needRefresh: [needRefresh, setNeedRefresh], updateServiceWorker, } = useRegisterSW({
|
|
29
|
+
onRegistered(registration) {
|
|
30
|
+
onRegistered?.(registration);
|
|
31
|
+
if (registration && updateCheckIntervalMs > 0) {
|
|
32
|
+
setInterval(() => {
|
|
33
|
+
registration.update();
|
|
34
|
+
}, updateCheckIntervalMs);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
onRegisterError(error) {
|
|
38
|
+
// eslint-disable-next-line no-console
|
|
39
|
+
console.error('SW registration error:', error);
|
|
40
|
+
onRegisterError?.(error);
|
|
41
|
+
},
|
|
42
|
+
onOfflineReady() {
|
|
43
|
+
toast.success(msgs.offlineReady);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const pushService = pushServiceRef.current;
|
|
48
|
+
if (!pushService)
|
|
49
|
+
return;
|
|
50
|
+
const initPush = async () => {
|
|
51
|
+
setIsPushSupported(pushService.getSupported());
|
|
52
|
+
await pushService.init();
|
|
53
|
+
setIsPushSubscribed(pushService.isSubscribed());
|
|
54
|
+
};
|
|
55
|
+
void initPush();
|
|
56
|
+
}, []);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (typeof window === 'undefined')
|
|
59
|
+
return;
|
|
60
|
+
if (window.deferredPrompt) {
|
|
61
|
+
setDeferredPrompt(window.deferredPrompt);
|
|
62
|
+
setIsInstallable(true);
|
|
63
|
+
}
|
|
64
|
+
const handleOnline = () => {
|
|
65
|
+
setIsOnline(true);
|
|
66
|
+
toast.success(msgs.connectionRestored);
|
|
67
|
+
};
|
|
68
|
+
const handleOffline = () => {
|
|
69
|
+
setIsOnline(false);
|
|
70
|
+
toast.warning(msgs.offline);
|
|
71
|
+
};
|
|
72
|
+
const handleBeforeInstallPrompt = (e) => {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
const evt = e;
|
|
75
|
+
setDeferredPrompt(evt);
|
|
76
|
+
setIsInstallable(true);
|
|
77
|
+
window.deferredPrompt = evt;
|
|
78
|
+
};
|
|
79
|
+
const handleAppInstalled = () => {
|
|
80
|
+
setIsInstallable(false);
|
|
81
|
+
setDeferredPrompt(null);
|
|
82
|
+
window.deferredPrompt = null;
|
|
83
|
+
toast.success(msgs.appInstalled);
|
|
84
|
+
};
|
|
85
|
+
window.addEventListener('online', handleOnline);
|
|
86
|
+
window.addEventListener('offline', handleOffline);
|
|
87
|
+
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
|
|
88
|
+
window.addEventListener('appinstalled', handleAppInstalled);
|
|
89
|
+
return () => {
|
|
90
|
+
window.removeEventListener('online', handleOnline);
|
|
91
|
+
window.removeEventListener('offline', handleOffline);
|
|
92
|
+
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
|
|
93
|
+
window.removeEventListener('appinstalled', handleAppInstalled);
|
|
94
|
+
};
|
|
95
|
+
}, [msgs]);
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (typeof navigator === 'undefined' || !('serviceWorker' in navigator))
|
|
98
|
+
return;
|
|
99
|
+
let refreshing = false;
|
|
100
|
+
const handleControllerChange = () => {
|
|
101
|
+
if (!refreshing) {
|
|
102
|
+
refreshing = true;
|
|
103
|
+
window.location.reload();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
navigator.serviceWorker.addEventListener('controllerchange', handleControllerChange);
|
|
107
|
+
return () => {
|
|
108
|
+
navigator.serviceWorker.removeEventListener('controllerchange', handleControllerChange);
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
111
|
+
const installApp = async () => {
|
|
112
|
+
if (!deferredPrompt) {
|
|
113
|
+
toast.error(msgs.cannotInstall);
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
await deferredPrompt.prompt();
|
|
117
|
+
const { outcome } = await deferredPrompt.userChoice;
|
|
118
|
+
if (outcome === 'accepted') {
|
|
119
|
+
toast.success(msgs.installing);
|
|
120
|
+
setDeferredPrompt(null);
|
|
121
|
+
setIsInstallable(false);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
toast.info(msgs.installCancelled);
|
|
125
|
+
return false;
|
|
126
|
+
};
|
|
127
|
+
const updateApp = () => {
|
|
128
|
+
void updateServiceWorker(true);
|
|
129
|
+
};
|
|
130
|
+
const subscribeToPush = async () => {
|
|
131
|
+
const pushService = pushServiceRef.current;
|
|
132
|
+
if (!pushService)
|
|
133
|
+
return false;
|
|
134
|
+
const result = await pushService.subscribe();
|
|
135
|
+
setIsPushSubscribed(result);
|
|
136
|
+
return result;
|
|
137
|
+
};
|
|
138
|
+
const unsubscribeFromPush = async () => {
|
|
139
|
+
const pushService = pushServiceRef.current;
|
|
140
|
+
if (!pushService)
|
|
141
|
+
return false;
|
|
142
|
+
const result = await pushService.unsubscribe();
|
|
143
|
+
if (result) {
|
|
144
|
+
setIsPushSubscribed(false);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
};
|
|
148
|
+
const testPushNotification = async () => {
|
|
149
|
+
const pushService = pushServiceRef.current;
|
|
150
|
+
if (!pushService)
|
|
151
|
+
return;
|
|
152
|
+
await pushService.testNotification();
|
|
153
|
+
};
|
|
154
|
+
const value = {
|
|
155
|
+
isOnline,
|
|
156
|
+
isInstallable,
|
|
157
|
+
needRefresh,
|
|
158
|
+
isPushSupported,
|
|
159
|
+
isPushSubscribed,
|
|
160
|
+
installApp,
|
|
161
|
+
updateApp,
|
|
162
|
+
closeUpdatePrompt: () => setNeedRefresh(false),
|
|
163
|
+
subscribeToPush,
|
|
164
|
+
unsubscribeFromPush,
|
|
165
|
+
testPushNotification,
|
|
166
|
+
};
|
|
167
|
+
return _jsx(PWAContext.Provider, { value: value, children: children });
|
|
168
|
+
}
|
|
169
|
+
export function usePWAContext() {
|
|
170
|
+
const context = useContext(PWAContext);
|
|
171
|
+
if (context === undefined) {
|
|
172
|
+
throw new Error('usePWA must be used within a PWAProvider');
|
|
173
|
+
}
|
|
174
|
+
return context;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":";AAAA,+CAA+C;AAC/C,OAAO,EACL,aAAa,EACb,UAAU,EACV,SAAS,EACT,OAAO,EACP,MAAM,EACN,QAAQ,GAET,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,EAAE,uBAAuB,EAA+C,MAAM,gBAAgB,CAAA;AAgBrG,MAAM,UAAU,GAAG,aAAa,CAA8B,SAAS,CAAC,CAAA;AAwBxE,MAAM,gBAAgB,GAAkC;IACtD,YAAY,EAAE,uCAAuC;IACrD,kBAAkB,EAAE,qBAAqB;IACzC,OAAO,EAAE,yBAAyB;IAClC,YAAY,EAAE,6BAA6B;IAC3C,gBAAgB,EAAE,uBAAuB;IACzC,aAAa,EAAE,iDAAiD;IAChE,UAAU,EAAE,mBAAmB;CAChC,CAAA;AAuBD,MAAM,UAAU,WAAW,CAAC,EAC1B,QAAQ,EACR,GAAG,EACH,WAAW,EACX,QAAQ,EACR,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EACtC,YAAY,EACZ,eAAe,GACE;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,gBAAgB,EAAE,GAAG,QAAQ,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAE9E,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CACtC,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC3D,CAAA;IACD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACzD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAkC,IAAI,CAAC,CAAA;IAC3F,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7D,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE/D,MAAM,cAAc,GAAG,MAAM,CAAiC,IAAI,CAAC,CAAA;IACnE,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QACnC,cAAc,CAAC,OAAO,GAAG,IAAI,uBAAuB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IACxE,CAAC;IAED,MAAM,EACJ,WAAW,EAAE,CAAC,WAAW,EAAE,cAAc,CAAC,EAC1C,mBAAmB,GACpB,GAAG,aAAa,CAAC;QAChB,YAAY,CAAC,YAAY;YACvB,YAAY,EAAE,CAAC,YAAY,CAAC,CAAA;YAC5B,IAAI,YAAY,IAAI,qBAAqB,GAAG,CAAC,EAAE,CAAC;gBAC9C,WAAW,CAAC,GAAG,EAAE;oBACf,YAAY,CAAC,MAAM,EAAE,CAAA;gBACvB,CAAC,EAAE,qBAAqB,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QACD,eAAe,CAAC,KAAK;YACnB,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAA;YAC9C,eAAe,EAAE,CAAC,KAAK,CAAC,CAAA;QAC1B,CAAC;QACD,cAAc;YACZ,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAClC,CAAC;KACF,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAA;QAC1C,IAAI,CAAC,WAAW;YAAE,OAAM;QAExB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;YAC1B,kBAAkB,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAA;YAC9C,MAAM,WAAW,CAAC,IAAI,EAAE,CAAA;YACxB,mBAAmB,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAA;QACjD,CAAC,CAAA;QACD,KAAK,QAAQ,EAAE,CAAA;IACjB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QAEzC,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1B,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;YACxC,gBAAgB,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC;QAED,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,WAAW,CAAC,IAAI,CAAC,CAAA;YACjB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QACxC,CAAC,CAAA;QAED,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,WAAW,CAAC,KAAK,CAAC,CAAA;YAClB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,CAAC,CAAA;QAED,MAAM,yBAAyB,GAAG,CAAC,CAAQ,EAAE,EAAE;YAC7C,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,MAAM,GAAG,GAAG,CAA6B,CAAA;YACzC,iBAAiB,CAAC,GAAG,CAAC,CAAA;YACtB,gBAAgB,CAAC,IAAI,CAAC,CAAA;YACtB,MAAM,CAAC,cAAc,GAAG,GAAG,CAAA;QAC7B,CAAC,CAAA;QAED,MAAM,kBAAkB,GAAG,GAAG,EAAE;YAC9B,gBAAgB,CAAC,KAAK,CAAC,CAAA;YACvB,iBAAiB,CAAC,IAAI,CAAC,CAAA;YACvB,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;YAC5B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAClC,CAAC,CAAA;QAED,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAC/C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACjD,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,yBAAyB,CAAC,CAAA;QACzE,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;QAE3D,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;YAClD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;YACpD,MAAM,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,yBAAyB,CAAC,CAAA;YAC5E,MAAM,CAAC,mBAAmB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;QAChE,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC;YAAE,OAAM;QAE/E,IAAI,UAAU,GAAG,KAAK,CAAA;QACtB,MAAM,sBAAsB,GAAG,GAAG,EAAE;YAClC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,UAAU,GAAG,IAAI,CAAA;gBACjB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;YAC1B,CAAC;QACH,CAAC,CAAA;QAED,SAAS,CAAC,aAAa,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAA;QACpF,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,aAAa,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAA;QACzF,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,UAAU,GAAG,KAAK,IAAsB,EAAE;QAC9C,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAC/B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,cAAc,CAAC,MAAM,EAAE,CAAA;QAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,cAAc,CAAC,UAAU,CAAA;QAEnD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAC9B,iBAAiB,CAAC,IAAI,CAAC,CAAA;YACvB,gBAAgB,CAAC,KAAK,CAAC,CAAA;YACvB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACjC,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,KAAK,mBAAmB,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,IAAsB,EAAE;QACnD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAA;QAC1C,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,CAAA;QAC5C,mBAAmB,CAAC,MAAM,CAAC,CAAA;QAC3B,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,MAAM,mBAAmB,GAAG,KAAK,IAAsB,EAAE;QACvD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAA;QAC1C,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,CAAA;QAC9C,IAAI,MAAM,EAAE,CAAC;YACX,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,MAAM,oBAAoB,GAAG,KAAK,IAAmB,EAAE;QACrD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAA;QAC1C,IAAI,CAAC,WAAW;YAAE,OAAM;QACxB,MAAM,WAAW,CAAC,gBAAgB,EAAE,CAAA;IACtC,CAAC,CAAA;IAED,MAAM,KAAK,GAAoB;QAC7B,QAAQ;QACR,aAAa;QACb,WAAW;QACX,eAAe;QACf,gBAAgB;QAChB,UAAU;QACV,SAAS;QACT,iBAAiB,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC;QAC9C,eAAe;QACf,mBAAmB;QACnB,oBAAoB;KACrB,CAAA;IAED,OAAO,KAAC,UAAU,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAuB,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;IACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface PushApiClient {
|
|
2
|
+
get: <T = unknown>(url: string) => Promise<{
|
|
3
|
+
data: T;
|
|
4
|
+
}>;
|
|
5
|
+
post: <T = unknown>(url: string, body?: unknown) => Promise<{
|
|
6
|
+
data: T;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
9
|
+
export interface PushServiceOptions {
|
|
10
|
+
/** Endpoint to fetch VAPID public key (GET). Default: `/push/public-key` */
|
|
11
|
+
publicKeyPath?: string;
|
|
12
|
+
/** Endpoint to register subscription (POST). Default: `/push/subscribe` */
|
|
13
|
+
subscribePath?: string;
|
|
14
|
+
/** Endpoint to remove subscription (POST). Default: `/push/unsubscribe` */
|
|
15
|
+
unsubscribePath?: string;
|
|
16
|
+
/** Endpoint to trigger a test notification (POST). Default: `/push/test` */
|
|
17
|
+
testPath?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class PushNotificationService {
|
|
20
|
+
private vapidPublicKey;
|
|
21
|
+
private subscription;
|
|
22
|
+
private readonly isSupportedFlag;
|
|
23
|
+
private readonly api;
|
|
24
|
+
private readonly opts;
|
|
25
|
+
constructor(api: PushApiClient, options?: PushServiceOptions);
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
subscribe(): Promise<boolean>;
|
|
28
|
+
unsubscribe(): Promise<boolean>;
|
|
29
|
+
testNotification(): Promise<void>;
|
|
30
|
+
isSubscribed(): boolean;
|
|
31
|
+
getSupported(): boolean;
|
|
32
|
+
private urlBase64ToUint8Array;
|
|
33
|
+
private detectDeviceType;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=push-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-service.d.ts","sourceRoot":"","sources":["../src/push-service.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAA;IACvD,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAA;CACzE;AAWD,MAAM,WAAW,kBAAkB;IACjC,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;gBAEvC,GAAG,EAAE,aAAa,EAAE,OAAO,GAAE,kBAAuB;IAe1D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBrB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IA+C7B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAuB/B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWvC,YAAY,IAAI,OAAO;IAIvB,YAAY,IAAI,OAAO;IAIvB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,gBAAgB;CAczB"}
|