Skip to content
Library provides low-level API to control NW.js app auto-updates
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Lib Remove backupDir before copy to it Mar 11, 2019
example updating dependencies for npm audit Nov 30, 2018
.gitignore going 1.1.0-beta Apr 20, 2017
CHANGELOG.md updating version Oct 18, 2017
LICENSE Create LICENSE Nov 26, 2018
README.md release 1.1.7 Nov 29, 2018
book-cover.png adding book promo Sep 8, 2017
index.js - Fix log Oct 1, 2017
nw-autoupdater.gif animated gif to show Strategy ScriptSwap Apr 24, 2017
package-lock.json 1.1.10 Mar 12, 2019
package.json 1.1.10 Mar 12, 2019

README.md

NW-Autoupdater v1.1

NPM

FOSSA Status Join the chat at https://gitter.im/dsheiko/nw-autoupdater

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

Autoupdater in action

📹 Screencast: Running nw-autoupdater examples in the terminal on Ubuntu

What do we do to autoupdate (see demo A or demo B)

  • readRemoteManifest reads 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 download events
    • We subscribe for install events
  • download( rManifest ) downloads the latest available release matching the host platform (according to the packages map of the remote manifest)
  • unpack( updateFile ) unpacks the release archive (zip or 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 manifestUrl pointing at release server
  • Package your app by using nwjs-builder (see example)
  • Update the contents of packages field in release server manifest (e.g. by running node update.js)
  • Update version field 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 ScriptSwap or 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.execPath contains 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 true swap 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 true for 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}/package

So 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.7.tgz`
# Switch a client example
cd example/client-strategy-script/

# Install the updated package
npm i ../../nw-autoupdater-1.1.7.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-demo


My book:

Cross-platform Desktop Application Development: Electron, Node, NW.js, and React

I split the book in four tutorials, starting with basics and advancing progressively though more and more complex aspects. So the first part guides on creating a file-explorer built with pure JavaScript and NW.js/Node.js. The second part is about creating a chat with Electron, React and PhotonKit. The third part is about screen capturer made with NW.js, React/Redux and Material UI. The last part guides on creating RSS aggregator with Electron, React, Redux and TypeScript.

You can’t perform that action at this time.