@vite-pwa/nuxt 0.1.2 → 0.2.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/configuration.d.ts +5 -0
- package/dist/module.d.ts +1 -25
- package/dist/module.json +1 -1
- package/dist/module.mjs +32 -9
- package/dist/runtime/plugins/pwa.client.d.ts +2 -0
- package/dist/runtime/plugins/pwa.client.mjs +112 -0
- package/dist/runtime/plugins/pwa.client.stub.d.ts +2 -0
- package/dist/runtime/plugins/pwa.client.stub.mjs +8 -0
- package/dist/runtime/plugins/types.d.ts +14 -0
- package/dist/runtime/plugins/types.mjs +0 -0
- package/dist/types.d.ts +1 -1
- package/package.json +20 -9
- package/templates/pwa.client.ts +0 -136
- /package/dist/runtime/{VitePwaManifest.d.ts → components/VitePwaManifest.d.ts} +0 -0
- /package/dist/runtime/{VitePwaManifest.mjs → components/VitePwaManifest.mjs} +0 -0
package/dist/module.d.ts
CHANGED
|
@@ -1,30 +1,6 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
2
|
import { VitePWAOptions } from 'vite-plugin-pwa';
|
|
3
|
-
import { UnwrapNestedRefs, Ref } from 'vue';
|
|
4
3
|
|
|
5
|
-
interface PwaInjection {
|
|
6
|
-
isInstalled: boolean;
|
|
7
|
-
showInstallPrompt: Ref<boolean>;
|
|
8
|
-
cancelInstall: () => void;
|
|
9
|
-
install: () => Promise<void>;
|
|
10
|
-
swActivated: Ref<boolean>;
|
|
11
|
-
registrationError: Ref<boolean>;
|
|
12
|
-
offlineReady: Ref<boolean>;
|
|
13
|
-
needRefresh: Ref<boolean>;
|
|
14
|
-
updateServiceWorker: (reloadPage?: boolean | undefined) => Promise<void>;
|
|
15
|
-
cancelPrompt: () => Promise<void>;
|
|
16
|
-
getSWRegistration: () => ServiceWorkerRegistration | undefined;
|
|
17
|
-
}
|
|
18
|
-
declare module '#app/nuxt' {
|
|
19
|
-
interface NuxtApp {
|
|
20
|
-
$pwa: UnwrapNestedRefs<PwaInjection>;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
declare module '@vue/runtime-core' {
|
|
24
|
-
interface ComponentCustomProperties {
|
|
25
|
-
$pwa: UnwrapNestedRefs<PwaInjection>;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
4
|
interface ClientOptions {
|
|
29
5
|
/**
|
|
30
6
|
* Exposes the plugin: defaults to true.
|
|
@@ -59,4 +35,4 @@ interface ModuleOptions extends Partial<VitePWAOptions> {
|
|
|
59
35
|
|
|
60
36
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
|
|
61
37
|
|
|
62
|
-
export { ClientOptions, ModuleOptions,
|
|
38
|
+
export { ClientOptions, ModuleOptions, _default as default };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { writeFile, mkdir } from 'node:fs/promises';
|
|
3
|
-
import { defineNuxtModule, createResolver,
|
|
3
|
+
import { defineNuxtModule, createResolver, addPlugin, addComponent, extendWebpackConfig } from '@nuxt/kit';
|
|
4
4
|
import { VitePWA } from 'vite-plugin-pwa';
|
|
5
5
|
import { resolve } from 'pathe';
|
|
6
6
|
|
|
@@ -85,21 +85,26 @@ const module = defineNuxtModule({
|
|
|
85
85
|
return vitePwaClientPlugin?.api;
|
|
86
86
|
};
|
|
87
87
|
const client = options.client ?? { registerPlugin: true, installPrompt: false, periodicSyncForUpdates: 0 };
|
|
88
|
+
const runtimeDir = resolver.resolve("./runtime");
|
|
89
|
+
if (!nuxt.options.ssr)
|
|
90
|
+
nuxt.options.build.transpile.push(runtimeDir);
|
|
88
91
|
if (client.registerPlugin) {
|
|
89
|
-
|
|
90
|
-
src: resolver.resolve("
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
addPlugin({
|
|
93
|
+
src: resolver.resolve(runtimeDir, "plugins/pwa.client"),
|
|
94
|
+
mode: "client"
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
addPlugin({
|
|
98
|
+
src: resolver.resolve(runtimeDir, "plugins/pwa.client.stub"),
|
|
99
|
+
mode: "client"
|
|
96
100
|
});
|
|
97
101
|
}
|
|
98
102
|
await addComponent({
|
|
99
103
|
name: "VitePwaManifest",
|
|
100
|
-
filePath: resolver.resolve("
|
|
104
|
+
filePath: resolver.resolve(runtimeDir, "components/VitePwaManifest")
|
|
101
105
|
});
|
|
102
106
|
nuxt.hook("prepare:types", ({ references }) => {
|
|
107
|
+
references.push({ types: "@vite-pwa/nuxt/configuration" });
|
|
103
108
|
references.push({ types: "vite-plugin-pwa/vue" });
|
|
104
109
|
references.push({ types: "vite-plugin-pwa/info" });
|
|
105
110
|
});
|
|
@@ -123,6 +128,8 @@ const module = defineNuxtModule({
|
|
|
123
128
|
if (plugin)
|
|
124
129
|
throw new Error("Remove vite-plugin-pwa plugin from Vite Plugins entry in Nuxt config file!");
|
|
125
130
|
if (options.manifest && isClient) {
|
|
131
|
+
const configuration = "virtual:nuxt-pwa-configuration";
|
|
132
|
+
const resolvedConfiguration = `\0${configuration}`;
|
|
126
133
|
viteInlineConfig.plugins.push({
|
|
127
134
|
name: "vite-pwa-nuxt:webmanifest:build",
|
|
128
135
|
apply: "build",
|
|
@@ -135,6 +142,22 @@ const module = defineNuxtModule({
|
|
|
135
142
|
await writeWebManifest(manifestDir, options.manifestFilename || "manifest.webmanifest", api);
|
|
136
143
|
}
|
|
137
144
|
}
|
|
145
|
+
}, {
|
|
146
|
+
name: "vite-pwa-nuxt:configuration",
|
|
147
|
+
enforce: "pre",
|
|
148
|
+
resolveId(id) {
|
|
149
|
+
if (id === configuration)
|
|
150
|
+
return resolvedConfiguration;
|
|
151
|
+
},
|
|
152
|
+
load(id) {
|
|
153
|
+
if (id === resolvedConfiguration) {
|
|
154
|
+
const installPrompt = typeof client.installPrompt === "undefined" || client.installPrompt === false ? void 0 : client.installPrompt === true || client.installPrompt.trim() === "" ? "vite-pwa:hide-install" : client.installPrompt.trim();
|
|
155
|
+
return `export const enabled = ${client.registerPlugin}
|
|
156
|
+
export const installPrompt = ${JSON.stringify(installPrompt)}
|
|
157
|
+
export const periodicSyncForUpdates = ${typeof client.periodicSyncForUpdates === "number" ? client.periodicSyncForUpdates : 0}
|
|
158
|
+
`;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
138
161
|
});
|
|
139
162
|
}
|
|
140
163
|
const plugins = [...VitePWA(options).filter((p) => p.name !== "vite-plugin-pwa:build")];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { nextTick, reactive, ref } from "vue";
|
|
2
|
+
import { useRegisterSW } from "virtual:pwa-register/vue";
|
|
3
|
+
import { installPrompt, periodicSyncForUpdates } from "virtual:nuxt-pwa-configuration";
|
|
4
|
+
import { defineNuxtPlugin } from "#imports";
|
|
5
|
+
export default defineNuxtPlugin(() => {
|
|
6
|
+
const registrationError = ref(false);
|
|
7
|
+
const swActivated = ref(false);
|
|
8
|
+
const showInstallPrompt = ref(false);
|
|
9
|
+
const hideInstall = ref(!installPrompt ? true : localStorage.getItem(installPrompt) === "true");
|
|
10
|
+
const ua = navigator.userAgent;
|
|
11
|
+
const ios = ua.match(/iPhone|iPad|iPod/);
|
|
12
|
+
const standalone = window.matchMedia("(display-mode: standalone)").matches;
|
|
13
|
+
const isInstalled = !!(standalone || ios && !ua.match(/Safari/));
|
|
14
|
+
let swRegistration;
|
|
15
|
+
const getSWRegistration = () => swRegistration;
|
|
16
|
+
const registerPeriodicSync = (swUrl, r, timeout) => {
|
|
17
|
+
setInterval(async () => {
|
|
18
|
+
if ("connection" in navigator && !navigator.onLine)
|
|
19
|
+
return;
|
|
20
|
+
const resp = await fetch(swUrl, {
|
|
21
|
+
cache: "no-store",
|
|
22
|
+
headers: {
|
|
23
|
+
"cache": "no-store",
|
|
24
|
+
"cache-control": "no-cache"
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
if (resp?.status === 200)
|
|
28
|
+
await r.update();
|
|
29
|
+
}, timeout);
|
|
30
|
+
};
|
|
31
|
+
const {
|
|
32
|
+
offlineReady,
|
|
33
|
+
needRefresh,
|
|
34
|
+
updateServiceWorker
|
|
35
|
+
} = useRegisterSW({
|
|
36
|
+
immediate: true,
|
|
37
|
+
onRegisterError() {
|
|
38
|
+
registrationError.value = true;
|
|
39
|
+
},
|
|
40
|
+
onRegisteredSW(swUrl, r) {
|
|
41
|
+
swRegistration = r;
|
|
42
|
+
const timeout = periodicSyncForUpdates;
|
|
43
|
+
if (timeout > 0) {
|
|
44
|
+
if (r?.active?.state === "activated") {
|
|
45
|
+
swActivated.value = true;
|
|
46
|
+
registerPeriodicSync(swUrl, r, timeout * 1e3);
|
|
47
|
+
} else if (r?.installing) {
|
|
48
|
+
r.installing.addEventListener("statechange", (e) => {
|
|
49
|
+
const sw = e.target;
|
|
50
|
+
swActivated.value = sw.state === "activated";
|
|
51
|
+
if (swActivated.value)
|
|
52
|
+
registerPeriodicSync(swUrl, r, timeout * 1e3);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const cancelPrompt = async () => {
|
|
59
|
+
offlineReady.value = false;
|
|
60
|
+
needRefresh.value = false;
|
|
61
|
+
};
|
|
62
|
+
let install = () => Promise.resolve();
|
|
63
|
+
let cancelInstall = () => {
|
|
64
|
+
};
|
|
65
|
+
if (!hideInstall.value) {
|
|
66
|
+
let deferredPrompt;
|
|
67
|
+
const beforeInstallPrompt = (e) => {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
deferredPrompt = e;
|
|
70
|
+
showInstallPrompt.value = true;
|
|
71
|
+
};
|
|
72
|
+
window.addEventListener("beforeinstallprompt", beforeInstallPrompt);
|
|
73
|
+
window.addEventListener("appinstalled", () => {
|
|
74
|
+
deferredPrompt = void 0;
|
|
75
|
+
showInstallPrompt.value = false;
|
|
76
|
+
});
|
|
77
|
+
cancelInstall = () => {
|
|
78
|
+
deferredPrompt = void 0;
|
|
79
|
+
showInstallPrompt.value = false;
|
|
80
|
+
window.removeEventListener("beforeinstallprompt", beforeInstallPrompt);
|
|
81
|
+
hideInstall.value = true;
|
|
82
|
+
localStorage.setItem(installPrompt, "true");
|
|
83
|
+
};
|
|
84
|
+
install = async () => {
|
|
85
|
+
if (!showInstallPrompt.value || !deferredPrompt) {
|
|
86
|
+
showInstallPrompt.value = false;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
showInstallPrompt.value = false;
|
|
90
|
+
await nextTick();
|
|
91
|
+
deferredPrompt.prompt();
|
|
92
|
+
await deferredPrompt.userChoice;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
provide: {
|
|
97
|
+
pwa: reactive({
|
|
98
|
+
isInstalled,
|
|
99
|
+
showInstallPrompt,
|
|
100
|
+
cancelInstall,
|
|
101
|
+
install,
|
|
102
|
+
swActivated,
|
|
103
|
+
registrationError,
|
|
104
|
+
offlineReady,
|
|
105
|
+
needRefresh,
|
|
106
|
+
updateServiceWorker,
|
|
107
|
+
cancelPrompt,
|
|
108
|
+
getSWRegistration
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
export interface PwaInjection {
|
|
3
|
+
isInstalled: boolean;
|
|
4
|
+
showInstallPrompt: Ref<boolean>;
|
|
5
|
+
cancelInstall: () => void;
|
|
6
|
+
install: () => Promise<void>;
|
|
7
|
+
swActivated: Ref<boolean>;
|
|
8
|
+
registrationError: Ref<boolean>;
|
|
9
|
+
offlineReady: Ref<boolean>;
|
|
10
|
+
needRefresh: Ref<boolean>;
|
|
11
|
+
updateServiceWorker: (reloadPage?: boolean | undefined) => Promise<void>;
|
|
12
|
+
cancelPrompt: () => Promise<void>;
|
|
13
|
+
getSWRegistration: () => ServiceWorkerRegistration | undefined;
|
|
14
|
+
}
|
|
File without changes
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vite-pwa/nuxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"packageManager": "pnpm@8.10.2",
|
|
6
6
|
"description": "Zero-config PWA for Nuxt 3",
|
|
7
7
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
@@ -23,15 +23,18 @@
|
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
25
|
"types": "./dist/types.d.ts",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
26
|
+
"import": "./dist/module.mjs",
|
|
27
|
+
"require": "./dist/module.cjs"
|
|
28
|
+
},
|
|
29
|
+
"./configuration": {
|
|
30
|
+
"types": "./configuration.d.ts"
|
|
28
31
|
}
|
|
29
32
|
},
|
|
30
33
|
"main": "./dist/module.cjs",
|
|
31
34
|
"types": "./dist/types.d.ts",
|
|
32
35
|
"files": [
|
|
33
36
|
"dist",
|
|
34
|
-
"
|
|
37
|
+
"*.d.ts"
|
|
35
38
|
],
|
|
36
39
|
"scripts": {
|
|
37
40
|
"prepack": "nuxt-module-build prepare && nuxt-module-build",
|
|
@@ -54,23 +57,27 @@
|
|
|
54
57
|
"test:with-build": "nr dev:prepare && nr prepack && nr test"
|
|
55
58
|
},
|
|
56
59
|
"peerDependencies": {
|
|
57
|
-
"@nuxt/kit": "^3.
|
|
60
|
+
"@nuxt/kit": "^3.6.2",
|
|
58
61
|
"vite-plugin-pwa": ">=0.16.5 <1"
|
|
59
62
|
},
|
|
60
63
|
"dependencies": {
|
|
61
|
-
"@nuxt/kit": "^3.
|
|
64
|
+
"@nuxt/kit": "^3.6.2",
|
|
65
|
+
"pathe": "^1.1.1",
|
|
66
|
+
"ufo": "^1.3.1",
|
|
62
67
|
"vite-plugin-pwa": ">=0.16.5 <1"
|
|
63
68
|
},
|
|
64
69
|
"devDependencies": {
|
|
65
70
|
"@antfu/eslint-config": "^0.41.0",
|
|
66
71
|
"@antfu/ni": "^0.21.8",
|
|
67
72
|
"@nuxt/module-builder": "^0.4.0",
|
|
68
|
-
"@nuxt/schema": "^3.5
|
|
73
|
+
"@nuxt/schema": "^3.6.5",
|
|
69
74
|
"@nuxt/test-utils": "^3.5.3",
|
|
70
75
|
"@playwright/test": "^1.37.1",
|
|
76
|
+
"@types/node": "^18",
|
|
71
77
|
"bumpp": "^9.2.0",
|
|
72
78
|
"eslint": "^8.49.0",
|
|
73
|
-
"
|
|
79
|
+
"node-fetch-native": "^1.4.1",
|
|
80
|
+
"nuxt": "^3.6.5",
|
|
74
81
|
"serve": "^14.2.1",
|
|
75
82
|
"typescript": "^5.2.2",
|
|
76
83
|
"vitest": "^0.34.4"
|
|
@@ -80,8 +87,12 @@
|
|
|
80
87
|
"node:child_process",
|
|
81
88
|
"node:fs",
|
|
82
89
|
"consola",
|
|
90
|
+
"esbuild",
|
|
83
91
|
"pathe",
|
|
84
|
-
"
|
|
92
|
+
"rollup",
|
|
93
|
+
"ufo",
|
|
94
|
+
"vite",
|
|
95
|
+
"vite-plugin-pwa"
|
|
85
96
|
]
|
|
86
97
|
}
|
|
87
98
|
}
|
package/templates/pwa.client.ts
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { ref, reactive, nextTick, type UnwrapNestedRefs } from 'vue'
|
|
2
|
-
import { useRegisterSW } from 'virtual:pwa-register/vue'
|
|
3
|
-
import { defineNuxtPlugin } from '#imports'
|
|
4
|
-
|
|
5
|
-
import { type PwaInjection } from '@vite-pwa/nuxt'
|
|
6
|
-
|
|
7
|
-
const options: { periodicSyncForUpdates: number; installPrompt?: string } = <%= JSON.stringify(options) %>
|
|
8
|
-
|
|
9
|
-
export default defineNuxtPlugin(() => {
|
|
10
|
-
const registrationError = ref(false)
|
|
11
|
-
const swActivated = ref(false)
|
|
12
|
-
const showInstallPrompt = ref(false)
|
|
13
|
-
const hideInstall = ref(!options.installPrompt ? true : localStorage.getItem(options.installPrompt) === 'true')
|
|
14
|
-
|
|
15
|
-
// https://thomashunter.name/posts/2021-12-11-detecting-if-pwa-twa-is-installed
|
|
16
|
-
const ua = navigator.userAgent
|
|
17
|
-
const ios = ua.match(/iPhone|iPad|iPod/)
|
|
18
|
-
const standalone = window.matchMedia('(display-mode: standalone)').matches
|
|
19
|
-
const isInstalled = !!(standalone || (ios && !ua.match(/Safari/)))
|
|
20
|
-
|
|
21
|
-
let swRegistration: ServiceWorkerRegistration | undefined
|
|
22
|
-
|
|
23
|
-
const getSWRegistration = () => swRegistration
|
|
24
|
-
|
|
25
|
-
const registerPeriodicSync = (swUrl: string, r: ServiceWorkerRegistration, timeout: number) => {
|
|
26
|
-
setInterval(async () => {
|
|
27
|
-
if (('connection' in navigator) && !navigator.onLine)
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
const resp = await fetch(swUrl, {
|
|
31
|
-
cache: 'no-store',
|
|
32
|
-
headers: {
|
|
33
|
-
'cache': 'no-store',
|
|
34
|
-
'cache-control': 'no-cache',
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
if (resp?.status === 200)
|
|
39
|
-
await r.update()
|
|
40
|
-
}, timeout)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const {
|
|
44
|
-
offlineReady, needRefresh, updateServiceWorker,
|
|
45
|
-
} = useRegisterSW({
|
|
46
|
-
immediate: true,
|
|
47
|
-
onRegisterError() {
|
|
48
|
-
registrationError.value = true
|
|
49
|
-
},
|
|
50
|
-
onRegisteredSW(swUrl, r) {
|
|
51
|
-
swRegistration = r
|
|
52
|
-
const timeout = options.periodicSyncForUpdates
|
|
53
|
-
if (timeout > 0) {
|
|
54
|
-
// should add support in pwa plugin
|
|
55
|
-
if (r?.active?.state === 'activated') {
|
|
56
|
-
swActivated.value = true
|
|
57
|
-
registerPeriodicSync(swUrl, r, timeout * 1000)
|
|
58
|
-
}
|
|
59
|
-
else if (r?.installing) {
|
|
60
|
-
r.installing.addEventListener('statechange', (e) => {
|
|
61
|
-
const sw = e.target as ServiceWorker
|
|
62
|
-
swActivated.value = sw.state === 'activated'
|
|
63
|
-
if (swActivated.value)
|
|
64
|
-
registerPeriodicSync(swUrl, r, timeout * 1000)
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
const cancelPrompt = async () => {
|
|
72
|
-
offlineReady.value = false
|
|
73
|
-
needRefresh.value = false
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let install: () => Promise<void> = () => Promise.resolve()
|
|
77
|
-
let cancelInstall: () => void = () => {}
|
|
78
|
-
|
|
79
|
-
if (!hideInstall.value) {
|
|
80
|
-
type InstallPromptEvent = Event & {
|
|
81
|
-
prompt: () => void
|
|
82
|
-
userChoice: Promise<{ outcome: 'dismissed' | 'accepted' }>
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let deferredPrompt: InstallPromptEvent | undefined
|
|
86
|
-
|
|
87
|
-
const beforeInstallPrompt = (e: Event) => {
|
|
88
|
-
e.preventDefault()
|
|
89
|
-
deferredPrompt = e as InstallPromptEvent
|
|
90
|
-
showInstallPrompt.value = true
|
|
91
|
-
}
|
|
92
|
-
window.addEventListener('beforeinstallprompt', beforeInstallPrompt)
|
|
93
|
-
window.addEventListener('appinstalled', () => {
|
|
94
|
-
deferredPrompt = undefined
|
|
95
|
-
showInstallPrompt.value = false
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
cancelInstall = () => {
|
|
99
|
-
deferredPrompt = undefined
|
|
100
|
-
showInstallPrompt.value = false
|
|
101
|
-
window.removeEventListener('beforeinstallprompt', beforeInstallPrompt)
|
|
102
|
-
hideInstall.value = true
|
|
103
|
-
localStorage.setItem(options.installPrompt!, 'true')
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
install = async () => {
|
|
107
|
-
if (!showInstallPrompt.value || !deferredPrompt) {
|
|
108
|
-
showInstallPrompt.value = false
|
|
109
|
-
return
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
showInstallPrompt.value = false
|
|
113
|
-
await nextTick()
|
|
114
|
-
deferredPrompt.prompt()
|
|
115
|
-
await deferredPrompt.userChoice
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
provide: {
|
|
121
|
-
pwa: reactive({
|
|
122
|
-
isInstalled,
|
|
123
|
-
showInstallPrompt,
|
|
124
|
-
cancelInstall,
|
|
125
|
-
install,
|
|
126
|
-
swActivated,
|
|
127
|
-
registrationError,
|
|
128
|
-
offlineReady,
|
|
129
|
-
needRefresh,
|
|
130
|
-
updateServiceWorker,
|
|
131
|
-
cancelPrompt,
|
|
132
|
-
getSWRegistration,
|
|
133
|
-
}) satisfies UnwrapNestedRefs<PwaInjection>,
|
|
134
|
-
},
|
|
135
|
-
}
|
|
136
|
-
})
|
|
File without changes
|
|
File without changes
|