@7n/tauri-components 0.7.0 → 0.8.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/package.json +5 -1
- package/src/vue/index.js +1 -0
- package/src/vue/use-updater.js +116 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@7n/tauri-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared LLM agent engine + Vue/Quasar UI for Tauri apps (chat, journal, trust-tier approval).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@tauri-apps/api": "^2.0.0",
|
|
38
38
|
"@tauri-apps/plugin-http": "^2.0.0",
|
|
39
|
+
"@tauri-apps/plugin-process": "^2.0.0",
|
|
40
|
+
"@tauri-apps/plugin-updater": "^2.0.0",
|
|
39
41
|
"@vue/test-utils": "^2.0.0",
|
|
40
42
|
"quasar": "^2.0.0",
|
|
41
43
|
"vue": "^3.0.0"
|
|
@@ -43,6 +45,8 @@
|
|
|
43
45
|
"peerDependenciesMeta": {
|
|
44
46
|
"@tauri-apps/api": { "optional": true },
|
|
45
47
|
"@tauri-apps/plugin-http": { "optional": true },
|
|
48
|
+
"@tauri-apps/plugin-process": { "optional": true },
|
|
49
|
+
"@tauri-apps/plugin-updater": { "optional": true },
|
|
46
50
|
"@vue/test-utils": { "optional": true },
|
|
47
51
|
"quasar": { "optional": true }
|
|
48
52
|
},
|
package/src/vue/index.js
CHANGED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { onMounted, onUnmounted } from 'vue'
|
|
2
|
+
import { relaunch } from '@tauri-apps/plugin-process'
|
|
3
|
+
import { check } from '@tauri-apps/plugin-updater'
|
|
4
|
+
import { useQuasar } from 'quasar'
|
|
5
|
+
|
|
6
|
+
// Checks for an app update on mount and hourly thereafter, prompting via a
|
|
7
|
+
// Quasar dialog; after install, offers an immediate relaunch. Requires the
|
|
8
|
+
// host app's tauri.conf.json to configure plugins.updater (pubkey + endpoint)
|
|
9
|
+
// and capabilities/default.json to grant "updater:default" — without the
|
|
10
|
+
// capability, check() fails with a silent permission-denied that only surfaces
|
|
11
|
+
// via console.error (no dialog, no visible error).
|
|
12
|
+
//
|
|
13
|
+
// No-op in dev builds: tauri.conf.json's version is the CI-injected release
|
|
14
|
+
// version, not what's running locally, so the updater would always think dev
|
|
15
|
+
// code is stale.
|
|
16
|
+
|
|
17
|
+
const FIRST_CHECK_DELAY_MS = 3000
|
|
18
|
+
const CHECK_INTERVAL_MS = 60 * 60 * 1000
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @returns {void}
|
|
22
|
+
*/
|
|
23
|
+
export function useUpdater() {
|
|
24
|
+
if (import.meta.env.DEV) return
|
|
25
|
+
|
|
26
|
+
const $q = useQuasar()
|
|
27
|
+
let timer = null
|
|
28
|
+
// A dialog is showing or an install already ran — don't stack background checks.
|
|
29
|
+
let busy = false
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Asks the configured update endpoint for a newer version and, if found,
|
|
33
|
+
* walks the user through the install flow.
|
|
34
|
+
* @returns {Promise<void>}
|
|
35
|
+
*/
|
|
36
|
+
async function checkForUpdates() {
|
|
37
|
+
if (busy) return
|
|
38
|
+
try {
|
|
39
|
+
const update = await check()
|
|
40
|
+
if (!update) return
|
|
41
|
+
|
|
42
|
+
busy = true
|
|
43
|
+
$q.dialog({
|
|
44
|
+
title: 'Доступне оновлення',
|
|
45
|
+
message: `Версія ${update.version} готова. Встановити зараз?`,
|
|
46
|
+
cancel: { label: 'Пізніше', flat: true },
|
|
47
|
+
ok: { label: 'Встановити', color: 'primary' },
|
|
48
|
+
persistent: true,
|
|
49
|
+
})
|
|
50
|
+
.onOk(() => installAndRelaunch(update))
|
|
51
|
+
.onCancel(() => {
|
|
52
|
+
busy = false
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// No network, or the updater isn't configured/permitted — don't bother
|
|
57
|
+
// the user, but leave a trace for diagnosis.
|
|
58
|
+
console.error('[updater] check failed:', error)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Downloads and installs the update with progress, then offers a relaunch.
|
|
64
|
+
* @param {import('@tauri-apps/plugin-updater').Update} update the update found by check()
|
|
65
|
+
* @returns {Promise<void>}
|
|
66
|
+
*/
|
|
67
|
+
async function installAndRelaunch(update) {
|
|
68
|
+
let downloaded = 0
|
|
69
|
+
let total = 0
|
|
70
|
+
const dismiss = $q.notify({ group: false, timeout: 0, spinner: true, message: 'Завантаження оновлення…' })
|
|
71
|
+
try {
|
|
72
|
+
await update.downloadAndInstall(event => {
|
|
73
|
+
switch (event.event) {
|
|
74
|
+
case 'Started': {
|
|
75
|
+
total = event.data.contentLength ?? 0
|
|
76
|
+
break
|
|
77
|
+
}
|
|
78
|
+
case 'Progress': {
|
|
79
|
+
downloaded += event.data.chunkLength
|
|
80
|
+
if (total) dismiss({ message: `Завантаження… ${Math.round((downloaded / total) * 100)}%` })
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
case 'Finished': {
|
|
84
|
+
dismiss()
|
|
85
|
+
break
|
|
86
|
+
}
|
|
87
|
+
// No default
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
// busy stays true: the update is already on disk, a repeat check would
|
|
91
|
+
// only offer to install the same thing again.
|
|
92
|
+
$q.dialog({
|
|
93
|
+
title: 'Оновлення встановлено',
|
|
94
|
+
message: `Перезапустити зараз, щоб перейти на версію ${update.version}?`,
|
|
95
|
+
cancel: { label: 'Пізніше', flat: true },
|
|
96
|
+
ok: { label: 'Перезапустити', color: 'primary' },
|
|
97
|
+
persistent: true,
|
|
98
|
+
}).onOk(() => relaunch())
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
dismiss()
|
|
102
|
+
busy = false
|
|
103
|
+
console.error('[updater] install failed:', error)
|
|
104
|
+
$q.notify({ message: `Помилка оновлення: ${error}`, color: 'negative', timeout: 5000 })
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
onMounted(() => {
|
|
109
|
+
setTimeout(checkForUpdates, FIRST_CHECK_DELAY_MS)
|
|
110
|
+
timer = setInterval(checkForUpdates, CHECK_INTERVAL_MS)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
onUnmounted(() => {
|
|
114
|
+
if (timer) clearInterval(timer)
|
|
115
|
+
})
|
|
116
|
+
}
|