diff --git a/README.md b/README.md index 091f99a..eb84e40 100644 --- a/README.md +++ b/README.md @@ -192,3 +192,7 @@ export const after = (configuration) => { return configuration } ``` + +## Deployment + +To deploy a papua to **Vercel** import the repository and ensure `Other Frameworks` is selected as the preset. Then override the build command with `npx papua build` and set the output folder to `dist`. diff --git a/package.json b/package.json index 985a6eb..69ca078 100644 --- a/package.json +++ b/package.json @@ -29,23 +29,23 @@ } }, "dependencies": { - "@babel/core": "^7.22.10", - "@babel/eslint-parser": "^7.22.10", - "@babel/preset-env": "^7.22.10", - "@babel/preset-react": "^7.22.5", + "@babel/core": "^7.22.17", + "@babel/eslint-parser": "^7.22.15", + "@babel/preset-env": "^7.22.15", + "@babel/preset-react": "^7.22.15", "@manypkg/find-root": "^2.2.1", "@npmcli/map-workspaces": "^3.0.4", - "@rspack/core": "^0.2.12", - "@rspack/dev-server": "^0.2.12", - "@typescript-eslint/eslint-plugin": "^6.4.0", - "@typescript-eslint/parser": "^6.4.0", + "@rspack/core": "^0.3.2", + "@rspack/dev-server": "^0.3.2", + "@typescript-eslint/eslint-plugin": "^6.6.0", + "@typescript-eslint/parser": "^6.6.0", "ajv": "^8.12.0", "chalk": "^5.3.0", "commander": "^11.0.0", "css-loader": "^6.8.1", "deepmerge-ts": "^5.1.0", "ejs": "^3.1.9", - "eslint": "^8.47.0", + "eslint": "^8.49.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.0.0", @@ -64,14 +64,14 @@ "inject-manifest-plugin": "^0.3.3", "lodash.isplainobject": "^4.0.6", "logua": "^2.3.0", - "node-html-parser": "^6.1.6", + "node-html-parser": "^6.1.8", "open": "^9.1.0", "p-each-series": "^3.0.0", - "pakag": "^3.0.0", + "pakag": "^3.1.1", "parse-gitignore": "^2.0.0", "postcss-styled": "^0.34.0", "postcss-syntax": "^0.36.2", - "prettier": "^3.0.2", + "prettier": "^3.0.3", "pretty-bytes": "^6.1.1", "pretty-ms": "^8.0.0", "prompts": "^2.4.2", @@ -80,9 +80,19 @@ "style-loader": "^3.3.3", "stylelint": "^15.10.3", "stylelint-config-recommended": "^13.0.0", - "typescript": "^5.1.6", + "typescript": "^5.2.2", "url-join": "^5.0.0" }, + "devDependencies": { + "@types/node": "^20.6.0", + "@types/serve-handler": "^6.1.1", + "cypress": "^13.1.0", + "jest-fixture": "^4.1.0", + "padua": "^2.0.3", + "react": "^18.2.0", + "tcp-port-used": "^1.0.2", + "vitest": "^0.34.4" + }, "peerDependencies": { "vitest": ">= 0.30" }, @@ -107,16 +117,6 @@ "lint", "configuration" ], - "devDependencies": { - "@types/node": "^20.5.1", - "@types/serve-handler": "^6.1.1", - "cypress": "^12.17.4", - "jest-fixture": "^4.1.0", - "padua": "^2.0.1", - "react": "^18.2.0", - "tcp-port-used": "^1.0.2", - "vitest": "^0.34.2" - }, "prettier": "padua/configuration/.prettierrc.json", "eslintConfig": { "extends": "./node_modules/padua/configuration/eslint.cjs" diff --git a/template/default/package.json b/template/default/package.json index 415ec82..638011e 100644 --- a/template/default/package.json +++ b/template/default/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@types/react": "^18.2.16", + "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "papua": "latest", "react": "^18.2.0", diff --git a/template/pwa/background/registration.ts b/template/pwa/background/registration.ts index 8e0c0ed..769cdf2 100644 --- a/template/pwa/background/registration.ts +++ b/template/pwa/background/registration.ts @@ -76,6 +76,10 @@ export function register() { registerValidSW(swUrl) } }) + } else if (!('serviceWorker' in navigator)) { + Todo.setError('Service Worker feature not available.') + } else { + Todo.setReady('local') } } diff --git a/template/pwa/data/todo.ts b/template/pwa/data/todo.ts index dbf4c7d..0402632 100644 --- a/template/pwa/data/todo.ts +++ b/template/pwa/data/todo.ts @@ -20,7 +20,7 @@ const TodosStore = class { updateAvailable = false // If true PWA assets will be updated upon reload. offline = !window.navigator.onLine // true when PWA running on cached assets. error: boolean | string = false // true when PWA registration errored. - ready = false // true when Service Worker is ready. + ready: boolean | 'local' = false // true when Service Worker is ready. constructor() { makeAutoObservable(this) @@ -80,12 +80,12 @@ const TodosStore = class { this.offline = true } - setError(error = true) { + setError(error: boolean | string = true) { this.error = error } - setReady() { - this.ready = true + setReady(value: boolean | 'local' = true) { + this.ready = value } } diff --git a/template/pwa/markup/Status.tsx b/template/pwa/markup/Status.tsx index 63f2b96..152cae3 100644 --- a/template/pwa/markup/Status.tsx +++ b/template/pwa/markup/Status.tsx @@ -16,10 +16,22 @@ const badgeStyles = (error = false): CSSProperties => ({ whiteSpace: 'nowrap', }) +const getReadyState = (ready: boolean | 'local') => { + if (!ready) { + return 'installing' + } + + if (ready === 'local') { + return 'development (not installed)' + } + + return 'ready' +} + export const Status = observer(() => (
{Todo.offline ? 'offline' : 'online'} - {!Todo.ready ? 'installing' : 'ready'} + {getReadyState(Todo.ready)} {Todo.updateAvailable ? 'update available' : 'up-to-date'} diff --git a/template/pwa/package.json b/template/pwa/package.json index 9412a6b..19e99b3 100644 --- a/template/pwa/package.json +++ b/template/pwa/package.json @@ -4,12 +4,12 @@ "title": "Progressive Web App" }, "dependencies": { - "@types/react": "^18.2.16", + "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "@types/url-join": "^4.0.1", - "mobx": "^6.10.0", - "mobx-react-lite": "^4.0.3", - "papua": "^5.6.0", + "mobx": "^6.10.2", + "mobx-react-lite": "^4.0.4", + "papua": "^5.6.2", "react": "^18.2.0", "react-dom": "^18.2.0", "url-join": "^5.0.0", diff --git a/template/pwa/service-worker.ts b/template/pwa/service-worker.ts index a716fe5..5b3dc51 100644 --- a/template/pwa/service-worker.ts +++ b/template/pwa/service-worker.ts @@ -5,16 +5,17 @@ import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies' import join from 'url-join' -clientsClaim() +clientsClaim() // Allows updating open service workers. -// Otherwise TS error for missing variable. +// Add types for the plugin and workbox. declare global { interface Window { - INJECT_MANIFEST_PLUGIN: any - skipWaiting: any + INJECT_MANIFEST_PLUGIN: { url: string; revision: string }[] + skipWaiting: Function } } +// Add all assets generated during build to the browser cache. precacheAndRoute(self.INJECT_MANIFEST_PLUGIN) const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$') @@ -54,8 +55,7 @@ registerRoute( }) ) -// This allows the web app to trigger skipWaiting via -// registration.waiting.postMessage({type: 'SKIP_WAITING'}) +// Update cached assets after reload without the need for the user to close all open tabs. self.addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') { self.skipWaiting() diff --git a/template/serverless/package.json b/template/serverless/package.json index 66a41b8..a61b064 100644 --- a/template/serverless/package.json +++ b/template/serverless/package.json @@ -13,6 +13,6 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "vercel": "^31.1.0" + "vercel": "^32.2.0" } } diff --git a/template/website/package.json b/template/website/package.json index cf1e556..1c58577 100644 --- a/template/website/package.json +++ b/template/website/package.json @@ -1,10 +1,10 @@ { "dependencies": { "@stitches/react": "^1.2.8", - "@types/react": "^18.2.16", + "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", - "mobx": "^6.10.0", - "mobx-react-lite": "^4.0.3", + "mobx": "^6.10.2", + "mobx-react-lite": "^4.0.4", "papua": "latest", "react": "^18.2.0", "react-dom": "^18.2.0"