updater.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { listen, TauriEvent, emit, once } from './event.js';
  2. // Copyright 2019-2023 Tauri Programme within The Commons Conservancy
  3. // SPDX-License-Identifier: Apache-2.0
  4. // SPDX-License-Identifier: MIT
  5. /**
  6. * Customize the auto updater flow.
  7. *
  8. * This package is also accessible with `window.__TAURI__.updater` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`.
  9. * @module
  10. */
  11. /**
  12. * Listen to an updater event.
  13. * @example
  14. * ```typescript
  15. * import { onUpdaterEvent } from "@tauri-apps/api/updater";
  16. * const unlisten = await onUpdaterEvent(({ error, status }) => {
  17. * console.log('Updater event', error, status);
  18. * });
  19. *
  20. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  21. * unlisten();
  22. * ```
  23. *
  24. * @returns A promise resolving to a function to unlisten to the event.
  25. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  26. *
  27. * @since 1.0.2
  28. */
  29. async function onUpdaterEvent(handler) {
  30. return listen(TauriEvent.STATUS_UPDATE, (data) => {
  31. handler(data === null || data === void 0 ? void 0 : data.payload);
  32. });
  33. }
  34. /**
  35. * Install the update if there's one available.
  36. * @example
  37. * ```typescript
  38. * import { checkUpdate, installUpdate } from '@tauri-apps/api/updater';
  39. * const update = await checkUpdate();
  40. * if (update.shouldUpdate) {
  41. * console.log(`Installing update ${update.manifest?.version}, ${update.manifest?.date}, ${update.manifest.body}`);
  42. * await installUpdate();
  43. * }
  44. * ```
  45. *
  46. * @return A promise indicating the success or failure of the operation.
  47. *
  48. * @since 1.0.0
  49. */
  50. async function installUpdate() {
  51. let unlistenerFn;
  52. function cleanListener() {
  53. if (unlistenerFn) {
  54. unlistenerFn();
  55. }
  56. unlistenerFn = undefined;
  57. }
  58. return new Promise((resolve, reject) => {
  59. function onStatusChange(statusResult) {
  60. if (statusResult.error) {
  61. cleanListener();
  62. reject(statusResult.error);
  63. return;
  64. }
  65. // install complete
  66. if (statusResult.status === 'DONE') {
  67. cleanListener();
  68. resolve();
  69. }
  70. }
  71. // listen status change
  72. onUpdaterEvent(onStatusChange)
  73. .then((fn) => {
  74. unlistenerFn = fn;
  75. })
  76. .catch((e) => {
  77. cleanListener();
  78. // dispatch the error to our checkUpdate
  79. throw e;
  80. });
  81. // start the process we dont require much security as it's
  82. // handled by rust
  83. emit(TauriEvent.INSTALL_UPDATE).catch((e) => {
  84. cleanListener();
  85. // dispatch the error to our checkUpdate
  86. throw e;
  87. });
  88. });
  89. }
  90. /**
  91. * Checks if an update is available.
  92. * @example
  93. * ```typescript
  94. * import { checkUpdate } from '@tauri-apps/api/updater';
  95. * const update = await checkUpdate();
  96. * // now run installUpdate() if needed
  97. * ```
  98. *
  99. * @return Promise resolving to the update status.
  100. *
  101. * @since 1.0.0
  102. */
  103. async function checkUpdate() {
  104. let unlistenerFn;
  105. function cleanListener() {
  106. if (unlistenerFn) {
  107. unlistenerFn();
  108. }
  109. unlistenerFn = undefined;
  110. }
  111. return new Promise((resolve, reject) => {
  112. function onUpdateAvailable(manifest) {
  113. cleanListener();
  114. resolve({
  115. manifest,
  116. shouldUpdate: true
  117. });
  118. }
  119. function onStatusChange(statusResult) {
  120. if (statusResult.error) {
  121. cleanListener();
  122. reject(statusResult.error);
  123. return;
  124. }
  125. if (statusResult.status === 'UPTODATE') {
  126. cleanListener();
  127. resolve({
  128. shouldUpdate: false
  129. });
  130. }
  131. }
  132. // wait to receive the latest update
  133. once(TauriEvent.UPDATE_AVAILABLE, (data) => {
  134. onUpdateAvailable(data === null || data === void 0 ? void 0 : data.payload);
  135. }).catch((e) => {
  136. cleanListener();
  137. // dispatch the error to our checkUpdate
  138. throw e;
  139. });
  140. // listen status change
  141. onUpdaterEvent(onStatusChange)
  142. .then((fn) => {
  143. unlistenerFn = fn;
  144. })
  145. .catch((e) => {
  146. cleanListener();
  147. // dispatch the error to our checkUpdate
  148. throw e;
  149. });
  150. // start the process
  151. emit(TauriEvent.CHECK_UPDATE).catch((e) => {
  152. cleanListener();
  153. // dispatch the error to our checkUpdate
  154. throw e;
  155. });
  156. });
  157. }
  158. export { checkUpdate, installUpdate, onUpdaterEvent };