@markwharton/pwa-push 1.5.3 → 2.0.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/dist/client.d.ts +181 -0
- package/dist/client.js +412 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/pwa-push-sw.js +61 -39
- package/dist/{server/send.d.ts → server.d.ts} +6 -2
- package/dist/{server/send.js → server.js} +9 -7
- package/dist/shared.d.ts +22 -2
- package/dist/shared.js +9 -6
- package/dist/sw.d.ts +1 -1
- package/dist/sw.js +2 -2
- package/package.json +11 -8
- package/dist/__tests__/client/deviceId.test.d.ts +0 -1
- package/dist/__tests__/client/deviceId.test.js +0 -134
- package/dist/__tests__/client/encoding.test.d.ts +0 -1
- package/dist/__tests__/client/encoding.test.js +0 -89
- package/dist/__tests__/client/indexedDb.test.d.ts +0 -1
- package/dist/__tests__/client/indexedDb.test.js +0 -195
- package/dist/__tests__/client/renewal.test.d.ts +0 -1
- package/dist/__tests__/client/renewal.test.js +0 -170
- package/dist/__tests__/client/subscribe.test.d.ts +0 -1
- package/dist/__tests__/client/subscribe.test.js +0 -299
- package/dist/__tests__/server/send.test.d.ts +0 -1
- package/dist/__tests__/server/send.test.js +0 -226
- package/dist/client/deviceId.d.ts +0 -23
- package/dist/client/deviceId.js +0 -49
- package/dist/client/encoding.d.ts +0 -17
- package/dist/client/encoding.js +0 -32
- package/dist/client/index.d.ts +0 -4
- package/dist/client/index.js +0 -20
- package/dist/client/indexedDb.d.ts +0 -38
- package/dist/client/indexedDb.js +0 -89
- package/dist/client/renewal.d.ts +0 -31
- package/dist/client/renewal.js +0 -80
- package/dist/client/subscribe.d.ts +0 -88
- package/dist/client/subscribe.js +0 -176
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.js +0 -11
- package/dist/types.d.ts +0 -39
- package/dist/types.js +0 -11
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Push subscription helpers for main thread
|
|
3
|
-
*/
|
|
4
|
-
import { Result } from '@markwharton/pwa-core/types';
|
|
5
|
-
import { PushSubscription, SubscriptionRequest, PushPermissionState } from '../shared';
|
|
6
|
-
/**
|
|
7
|
-
* Gets the current notification permission state.
|
|
8
|
-
* @returns The current permission state ('granted', 'denied', or 'default')
|
|
9
|
-
* @example
|
|
10
|
-
* const state = getPermissionState();
|
|
11
|
-
* if (state === 'granted') {
|
|
12
|
-
* // Can show notifications
|
|
13
|
-
* }
|
|
14
|
-
*/
|
|
15
|
-
export declare function getPermissionState(): PushPermissionState;
|
|
16
|
-
/**
|
|
17
|
-
* Requests notification permission from the user.
|
|
18
|
-
* Shows browser permission dialog if not already granted/denied.
|
|
19
|
-
* @returns The resulting permission state
|
|
20
|
-
* @example
|
|
21
|
-
* const permission = await requestPermission();
|
|
22
|
-
* if (permission === 'granted') {
|
|
23
|
-
* await subscribeToPush(vapidKey);
|
|
24
|
-
* }
|
|
25
|
-
*/
|
|
26
|
-
export declare function requestPermission(): Promise<PushPermissionState>;
|
|
27
|
-
/**
|
|
28
|
-
* Checks if push notifications are supported in the current browser.
|
|
29
|
-
* Requires both Service Worker and Push API support.
|
|
30
|
-
* @returns True if push notifications are supported
|
|
31
|
-
* @example
|
|
32
|
-
* if (!isPushSupported()) {
|
|
33
|
-
* console.log('Push not supported on this browser');
|
|
34
|
-
* return;
|
|
35
|
-
* }
|
|
36
|
-
*/
|
|
37
|
-
export declare function isPushSupported(): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Converts a browser PushSubscription to the simplified format for backend storage.
|
|
40
|
-
* Works in both main thread and service worker contexts.
|
|
41
|
-
* @param browserSub - The native browser PushSubscription object
|
|
42
|
-
* @returns A simplified PushSubscription with endpoint and keys
|
|
43
|
-
* @example
|
|
44
|
-
* const browserSub = await registration.pushManager.subscribe({ ... });
|
|
45
|
-
* const subscription = toPushSubscription(browserSub);
|
|
46
|
-
* await fetch('/api/subscribe', { body: JSON.stringify(subscription) });
|
|
47
|
-
*/
|
|
48
|
-
export declare function toPushSubscription(browserSub: globalThis.PushSubscription): PushSubscription;
|
|
49
|
-
/**
|
|
50
|
-
* Subscribes to push notifications and prepares a request for backend registration.
|
|
51
|
-
* Handles permission request, service worker subscription, and data persistence.
|
|
52
|
-
* @param vapidPublicKey - The VAPID public key from your server
|
|
53
|
-
* @param basePath - Optional base path for notification click handling (default: '/')
|
|
54
|
-
* @returns Result with subscription request on success, or error message on failure
|
|
55
|
-
* @example
|
|
56
|
-
* const result = await subscribeToPush(vapidPublicKey);
|
|
57
|
-
* if (result.ok) {
|
|
58
|
-
* await fetch('/api/push/subscribe', {
|
|
59
|
-
* method: 'POST',
|
|
60
|
-
* body: JSON.stringify(result.data)
|
|
61
|
-
* });
|
|
62
|
-
* }
|
|
63
|
-
*/
|
|
64
|
-
export declare function subscribeToPush(vapidPublicKey: string, basePath?: string): Promise<Result<SubscriptionRequest>>;
|
|
65
|
-
/**
|
|
66
|
-
* Unsubscribes from push notifications.
|
|
67
|
-
* Removes the browser push subscription and clears stored subscription data.
|
|
68
|
-
* @returns Result with ok=true on success, or error message on failure
|
|
69
|
-
* @example
|
|
70
|
-
* const result = await unsubscribeFromPush();
|
|
71
|
-
* if (result.ok) {
|
|
72
|
-
* await fetch('/api/push/unsubscribe', { method: 'POST' });
|
|
73
|
-
* }
|
|
74
|
-
*/
|
|
75
|
-
export declare function unsubscribeFromPush(): Promise<Result<void>>;
|
|
76
|
-
/**
|
|
77
|
-
* Gets the current push subscription if one exists.
|
|
78
|
-
* Useful for checking subscription status or syncing with backend.
|
|
79
|
-
* @returns Result with the current subscription, or error if not subscribed
|
|
80
|
-
* @example
|
|
81
|
-
* const result = await getCurrentSubscription();
|
|
82
|
-
* if (result.ok) {
|
|
83
|
-
* console.log('Endpoint:', result.data.endpoint);
|
|
84
|
-
* } else {
|
|
85
|
-
* console.log('Not subscribed:', result.error);
|
|
86
|
-
* }
|
|
87
|
-
*/
|
|
88
|
-
export declare function getCurrentSubscription(): Promise<Result<PushSubscription>>;
|
package/dist/client/subscribe.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Push subscription helpers for main thread
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getPermissionState = getPermissionState;
|
|
7
|
-
exports.requestPermission = requestPermission;
|
|
8
|
-
exports.isPushSupported = isPushSupported;
|
|
9
|
-
exports.toPushSubscription = toPushSubscription;
|
|
10
|
-
exports.subscribeToPush = subscribeToPush;
|
|
11
|
-
exports.unsubscribeFromPush = unsubscribeFromPush;
|
|
12
|
-
exports.getCurrentSubscription = getCurrentSubscription;
|
|
13
|
-
const types_1 = require("@markwharton/pwa-core/types");
|
|
14
|
-
const deviceId_1 = require("./deviceId");
|
|
15
|
-
const indexedDb_1 = require("./indexedDb");
|
|
16
|
-
const encoding_1 = require("./encoding");
|
|
17
|
-
/**
|
|
18
|
-
* Gets the current notification permission state.
|
|
19
|
-
* @returns The current permission state ('granted', 'denied', or 'default')
|
|
20
|
-
* @example
|
|
21
|
-
* const state = getPermissionState();
|
|
22
|
-
* if (state === 'granted') {
|
|
23
|
-
* // Can show notifications
|
|
24
|
-
* }
|
|
25
|
-
*/
|
|
26
|
-
function getPermissionState() {
|
|
27
|
-
return Notification.permission;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Requests notification permission from the user.
|
|
31
|
-
* Shows browser permission dialog if not already granted/denied.
|
|
32
|
-
* @returns The resulting permission state
|
|
33
|
-
* @example
|
|
34
|
-
* const permission = await requestPermission();
|
|
35
|
-
* if (permission === 'granted') {
|
|
36
|
-
* await subscribeToPush(vapidKey);
|
|
37
|
-
* }
|
|
38
|
-
*/
|
|
39
|
-
async function requestPermission() {
|
|
40
|
-
const result = await Notification.requestPermission();
|
|
41
|
-
return result;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Checks if push notifications are supported in the current browser.
|
|
45
|
-
* Requires both Service Worker and Push API support.
|
|
46
|
-
* @returns True if push notifications are supported
|
|
47
|
-
* @example
|
|
48
|
-
* if (!isPushSupported()) {
|
|
49
|
-
* console.log('Push not supported on this browser');
|
|
50
|
-
* return;
|
|
51
|
-
* }
|
|
52
|
-
*/
|
|
53
|
-
function isPushSupported() {
|
|
54
|
-
return 'serviceWorker' in navigator && 'PushManager' in window;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Converts a browser PushSubscription to the simplified format for backend storage.
|
|
58
|
-
* Works in both main thread and service worker contexts.
|
|
59
|
-
* @param browserSub - The native browser PushSubscription object
|
|
60
|
-
* @returns A simplified PushSubscription with endpoint and keys
|
|
61
|
-
* @example
|
|
62
|
-
* const browserSub = await registration.pushManager.subscribe({ ... });
|
|
63
|
-
* const subscription = toPushSubscription(browserSub);
|
|
64
|
-
* await fetch('/api/subscribe', { body: JSON.stringify(subscription) });
|
|
65
|
-
*/
|
|
66
|
-
function toPushSubscription(browserSub) {
|
|
67
|
-
const json = browserSub.toJSON();
|
|
68
|
-
return {
|
|
69
|
-
endpoint: browserSub.endpoint,
|
|
70
|
-
keys: {
|
|
71
|
-
p256dh: json.keys?.p256dh || '',
|
|
72
|
-
auth: json.keys?.auth || ''
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Subscribes to push notifications and prepares a request for backend registration.
|
|
78
|
-
* Handles permission request, service worker subscription, and data persistence.
|
|
79
|
-
* @param vapidPublicKey - The VAPID public key from your server
|
|
80
|
-
* @param basePath - Optional base path for notification click handling (default: '/')
|
|
81
|
-
* @returns Result with subscription request on success, or error message on failure
|
|
82
|
-
* @example
|
|
83
|
-
* const result = await subscribeToPush(vapidPublicKey);
|
|
84
|
-
* if (result.ok) {
|
|
85
|
-
* await fetch('/api/push/subscribe', {
|
|
86
|
-
* method: 'POST',
|
|
87
|
-
* body: JSON.stringify(result.data)
|
|
88
|
-
* });
|
|
89
|
-
* }
|
|
90
|
-
*/
|
|
91
|
-
async function subscribeToPush(vapidPublicKey, basePath = '/') {
|
|
92
|
-
if (!isPushSupported()) {
|
|
93
|
-
return (0, types_1.err)('Push notifications not supported');
|
|
94
|
-
}
|
|
95
|
-
const permission = await requestPermission();
|
|
96
|
-
if (permission !== 'granted') {
|
|
97
|
-
return (0, types_1.err)('Push permission denied');
|
|
98
|
-
}
|
|
99
|
-
try {
|
|
100
|
-
const registration = await navigator.serviceWorker.ready;
|
|
101
|
-
const deviceId = (0, deviceId_1.getDeviceId)();
|
|
102
|
-
// Convert VAPID key to Uint8Array
|
|
103
|
-
const applicationServerKey = (0, encoding_1.urlBase64ToUint8Array)(vapidPublicKey);
|
|
104
|
-
const browserSub = await registration.pushManager.subscribe({
|
|
105
|
-
userVisibleOnly: true,
|
|
106
|
-
applicationServerKey
|
|
107
|
-
});
|
|
108
|
-
// Save data for service worker renewal
|
|
109
|
-
await (0, indexedDb_1.saveSubscriptionData)({
|
|
110
|
-
publicKey: vapidPublicKey,
|
|
111
|
-
deviceId,
|
|
112
|
-
basePath
|
|
113
|
-
});
|
|
114
|
-
return (0, types_1.ok)({
|
|
115
|
-
subscription: toPushSubscription(browserSub),
|
|
116
|
-
deviceId,
|
|
117
|
-
basePath
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
const message = error instanceof Error ? error.message : 'Subscription failed';
|
|
122
|
-
return (0, types_1.err)(message);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Unsubscribes from push notifications.
|
|
127
|
-
* Removes the browser push subscription and clears stored subscription data.
|
|
128
|
-
* @returns Result with ok=true on success, or error message on failure
|
|
129
|
-
* @example
|
|
130
|
-
* const result = await unsubscribeFromPush();
|
|
131
|
-
* if (result.ok) {
|
|
132
|
-
* await fetch('/api/push/unsubscribe', { method: 'POST' });
|
|
133
|
-
* }
|
|
134
|
-
*/
|
|
135
|
-
async function unsubscribeFromPush() {
|
|
136
|
-
try {
|
|
137
|
-
const registration = await navigator.serviceWorker.ready;
|
|
138
|
-
const subscription = await registration.pushManager.getSubscription();
|
|
139
|
-
if (subscription) {
|
|
140
|
-
await subscription.unsubscribe();
|
|
141
|
-
}
|
|
142
|
-
// Clear stored subscription data from IndexedDB
|
|
143
|
-
await (0, indexedDb_1.clearSubscriptionData)();
|
|
144
|
-
return (0, types_1.okVoid)();
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
const message = error instanceof Error ? error.message : 'Unsubscribe failed';
|
|
148
|
-
return (0, types_1.err)(message);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Gets the current push subscription if one exists.
|
|
153
|
-
* Useful for checking subscription status or syncing with backend.
|
|
154
|
-
* @returns Result with the current subscription, or error if not subscribed
|
|
155
|
-
* @example
|
|
156
|
-
* const result = await getCurrentSubscription();
|
|
157
|
-
* if (result.ok) {
|
|
158
|
-
* console.log('Endpoint:', result.data.endpoint);
|
|
159
|
-
* } else {
|
|
160
|
-
* console.log('Not subscribed:', result.error);
|
|
161
|
-
* }
|
|
162
|
-
*/
|
|
163
|
-
async function getCurrentSubscription() {
|
|
164
|
-
try {
|
|
165
|
-
const registration = await navigator.serviceWorker.ready;
|
|
166
|
-
const subscription = await registration.pushManager.getSubscription();
|
|
167
|
-
if (!subscription) {
|
|
168
|
-
return (0, types_1.err)('No active subscription');
|
|
169
|
-
}
|
|
170
|
-
return (0, types_1.ok)(toPushSubscription(subscription));
|
|
171
|
-
}
|
|
172
|
-
catch (error) {
|
|
173
|
-
const message = error instanceof Error ? error.message : 'Failed to get subscription';
|
|
174
|
-
return (0, types_1.err)(message);
|
|
175
|
-
}
|
|
176
|
-
}
|
package/dist/server/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { initPush, initPushFromEnv, getVapidPublicKey, sendPushNotification, sendPushToAll, sendPushWithDetails, isSubscriptionExpired } from './send';
|
package/dist/server/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isSubscriptionExpired = exports.sendPushWithDetails = exports.sendPushToAll = exports.sendPushNotification = exports.getVapidPublicKey = exports.initPushFromEnv = exports.initPush = void 0;
|
|
4
|
-
var send_1 = require("./send");
|
|
5
|
-
Object.defineProperty(exports, "initPush", { enumerable: true, get: function () { return send_1.initPush; } });
|
|
6
|
-
Object.defineProperty(exports, "initPushFromEnv", { enumerable: true, get: function () { return send_1.initPushFromEnv; } });
|
|
7
|
-
Object.defineProperty(exports, "getVapidPublicKey", { enumerable: true, get: function () { return send_1.getVapidPublicKey; } });
|
|
8
|
-
Object.defineProperty(exports, "sendPushNotification", { enumerable: true, get: function () { return send_1.sendPushNotification; } });
|
|
9
|
-
Object.defineProperty(exports, "sendPushToAll", { enumerable: true, get: function () { return send_1.sendPushToAll; } });
|
|
10
|
-
Object.defineProperty(exports, "sendPushWithDetails", { enumerable: true, get: function () { return send_1.sendPushWithDetails; } });
|
|
11
|
-
Object.defineProperty(exports, "isSubscriptionExpired", { enumerable: true, get: function () { return send_1.isSubscriptionExpired; } });
|
package/dist/types.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Push notification types - shared between server and client
|
|
3
|
-
*/
|
|
4
|
-
export { Result, ok, okVoid, err } from '@markwharton/pwa-core/types';
|
|
5
|
-
export interface PushSubscription {
|
|
6
|
-
endpoint: string;
|
|
7
|
-
keys: {
|
|
8
|
-
p256dh: string;
|
|
9
|
-
auth: string;
|
|
10
|
-
};
|
|
11
|
-
basePath?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface NotificationPayload {
|
|
14
|
-
title: string;
|
|
15
|
-
body: string;
|
|
16
|
-
type?: string;
|
|
17
|
-
url?: string;
|
|
18
|
-
tag?: string;
|
|
19
|
-
data?: Record<string, unknown>;
|
|
20
|
-
id?: string;
|
|
21
|
-
timestamp?: string;
|
|
22
|
-
basePath?: string;
|
|
23
|
-
}
|
|
24
|
-
export interface VapidConfig {
|
|
25
|
-
publicKey: string;
|
|
26
|
-
privateKey: string;
|
|
27
|
-
subject: string;
|
|
28
|
-
}
|
|
29
|
-
export interface SubscriptionRequest {
|
|
30
|
-
subscription: PushSubscription;
|
|
31
|
-
deviceId: string;
|
|
32
|
-
basePath?: string;
|
|
33
|
-
}
|
|
34
|
-
export interface SubscriptionData {
|
|
35
|
-
publicKey: string;
|
|
36
|
-
deviceId: string;
|
|
37
|
-
basePath: string;
|
|
38
|
-
}
|
|
39
|
-
export type PushPermissionState = 'granted' | 'denied' | 'default';
|
package/dist/types.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Push notification types - shared between server and client
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.err = exports.okVoid = exports.ok = void 0;
|
|
7
|
-
// Re-export Result from pwa-core for convenience
|
|
8
|
-
var types_1 = require("@markwharton/pwa-core/types");
|
|
9
|
-
Object.defineProperty(exports, "ok", { enumerable: true, get: function () { return types_1.ok; } });
|
|
10
|
-
Object.defineProperty(exports, "okVoid", { enumerable: true, get: function () { return types_1.okVoid; } });
|
|
11
|
-
Object.defineProperty(exports, "err", { enumerable: true, get: function () { return types_1.err; } });
|