@djangocfg/nextjs 2.1.36 → 2.1.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +146 -1
  2. package/dist/config/index.d.mts +7 -428
  3. package/dist/config/index.mjs +80 -396
  4. package/dist/config/index.mjs.map +1 -1
  5. package/dist/index.d.mts +2 -1
  6. package/dist/index.mjs +80 -396
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/plugin-DuRJ_Jq6.d.mts +100 -0
  9. package/dist/pwa/cli.d.mts +1 -0
  10. package/dist/pwa/cli.mjs +140 -0
  11. package/dist/pwa/cli.mjs.map +1 -0
  12. package/dist/pwa/index.d.mts +274 -0
  13. package/dist/pwa/index.mjs +327 -0
  14. package/dist/pwa/index.mjs.map +1 -0
  15. package/dist/pwa/server/index.d.mts +86 -0
  16. package/dist/pwa/server/index.mjs +175 -0
  17. package/dist/pwa/server/index.mjs.map +1 -0
  18. package/dist/pwa/server/routes.d.mts +2 -0
  19. package/dist/pwa/server/routes.mjs +149 -0
  20. package/dist/pwa/server/routes.mjs.map +1 -0
  21. package/dist/pwa/worker/index.d.mts +56 -0
  22. package/dist/pwa/worker/index.mjs +97 -0
  23. package/dist/pwa/worker/index.mjs.map +1 -0
  24. package/dist/routes-DXA29sS_.d.mts +68 -0
  25. package/package.json +39 -8
  26. package/src/config/createNextConfig.ts +9 -13
  27. package/src/config/index.ts +2 -20
  28. package/src/config/plugins/devStartup.ts +35 -36
  29. package/src/config/plugins/index.ts +1 -1
  30. package/src/config/utils/index.ts +0 -1
  31. package/src/index.ts +4 -0
  32. package/src/pwa/cli.ts +171 -0
  33. package/src/pwa/index.ts +9 -0
  34. package/src/pwa/manifest.ts +355 -0
  35. package/src/pwa/notifications.ts +192 -0
  36. package/src/pwa/plugin.ts +194 -0
  37. package/src/pwa/server/index.ts +23 -0
  38. package/src/pwa/server/push.ts +166 -0
  39. package/src/pwa/server/routes.ts +137 -0
  40. package/src/pwa/worker/index.ts +174 -0
  41. package/src/pwa/worker/package.json +3 -0
  42. package/src/config/plugins/pwa.ts +0 -616
  43. package/src/config/utils/manifest.ts +0 -214
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Service Worker Utilities
3
+ *
4
+ * Ready-to-use Serwist configuration for Next.js PWA
5
+ */
6
+
7
+ /// <reference lib="webworker" />
8
+
9
+ import { defaultCache } from '@serwist/next/worker';
10
+ import { Serwist } from 'serwist';
11
+
12
+ export interface ServiceWorkerOptions {
13
+ /**
14
+ * Offline fallback URL
15
+ * @default '/_offline'
16
+ */
17
+ offlineFallback?: string;
18
+
19
+ /**
20
+ * Skip waiting - activate new SW immediately
21
+ * @default true
22
+ */
23
+ skipWaiting?: boolean;
24
+
25
+ /**
26
+ * Take control of all clients immediately
27
+ * @default true
28
+ */
29
+ clientsClaim?: boolean;
30
+
31
+ /**
32
+ * Enable navigation preload for faster loads
33
+ * @default true
34
+ */
35
+ navigationPreload?: boolean;
36
+
37
+ /**
38
+ * Enable push notifications
39
+ * @default false
40
+ */
41
+ enablePushNotifications?: boolean;
42
+
43
+ /**
44
+ * Default notification icon
45
+ */
46
+ notificationIcon?: string;
47
+
48
+ /**
49
+ * Default notification badge
50
+ */
51
+ notificationBadge?: string;
52
+ }
53
+
54
+ /**
55
+ * Create and initialize Serwist service worker
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * // app/sw.ts
60
+ * import { createServiceWorker } from '@djangocfg/nextjs/worker';
61
+ *
62
+ * createServiceWorker({
63
+ * offlineFallback: '/_offline',
64
+ * });
65
+ * ```
66
+ */
67
+ export function createServiceWorker(options: ServiceWorkerOptions = {}) {
68
+ const {
69
+ offlineFallback = '/_offline',
70
+ skipWaiting = true,
71
+ clientsClaim = true,
72
+ navigationPreload = true,
73
+ enablePushNotifications = false,
74
+ notificationIcon,
75
+ notificationBadge,
76
+ } = options;
77
+
78
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
+ const self = globalThis as any;
80
+ console.log('SW: Worker Initialized 🚀');
81
+
82
+ const serwist = new Serwist({
83
+ // Precache entries injected by Serwist build plugin
84
+ precacheEntries: self.__SW_MANIFEST,
85
+
86
+ // Skip waiting - activate new SW immediately
87
+ skipWaiting,
88
+
89
+ // Take control of all clients immediately
90
+ clientsClaim,
91
+
92
+ // Enable navigation preload for faster loads
93
+ navigationPreload,
94
+
95
+ // Use default Next.js runtime caching strategies
96
+ runtimeCaching: defaultCache,
97
+
98
+ // Fallback pages for offline
99
+ fallbacks: {
100
+ entries: [
101
+ {
102
+ url: offlineFallback,
103
+ matcher({ request }) {
104
+ return request.destination === 'document';
105
+ },
106
+ },
107
+ ],
108
+ },
109
+ });
110
+
111
+ serwist.addEventListeners();
112
+
113
+ // Push notification support
114
+ if (enablePushNotifications) {
115
+ // Handle push events
116
+ self.addEventListener('push', (event: PushEvent) => {
117
+ let data;
118
+ try {
119
+ data = event.data?.json() || {};
120
+ console.log('SW: Push Received (JSON)', data);
121
+ } catch (err) {
122
+ console.log('SW: Push Received (Raw)', event.data?.text());
123
+ data = {};
124
+ }
125
+
126
+ const {
127
+ title = 'Notification',
128
+ body = '',
129
+ icon = notificationIcon,
130
+ badge = notificationBadge,
131
+ data: notificationData = {},
132
+ tag,
133
+ requireInteraction = false,
134
+ vibrate = [200, 100, 200], // Default vibration pattern
135
+ silent = false, // Default to playing sound
136
+ } = data;
137
+
138
+ event.waitUntil(
139
+ self.registration.showNotification(title, {
140
+ body,
141
+ icon,
142
+ badge,
143
+ data: notificationData,
144
+ tag,
145
+ requireInteraction,
146
+ vibrate,
147
+ silent,
148
+ })
149
+ );
150
+ });
151
+
152
+ // Handle notification clicks
153
+ self.addEventListener('notificationclick', (event: NotificationEvent) => {
154
+ event.notification.close();
155
+
156
+ const urlToOpen = event.notification.data?.url || '/';
157
+
158
+ event.waitUntil(
159
+ self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList: readonly WindowClient[]) => {
160
+ // Check if there's already a window open with the URL
161
+ for (const client of clientList) {
162
+ if (client.url === urlToOpen && 'focus' in client) {
163
+ return client.focus();
164
+ }
165
+ }
166
+ // If not, open a new window
167
+ if (self.clients.openWindow) {
168
+ return self.clients.openWindow(urlToOpen);
169
+ }
170
+ })
171
+ );
172
+ });
173
+ }
174
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }