@todesktop/runtime
Advanced tools
Comparing version 1.6.1 to 1.6.2
@@ -0,6 +1,7 @@ | ||
import type { AllPublishOptions, PublishConfiguration } from "builder-util-runtime"; | ||
import { ProgressInfo } from "electron-updater"; | ||
import { CancelablePromise, EventEmitter2, GeneralEventEmitter, ListenToOptions, WaitForFilter, WaitForOptions } from "eventemitter2"; | ||
import type { PublishConfiguration, AllPublishOptions } from "builder-util-runtime"; | ||
import { LoggerInterface } from "./Logger"; | ||
import { TDUpdateInfo } from "./updaterAgents"; | ||
import { CheckForUpdatesInput, RestartAndInstallInput, Source } from "./types"; | ||
export declare type AutoUpdaterConstructorOptions = { | ||
@@ -12,9 +13,4 @@ readonly autoCheckInterval?: number; | ||
}; | ||
export declare enum BuiltInSources { | ||
autoCheckOnLaunch = "auto-check-on-launch", | ||
autoCheckOnInterval = "auto-check-on-interval", | ||
programmaticCall = "programmatic-call" | ||
} | ||
export declare type Source = BuiltInSources | string; | ||
export declare type UpdateAvailableEventPayload = { | ||
readonly disableUpdateReadyAction: boolean; | ||
readonly sources: Source[]; | ||
@@ -38,8 +34,4 @@ readonly updateInfo: TDUpdateInfo | null; | ||
logger, shouldAutoCheckOnLaunch, }: AutoUpdaterConstructorOptions); | ||
checkForUpdates({ source, }?: { | ||
source?: Source; | ||
}): Promise<UpdateCheckResult>; | ||
restartAndInstall({ isSilent, }?: { | ||
isSilent?: boolean; | ||
}): void; | ||
checkForUpdates({ source, disableUpdateReadyAction, }?: CheckForUpdatesInput): Promise<UpdateCheckResult>; | ||
restartAndInstall({ isSilent, }?: RestartAndInstallInput): void; | ||
setFeedURL(options: PublishConfiguration | AllPublishOptions | string): void; | ||
@@ -56,30 +48,31 @@ private _actuallyPerformCheck; | ||
declare interface AutoUpdater { | ||
addListener<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
emit<E extends keyof EventMap>(event: E, ...args: Parameters<EventMap[E]>): boolean; | ||
emitAsync<E extends keyof EventMap>(event: E, ...args: Parameters<EventMap[E]>): Promise<unknown[]>; | ||
hasListeners<E extends keyof EventMap>(event?: E): boolean; | ||
eventNames(): (keyof EventMap | string)[]; | ||
listenerCount<E extends keyof EventMap>(event: E): number; | ||
listeners<E extends keyof EventMap>(event: E): EventMap[E][]; | ||
listenersAny<E extends keyof EventMap>(): EventMap[E][]; | ||
listenTo<E extends keyof EventMap>(target: GeneralEventEmitter, events: E | E[], options?: ListenToOptions): this; | ||
listenTo<E extends keyof EventMap>(target: GeneralEventEmitter, events: Record<E, EventMap[E]>, options?: ListenToOptions): this; | ||
many<E extends keyof EventMap>(event: E, timesToListen: number, listener: EventMap[E], options?: boolean | object): this; | ||
off<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
offAny<E extends keyof EventMap>(listener: EventMap[E]): this; | ||
on<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
onAny<E extends keyof EventMap>(listener: (event: E, values: unknown[]) => void): this; | ||
once<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
prependAny<E extends keyof EventMap>(listener: (event: E, values: unknown[]) => void): this; | ||
prependListener<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
prependMany<E extends keyof EventMap>(event: E, timesToListen: number, listener: EventMap[E], options?: boolean | object): this; | ||
prependOnceListener<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
removeAllListeners<E extends keyof EventMap>(event?: E): this; | ||
removeListener<E extends keyof EventMap>(event: E, listener: EventMap[E]): this; | ||
stopListeningTo<E extends keyof EventMap>(target?: GeneralEventEmitter, event?: E): boolean; | ||
waitFor<E extends keyof EventMap>(event: E, timeout?: number): CancelablePromise<Parameters<EventMap[E]>>; | ||
waitFor<E extends keyof EventMap>(event: E, filter?: WaitForFilter): CancelablePromise<Parameters<EventMap[E]>>; | ||
waitFor<E extends keyof EventMap>(event: E, options?: WaitForOptions): CancelablePromise<Parameters<EventMap[E]>>; | ||
addListener<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
emit<E extends keyof AutoUpdaterEvents>(event: E, ...args: Parameters<AutoUpdaterEvents[E]>): boolean; | ||
emitAsync<E extends keyof AutoUpdaterEvents>(event: E, ...args: Parameters<AutoUpdaterEvents[E]>): Promise<unknown[]>; | ||
hasListeners<E extends keyof AutoUpdaterEvents>(event?: E): boolean; | ||
eventNames(): (keyof AutoUpdaterEvents | string)[]; | ||
listenerCount<E extends keyof AutoUpdaterEvents>(event: E): number; | ||
listeners<E extends keyof AutoUpdaterEvents>(event: E): AutoUpdaterEvents[E][]; | ||
listenersAny<E extends keyof AutoUpdaterEvents>(): AutoUpdaterEvents[E][]; | ||
listenTo<E extends keyof AutoUpdaterEvents>(target: GeneralEventEmitter, events: E | E[], options?: ListenToOptions): this; | ||
listenTo<E extends keyof AutoUpdaterEvents>(target: GeneralEventEmitter, events: Record<E, AutoUpdaterEvents[E]>, options?: ListenToOptions): this; | ||
many<E extends keyof AutoUpdaterEvents>(event: E, timesToListen: number, listener: AutoUpdaterEvents[E], options?: boolean | object): this; | ||
off<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
offAny<E extends keyof AutoUpdaterEvents>(listener: AutoUpdaterEvents[E]): this; | ||
on<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
onAny<E extends keyof AutoUpdaterEvents>(listener: (event: E, values: unknown[]) => void): this; | ||
once<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
prependAny<E extends keyof AutoUpdaterEvents>(listener: (event: E, values: unknown[]) => void): this; | ||
prependListener<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
prependMany<E extends keyof AutoUpdaterEvents>(event: E, timesToListen: number, listener: AutoUpdaterEvents[E], options?: boolean | object): this; | ||
prependOnceListener<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
removeAllListeners<E extends keyof AutoUpdaterEvents>(event?: E): this; | ||
removeListener<E extends keyof AutoUpdaterEvents>(event: E, listener: AutoUpdaterEvents[E]): this; | ||
stopListeningTo<E extends keyof AutoUpdaterEvents>(target?: GeneralEventEmitter, event?: E): boolean; | ||
waitFor<E extends keyof AutoUpdaterEvents>(event: E, timeout?: number): CancelablePromise<Parameters<AutoUpdaterEvents[E]>>; | ||
waitFor<E extends keyof AutoUpdaterEvents>(event: E, filter?: WaitForFilter): CancelablePromise<Parameters<AutoUpdaterEvents[E]>>; | ||
waitFor<E extends keyof AutoUpdaterEvents>(event: E, options?: WaitForOptions): CancelablePromise<Parameters<AutoUpdaterEvents[E]>>; | ||
} | ||
interface EventMap { | ||
export declare type AutoUpdaterEvents = { | ||
["error"](error: Error, message?: string): void; | ||
["before-quit-for-update"](...args: unknown[]): void; | ||
@@ -92,2 +85,2 @@ ["checking-for-update"](): void; | ||
["update-not-available"](info: TDUpdateInfo): void; | ||
} | ||
}; |
@@ -12,5 +12,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BuiltInSources = void 0; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore | ||
// @ts-ignore | ||
const electron = require("electron"); | ||
@@ -25,8 +22,3 @@ const electronUpdater = require("electron-updater"); | ||
const version_1 = require("./version"); | ||
var BuiltInSources; | ||
(function (BuiltInSources) { | ||
BuiltInSources["autoCheckOnLaunch"] = "auto-check-on-launch"; | ||
BuiltInSources["autoCheckOnInterval"] = "auto-check-on-interval"; | ||
BuiltInSources["programmaticCall"] = "programmatic-call"; | ||
})(BuiltInSources = exports.BuiltInSources || (exports.BuiltInSources = {})); | ||
const types_1 = require("./types"); | ||
class AutoUpdater extends eventemitter2_1.EventEmitter2 { | ||
@@ -77,3 +69,3 @@ constructor({ autoCheckInterval = 10 * 60 * 1000, // 10 min | ||
} | ||
checkForUpdates({ source = BuiltInSources.programmaticCall, } = {}) { | ||
checkForUpdates({ source = types_1.BuiltInSources.programmaticCall, disableUpdateReadyAction = false, } = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -91,3 +83,3 @@ this._log("info", ".checkForUpdates called"); | ||
} | ||
return yield this._check({ source }); | ||
return yield this._check({ source, disableUpdateReadyAction }); | ||
}); | ||
@@ -117,3 +109,3 @@ } | ||
} | ||
_actuallyPerformCheck() { | ||
_actuallyPerformCheck({ disableUpdateReadyAction, } = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -142,2 +134,3 @@ this._log("debug", "_actuallyPerformCheck called"); | ||
updateInfo, | ||
disableUpdateReadyAction, | ||
}; | ||
@@ -174,3 +167,4 @@ this._log("debug", "Emitting update-downloaded event"); | ||
yield this._check({ | ||
source: BuiltInSources.autoCheckOnInterval, | ||
source: types_1.BuiltInSources.autoCheckOnInterval, | ||
disableUpdateReadyAction: false, | ||
}); | ||
@@ -193,3 +187,4 @@ checkAfterTimeout(); | ||
yield this._check({ | ||
source: BuiltInSources.autoCheckOnLaunch, | ||
source: types_1.BuiltInSources.autoCheckOnLaunch, | ||
disableUpdateReadyAction: false, | ||
}); | ||
@@ -203,3 +198,3 @@ } | ||
} | ||
_check({ source, }) { | ||
_check({ source, disableUpdateReadyAction, }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -224,3 +219,5 @@ /* | ||
}; | ||
this._pendingUpdateCheckPromise = this._actuallyPerformCheck() | ||
this._pendingUpdateCheckPromise = this._actuallyPerformCheck({ | ||
disableUpdateReadyAction, | ||
}) | ||
.then((updateCheckResult) => { | ||
@@ -294,2 +291,6 @@ onEnd(); | ||
}); | ||
electronUpdater.autoUpdater.on("error", (error, message) => { | ||
this._log("info", "error"); | ||
this.emit("error", error, message); | ||
}); | ||
electronUpdater.autoUpdater.on("checking-for-update", () => { | ||
@@ -299,5 +300,5 @@ this._log("info", "checking-for-update"); | ||
}); | ||
electronUpdater.autoUpdater.on("download-progress", (info) => { | ||
this._log("info", "download-progress", info); | ||
this.emit("download-progress", info); | ||
electronUpdater.autoUpdater.on("update-not-available", (info) => { | ||
this._log("info", "update-not-available", info); | ||
this.emit("update-not-available", info); | ||
}); | ||
@@ -308,5 +309,6 @@ electronUpdater.autoUpdater.on("update-available", (info) => { | ||
}); | ||
electronUpdater.autoUpdater.on("update-not-available", (info) => { | ||
this._log("info", "update-not-available", info); | ||
this.emit("update-not-available", info); | ||
// we emit update-downloaded ourselves in `_actuallyPerformCheck` | ||
electronUpdater.autoUpdater.on("download-progress", (info) => { | ||
this._log("info", "download-progress", info); | ||
this.emit("download-progress", info); | ||
}); | ||
@@ -313,0 +315,0 @@ } |
import AutoUpdater from "./AutoUpdater"; | ||
import { LoggerInterface } from "./Logger"; | ||
import { UpdateReadyAction } from "./Notifier"; | ||
declare type initParams = { | ||
autoUpdater?: boolean; | ||
customLogger?: LoggerInterface; | ||
updateReadyAction?: UpdateReadyAction; | ||
}; | ||
import { ToDesktopRuntimeParams } from "./types"; | ||
declare class ToDesktop { | ||
autoUpdater: AutoUpdater; | ||
isSmokeTestMode: boolean; | ||
init(params?: initParams): void; | ||
init(params?: ToDesktopRuntimeParams): void; | ||
private _init; | ||
@@ -14,0 +8,0 @@ } |
@@ -7,2 +7,3 @@ "use strict"; | ||
const Notifier_1 = require("./Notifier"); | ||
const SimulatedAutoUpdater_1 = require("./SimulatedAutoUpdater"); | ||
class ToDesktop { | ||
@@ -21,15 +22,19 @@ constructor() { | ||
} | ||
_init({ autoUpdater = true, customLogger, updateReadyAction, } = {}) { | ||
_init({ autoUpdater = true, autoCheckInterval, shouldAutoCheckOnLaunch, customLogger, updateReadyAction, } = {}) { | ||
const logger = new Logger_1.default(customLogger); | ||
const Updater = (0, SimulatedAutoUpdater_1.parseSimulateUpdatesFlag)() | ||
? SimulatedAutoUpdater_1.SimulatedAutoUpdater | ||
: AutoUpdater_1.default; | ||
let autoUpdaterInstance; | ||
if (autoUpdater) { | ||
autoUpdaterInstance = new AutoUpdater_1.default({ logger }); | ||
new Notifier_1.default({ | ||
autoUpdater: autoUpdaterInstance, | ||
updateReadyAction, | ||
autoUpdaterInstance = new Updater({ | ||
logger, | ||
autoCheckInterval, | ||
shouldAutoCheckOnLaunch, | ||
}); | ||
new Notifier_1.default({ autoUpdater: autoUpdaterInstance, updateReadyAction }); | ||
} | ||
else { | ||
// Disables the default behaviour | ||
autoUpdaterInstance = new AutoUpdater_1.default({ | ||
autoUpdaterInstance = new Updater({ | ||
autoCheckInterval: 0, | ||
@@ -36,0 +41,0 @@ logger, |
@@ -101,3 +101,3 @@ "use strict"; | ||
if (config.autoRestart) { | ||
autoUpdater.restartAndInstall(); | ||
autoUpdater.restartAndInstall({ isSilent: true }); | ||
} | ||
@@ -104,0 +104,0 @@ }) |
import { Notification, NotificationConstructorOptions } from "electron"; | ||
import AutoUpdater, { UpdateAvailableEventPayload } from "./AutoUpdater"; | ||
import { MessageBoxOptions } from "electron/main"; | ||
import AutoUpdater from "./AutoUpdater"; | ||
import { UpdateReadyAction } from "./types"; | ||
/** | ||
@@ -28,24 +28,2 @@ * A proxy to a real Electron API. | ||
} | ||
export interface UpdateReadyAction { | ||
showInstallAndRestartPrompt?: "always" | "whenInForeground" | "never" | ShowInstallAndRestartPrompt; | ||
showNotification?: "always" | "whenInBackground" | "never" | ShowNotification; | ||
} | ||
export declare type ShowNotification = (context: UpdateContext) => Awaitable<Omit<NotificationConstructorOptions, "actions"> | ((api: ShowNotificationApi) => Awaitable<void>) | void>; | ||
declare type ShowNotificationApi = { | ||
showNotification(options: NotificationConstructorOptions): Notification; | ||
}; | ||
export declare type ShowInstallAndRestartPrompt = (context: UpdateContext) => Awaitable<(Omit<MessageBoxOptions, "buttons"> & { | ||
installOnNextLaunchButton: string; | ||
restartAndInstallButton: string; | ||
}) | ((api: ShowInstallAndRestartPromptApi) => Awaitable<void>) | void>; | ||
declare type ShowInstallAndRestartPromptApi = { | ||
showInstallAndRestartPrompt(options: Electron.MessageBoxOptions): Promise<Electron.MessageBoxReturnValue>; | ||
restartAndInstall({ isSilent }?: { | ||
isSilent?: boolean; | ||
}): void; | ||
}; | ||
declare type UpdateContext = UpdateAvailableEventPayload & { | ||
appIsInForeground: boolean; | ||
}; | ||
declare type Awaitable<T> = T | Promise<T>; | ||
export {}; |
@@ -60,2 +60,4 @@ "use strict"; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (payload.disableUpdateReadyAction) | ||
return; | ||
if (this._lastUpdate.isProcessing || | ||
@@ -62,0 +64,0 @@ this._lastUpdate.version === payload.updateInfo.version) { |
@@ -1,1 +0,1 @@ | ||
export declare const CLIENT_VERSION = "1.4.0"; | ||
export declare const CLIENT_VERSION = "1.6.2"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CLIENT_VERSION = void 0; | ||
exports.CLIENT_VERSION = "1.4.0"; | ||
exports.CLIENT_VERSION = "1.6.2"; |
@@ -7,3 +7,3 @@ { | ||
"name": "@todesktop/runtime", | ||
"version": "1.6.1", | ||
"version": "1.6.2", | ||
"license": "MIT", | ||
@@ -64,3 +64,3 @@ "author": "ToDesktop <hi@todesktop.com> (https://www.todesktop.com/)", | ||
"lint-staged": "^10.4.0", | ||
"np": "^6.5.0", | ||
"np": "^10.0.5", | ||
"prettier": "^2.0.5", | ||
@@ -67,0 +67,0 @@ "promise-polyfill": "^8.1.3", |
@@ -16,2 +16,3 @@ # @todesktop/runtime | ||
- [Default Behaviour](#default-behviour) | ||
- [Simulate Updates](#simulate-updates) | ||
- [Smoke Test](#smoke-test) | ||
@@ -85,4 +86,15 @@ - [API](#api) | ||
## Simulate updates | ||
Passing `--runtime-simulate-updates` as a flag with an associated value will run `@todesktop/runtime` in simulation mode: | ||
- `--runtime-simulate-updates=update-available` simulates the situation where an auto-update exists and will be downloaded. | ||
- `--runtime-simulate-updates=update-not-available` simulates the situation where an auto update is not available. | ||
Internally, this replaces the `autoUpdater` [API](#api) implementation with an alternative that simulates the above auto-update workflows. This is useful if you're running your application in local development and want to test `@todesktop/runtime`'s auto-update behaviour. | ||
## Smoke test | ||
Setting `TODESKTOP_SMOKE_TEST` in your environment to `true` will run `@todesktop/runtime` in simulation mode. | ||
When an application is run in Smoke Test mode the auto-update behavior is forcibly enabled. To successfully pass a Smoke Test your application should not expect any user interaction like showing some dialog on app start. | ||
@@ -122,2 +134,18 @@ | ||
##### `options.autoCheckInterval` (Optional) | ||
Type: `number` | ||
Default: `10 * 60 * 1000` (10 min) | ||
The interval at which ToDesktop should check for updates. | ||
##### `options.shouldAutoCheckOnLaunch` (Optional) | ||
Type: `boolean` | ||
Default: `true` | ||
Whether the app should check for auto-updates on launch. | ||
##### `options.customLogger` (Optional) | ||
@@ -165,2 +193,3 @@ | ||
- `context` contains update information: | ||
- `disableUpdateReadyAction: boolean;` | ||
- `sources: Source[];` | ||
@@ -240,2 +269,3 @@ - `updateInfo: TDUpdateInfo | null;` | ||
- `context` contains update information: | ||
- `disableUpdateReadyAction: boolean;` | ||
- `sources: Source[];` | ||
@@ -318,3 +348,3 @@ - `updateInfo: TDUpdateInfo | null;` | ||
Default: `{ source: "programmatic-call" }` | ||
Default: `{ source: "programmatic-call", disableUpdateReadyAction: false }` | ||
@@ -329,2 +359,10 @@ ##### `options.source` (Optional) | ||
##### `options.disableUpdateReadyAction` (Optional) | ||
Type: `boolean` | ||
Default: `false` | ||
Whether to disable the configured `updateReadyAction` behaviour. If disabled, the `updateReadyAction` prompt or notification will not display in response to invoking `.autoUpdater.checkForUpdates`. | ||
#### Example | ||
@@ -434,2 +472,3 @@ | ||
{ | ||
disableUpdateReadyAction: false, | ||
sources: ["auto-check-on-interval"], | ||
@@ -443,2 +482,4 @@ updateInfo: { | ||
`disableUpdateReadyAction` is a boolean that signals whether the configured `updateReadyAction` was disabled. | ||
`sources` (an array of strings) are the sources/triggers of the update check. The default built-in sources are `auto-check-on-launch`, `auto-check-on-interval`, and `programmatic-call`. You can pass a custom source to [`.autoUpdater.checkForUpdates`](#async-autoupdatercheckforupdatesoptions). NOTE: `sources` is an array because multiple checks could be triggered around the same time. They do not cancel an existing update check but piggyback onto it instead. | ||
@@ -586,3 +627,3 @@ | ||
Actions which require a user interaction may brake Smoke Test, especially | ||
Actions which require a user interaction may break Smoke Test, especially | ||
dialogs from electron dialog API. Use the following code to disable such a | ||
@@ -589,0 +630,0 @@ behavior in a Smoke Test mode: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
91106
649
1479