nw-autoupdater v1.1.11
NW-Autoupdater v1.1
Library provides low-level API to control NW.js app auto-updates. This project can be seen as a reincarnation of node-webkit-updater, which is not maintained anymore.
Features
- Node >= 7 compliant
- clean async/await syntax
- supports both Zip/Tar.Gz archives
- fires download/install progress events
Strategy ScriptSwap

:video_camera: Screencast: Running nw-autoupdater examples in the terminal on Ubuntu
What do we do to autoupdate (see demo A or demo B)
- readRemoteManifestreads manifest from the remote release server
- checkNewVersion( rManifest )checks if the version in the remote manifest greater than one of the local manifest
- If the remote manifest doesn't have newer version, skips the update flow- We subscribe for downloadevents
- We subscribe for installevents
 
- We subscribe for 
- download( rManifest )downloads the latest available release matching the host platform (according to the- packagesmap of the remote manifest)
- unpack( updateFile )unpacks the release archive (- zipor- tar.gz) in a temporary directory
- Strategy AppSwap- restartToSwap( extraArgs )closes the app and launches the downloaded release
- isSwapRequest()- checks if we need to go the swap flow (while running in tmp and therefore having the initial app directory unlocked for writing)
- swap()- backs up actual version and replaces it with the new one
- restart( extraArgs )- restarts the updated app from its original location
 
- Strategy ScriptSwap- restartToSwap()closes the app and launches the swap script, which launches the application when it's done
 
Distribution
- Run release server (see example)
- Add to your client manifest (package.json) field manifestUrlpointing at release server
- Package your app by using nwjs-builder (see example)
- Update the contents of packagesfield in release server manifest (e.g. by runningnode update.js)
- Update versionfield in release server manifest
- Launch your app and observe it's auto-updating
Examples
API
Constructor
new AutoUpdate( manifest, options );Params
- manifest- e.g.- require( "./package.json" )
- options.strategy- (OPTIONAL) can be- ScriptSwapor- AppSwap. By default- AppSwap
- options.executable- (OPTIONAL) executable if it doesn't match project name
- options.backupDir- (OPTIONAL) directory to backup. By default it's <project_name>.bak next to app directory
- options.execDir- (OPTIONAL) app directory. By default it's extracted from- process.execPath(nwjs-builder bundles the app into self-extractable and- process.cwd()is not a reliable source). Yet on a Mac- process.execPathcontains the full path to the executable within MacOS bundle. So you rather use this option to set the app path directly.
- options.updateDir- (OPTIONAL) temporary directory where the downloaded package gets extracted. By default /tmp/nw-autoupdater
- options.logPath- (OPTIONAL) the full path to the log file. By default- nw.App.dataPath + "/nw-autoupdater.log": Windows: %LOCALAPPDATA%/<project_name>; Linux: ~/.config/<project_name>; OSX: ~/Library/Application Support/<project_name>
- options.verbose- (OPTIONAL) when- trueswap script reports verbose in the log file. By default- false
- options.swapScript- (OPTIONAL) you custom swap script content (NOTE: available only for ScriptSwap strategy)
- options.accumulativeBackup- (OPTIONAL) when- truefor every backup creates a new folder. By default- false
Writing custom swap script
You can define with options.swapScript you own custom swap script:
 const updater = new AutoUpdater( require( "./package.json" ), {
          strategy: "ScriptSwap",
          swapScript: `
BASH/BAT SCRIPT CONTENT
`
      });By default on Linux/MacIO the following script is used:
rsync -a\${VERBOSE} --delete \${APP_PATH}/. \${BAK_PATH}/
rsync -a\${VERBOSE} --delete \${UPDATE_PATH}/. \${APP_PATH}/where the variables are populated from ARGV:
- VERBOSE - "v" or ""
- APP_PATH - application home directory
- BAK_PATH - backup directory
- UPDATE_PATH - update directory
For example, if you have for package not the entire NW.js application, but just HTML5 project, you set up the following script:
rsync -a\${VERBOSE} --delete \${APP_PATH}/. \${BAK_PATH}/
rsync -a\${VERBOSE} \${UPDATE_PATH}/. \${APP_PATH}/packageSo it backups the project, but copies extracted packaged into package subfolder in application home directory
readRemoteManifest
Reads package.json of the release server
const rManifest = await updater.readRemoteManifest();Returns: Promise<manifest: Object>
checkNewVersion
Check if the release server has newer app version
const needsUpdate = await updater.checkNewVersion( rManifest );Params
- rManifest- manifest of the release server
Returns: Promise<needsUpdate: boolean>
download
Download last available update to the temp directory
const updateFile = await updater.download( rManifest, { debounceTime: 100 });Params
- rManifest- manifest of the release server
- options.debounceTime- (OPTIONAL) debounce time in milliseconds
Returns: Promise<filepath: string>
unpack
Unpack downloaded update
const extractDir = await updater.unpack( updateFile, { debounceTime: 100 } );Params
- updateFile- path to downloaded update
- options.debounceTime- (OPTIONAL) debounce time in milliseconds
Returns: Promise<directory: string>
restartToSwap
Close this version of app and start the downloaded one with --swap param
await updater.restartToSwap();Params
- extraArgs- (OPTIONAL) Extra arguments to be passed to the newly started app
Returns: Promise
Events
download
Subscribe on download progress event
updater.on( "download", ( downloadSize, totalSize ) => {
  console.log( "download progress", Math.floor( downloadSize / totalSize * 100 ), "%" );
});install
Subscribe on install progress event
updater.on( "install", ( installFiles, totalFiles ) => {
  console.log( "install progress", Math.floor( installFiles / totalFiles * 100 ), "%" );
});Extra Methods required for Strategy AppSwap
isSwapRequest
Checks if the app launched for swap
const needsSwap = updater.isSwapRequest();Returns: boolean
swap
Backs up current version of the app and replaces it with the downloaded version
await updater.swap();Returns: Promise
restart
Restarts the updated app
await updater.restart();Params
- extraArgs- (OPTIONAL) Extra arguments to be passed to the newly started app
Returns: Promise
Contributing
nw-autoupdater welcomes maintainers. There is plenty of work to do. No big commitment required,
if all you do is review a single Pull Request, you are a maintainer.
How to check changes
# Clone the git repo
git clone git@github.com:dsheiko/nw-autoupdater.git
# Navigate to the newly created directory
cd nw-autoupdater
# Switch the branch if needed
# Make changes in the code
# Bundle the package
npm pack
# You'will get a new file like `nw-autoupdater-1.1.11.tgz`
# Switch a client example
cd example/client-strategy-script/
# Install the updated package
npm i ../../nw-autoupdater-1.1.11.tgz
# Package demo app
npm run package
# Extract demo app package in a temp directory
unzip ../server/releases/nw-autoupdater-demo-r1.0.0-linux-x64.zip -d /tmp/Sandbox/
# Switch to release server example
cd ../server/
# Make sure dependencies up to date
npm i
# Update releases manifest
npm run update
# Start the server
npm start
# Now start the demo app from your temp /tmp/Sandbox/
/tmp/Sandbox/nw-autoupdater-demo
# It says:
#  Application ver. 1.0.0
#  App is up to date...
# Switch back to demo app and update its version
cd ../client-strategy-script/
npm version patch
npm run package
# Back to the server to update manifest
cd ../server/
npm run update
npm start
# When starting the built app it updates
/tmp/Sandbox/nw-autoupdater-demo6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
