@djangocfg/nextjs 2.1.35 → 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.
- package/README.md +146 -22
- package/dist/config/index.d.mts +7 -409
- package/dist/config/index.mjs +79 -394
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +79 -394
- package/dist/index.mjs.map +1 -1
- package/dist/plugin-DuRJ_Jq6.d.mts +100 -0
- package/dist/pwa/cli.d.mts +1 -0
- package/dist/pwa/cli.mjs +140 -0
- package/dist/pwa/cli.mjs.map +1 -0
- package/dist/pwa/index.d.mts +274 -0
- package/dist/pwa/index.mjs +327 -0
- package/dist/pwa/index.mjs.map +1 -0
- package/dist/pwa/server/index.d.mts +86 -0
- package/dist/pwa/server/index.mjs +175 -0
- package/dist/pwa/server/index.mjs.map +1 -0
- package/dist/pwa/server/routes.d.mts +2 -0
- package/dist/pwa/server/routes.mjs +149 -0
- package/dist/pwa/server/routes.mjs.map +1 -0
- package/dist/pwa/worker/index.d.mts +56 -0
- package/dist/pwa/worker/index.mjs +97 -0
- package/dist/pwa/worker/index.mjs.map +1 -0
- package/dist/routes-DXA29sS_.d.mts +68 -0
- package/package.json +38 -9
- package/src/config/createNextConfig.ts +9 -13
- package/src/config/index.ts +2 -19
- package/src/config/plugins/devStartup.ts +35 -36
- package/src/config/plugins/index.ts +1 -1
- package/src/config/utils/index.ts +0 -1
- package/src/index.ts +4 -0
- package/src/pwa/cli.ts +171 -0
- package/src/pwa/index.ts +9 -0
- package/src/pwa/manifest.ts +355 -0
- package/src/pwa/notifications.ts +192 -0
- package/src/pwa/plugin.ts +194 -0
- package/src/pwa/server/index.ts +23 -0
- package/src/pwa/server/push.ts +166 -0
- package/src/pwa/server/routes.ts +137 -0
- package/src/pwa/worker/index.ts +174 -0
- package/src/pwa/worker/package.json +3 -0
- package/bin/dev-with-browser.js +0 -114
- package/src/config/plugins/pwa.ts +0 -616
- package/src/config/utils/manifest.ts +0 -195
|
@@ -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
|
+
}
|
package/bin/dev-with-browser.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Next.js Dev Server with Auto Browser Opening
|
|
4
|
-
*
|
|
5
|
-
* Cross-platform solution that works with both Turbopack and webpack
|
|
6
|
-
* Opens browser automatically when server is ready
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* "dev": "dev-with-browser"
|
|
10
|
-
* "dev": "dev-with-browser --port 3000"
|
|
11
|
-
* "dev": "dev-with-browser --webpack"
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const { spawn } = require('child_process');
|
|
15
|
-
const { exec } = require('child_process');
|
|
16
|
-
const consola = require('consola');
|
|
17
|
-
|
|
18
|
-
// Parse arguments
|
|
19
|
-
const args = process.argv.slice(2);
|
|
20
|
-
|
|
21
|
-
// Extract port
|
|
22
|
-
let PORT = process.env.PORT || '3000';
|
|
23
|
-
const portIndex = args.findIndex(arg => arg === '-p' || arg === '--port');
|
|
24
|
-
if (portIndex !== -1 && args[portIndex + 1]) {
|
|
25
|
-
PORT = args[portIndex + 1];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Build next dev command
|
|
29
|
-
const nextArgs = ['dev', '-p', PORT];
|
|
30
|
-
|
|
31
|
-
// Check if --webpack flag is present
|
|
32
|
-
const hasWebpackFlag = args.includes('--webpack');
|
|
33
|
-
|
|
34
|
-
// Add --turbopack by default (unless --webpack is specified)
|
|
35
|
-
// This silences the "webpack config with no turbopack config" warning
|
|
36
|
-
if (!hasWebpackFlag) {
|
|
37
|
-
nextArgs.push('--turbopack');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Pass through other flags, excluding port arguments
|
|
41
|
-
args.forEach((arg, i) => {
|
|
42
|
-
const isPreviousPort = i > 0 && (args[i - 1] === '-p' || args[i - 1] === '--port');
|
|
43
|
-
const isPortFlag = arg === '-p' || arg === '--port';
|
|
44
|
-
|
|
45
|
-
if (!isPortFlag && !isPreviousPort) {
|
|
46
|
-
nextArgs.push(arg);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const URL = `http://localhost:${PORT}`;
|
|
51
|
-
|
|
52
|
-
consola.info(`Starting Next.js dev server on port ${PORT}...`);
|
|
53
|
-
|
|
54
|
-
// Start Next.js dev server
|
|
55
|
-
const devServer = spawn('next', nextArgs, {
|
|
56
|
-
stdio: 'inherit',
|
|
57
|
-
shell: true,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Wait for server to be ready, then open browser
|
|
61
|
-
let serverReady = false;
|
|
62
|
-
let attempts = 0;
|
|
63
|
-
const maxAttempts = 60; // 30 seconds max
|
|
64
|
-
|
|
65
|
-
const checkInterval = setInterval(async () => {
|
|
66
|
-
if (serverReady || attempts >= maxAttempts) {
|
|
67
|
-
if (attempts >= maxAttempts) {
|
|
68
|
-
consola.warn('Server took too long to start, skipping browser open');
|
|
69
|
-
}
|
|
70
|
-
clearInterval(checkInterval);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
attempts++;
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const response = await fetch(URL);
|
|
78
|
-
if (response.ok) {
|
|
79
|
-
serverReady = true;
|
|
80
|
-
clearInterval(checkInterval);
|
|
81
|
-
|
|
82
|
-
consola.success(`Server ready! Opening browser at ${URL}`);
|
|
83
|
-
|
|
84
|
-
// Open browser (cross-platform)
|
|
85
|
-
const command = process.platform === 'darwin'
|
|
86
|
-
? 'open'
|
|
87
|
-
: process.platform === 'win32'
|
|
88
|
-
? 'start'
|
|
89
|
-
: 'xdg-open';
|
|
90
|
-
|
|
91
|
-
exec(`${command} ${URL}`, (error) => {
|
|
92
|
-
if (error) {
|
|
93
|
-
consola.warn(`Failed to open browser: ${error.message}`);
|
|
94
|
-
consola.info(`Please open manually: ${URL}`);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
} catch (err) {
|
|
99
|
-
// Server not ready yet, continue checking
|
|
100
|
-
}
|
|
101
|
-
}, 500);
|
|
102
|
-
|
|
103
|
-
// Cleanup on exit
|
|
104
|
-
process.on('SIGINT', () => {
|
|
105
|
-
clearInterval(checkInterval);
|
|
106
|
-
devServer.kill();
|
|
107
|
-
process.exit();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
process.on('SIGTERM', () => {
|
|
111
|
-
clearInterval(checkInterval);
|
|
112
|
-
devServer.kill();
|
|
113
|
-
process.exit();
|
|
114
|
-
});
|