Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
TheJaredWilcurt committed Dec 27, 2023
1 parent 1a8b065 commit 686204c
Showing 1 changed file with 58 additions and 34 deletions.
92 changes: 58 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@ In the `splash.html` file
* 3. Launches a window pointed to the latest version
*/
nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
// OPTIONAL: defaults to true
// OPTIONAL: defaults to true, will not show console messages if false
verbose: true,
/**
* OPTIONAL: console.error is called by default if verbose: true.
* OPTIONAL: Your own custom logging function called with helpful
* warning/error messages from the internal validators. Only used if
* verbose: true. Defaults to console.error if not supplied.
*
* Your own custom logging function called with helpful warning/error
* messages from the internal validators. Only used if verbose: true.
*
* @param {string} message The human readable warning/error message
* @param {object} error Sometimes an error or options object is passed
* @param string} message The human readable warning/error message
* @param object} error Sometimes an error or options object is passed
*/
customLogger: function (message, error) {
console.log(message, error);
Expand All @@ -51,20 +50,24 @@ nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
* then pass the response into the confirmNewVersion and downloadPath
* callback functions you provide.
*/
// This is an example, you can put whatever URL you want here
// This is an example, you can put whatever URL you want here, does not need to be JSON.
versionUrl: 'https://example.com/versions.json',
/**
* Check if the latest remote version is newer than the latest local version.
* This function is handed the response from the versionUrl request, and the version number
* of the latest locally installed version of your app. You can then perform whatever logic
* you want (including additional network calls) to determine wether to download a new
* version of your app or to use the local copy.
*
* If a new version is available, return the new version number to begin the
* download/extract. If no new version exists, then return false and the latest
* local version will be opened in a new window and the splash screen closed.
*
* @param {string} response The network respone from versionUrl
* @param {string} latestLocal The latest downloaded version, or undefined if not present
* @return {string} The new version number (continue to download zip), or false (open current version)
* @param {string} response The network respone from versionUrl
* @param {string} latestLocal The latest downloaded version, or undefined if not present
* @return {string} The new version number (continue to download zip), or false (open current version)
*/
confirmNewVersion: function (response, latestLocal) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
response = JSON.parse(response);
const latestRemote = response.latest.version;
const updateAvailable = require('semver').gt(latestRemote, latestLocal);
Expand All @@ -81,22 +84,23 @@ nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
* @return {string} A url to a ZIP file to be downloaded
*/
downloadPath: function (response) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
response = JSON.parse(response);
return response.latest.downloadUrl;
},
// If the download or extract fails, we will retry n times before stopping
// If the download or extract fails, we will retry the following amount of times before stopping
downloadRetries: 3,
extractRetries: 3,
/**
* Called when an update occurs during download/extract.
* Optional event hook.
* Called when an update occurs during download/extract. May be called many times.
*
* @param {object} update Object containing percents
* @param {number} update.downloadProgress The download progress percent
* @param {number} update.extractProgress The extract progress percent
* @param {object} update Object containing percents
* @param {number} update.downloadProgress The download progress percent
* @param {number} update.extractProgress The extract progress percent
*/
onUpdate: function ({ downloadProgress, extractProgress }) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
if (downloadProgress) {
console.log('Download progress: ' + downloadProgress + '%');
}
Expand All @@ -107,40 +111,42 @@ nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
/**
* Optional function. You can run any code to validate
* that the downloaded zip matches expecations.
* If it does return true. If you return false, then
* nwSplasherAutoUpdate will retry or stop running.
* If it does, return true. If you return false, then
* nwSplasherAutoUpdate will retry the download or stop running.
*
* @param {string} pathToZip File path to the downloaded zip file
* @return {Boolean} true = continue, false = retry/stop
*/
validateZip: function (pathToZip) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
return true;
},
/**
* Optional function. You can run any code to validate
* that the files extracted from the zip match your
* expecations. If they do return true. If you return false,
* then nwSplasherAutoUpdate will retry or stop running.
* expecations. If they do, return true. If you return false,
* then nwSplasherAutoUpdate will retry extraction or stop running.
*
* @param {string} pathToExtract File path to the downloaded zip file
* @param {string} pathToExtract File path to extracted folder
* @return {Boolean} true = continue, false = retry/stop
*/
validateExtract: function (pathToExtract) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
return true;
},
/**
* Optional event hook.
* When download or extract fails, but we haven't
* exhausted all retries yet, this is called.
*
* @param {string} message Human readable warning message
*/
onRetry: function (message) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
console.log(message);
},
/**
* Optional event hook.
* Called when an error is encountered that ended execution
* prematurely. Such as failing to download or extract after
* all retries were exhausted.
Expand All @@ -149,10 +155,11 @@ nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
* @param {object} err Detailed error information if available
*/
onError: function (errorMessage, err) {
//This is just an example, you can put any logic you want here
// This is just an example, you can put any logic you want here
console.log(errorMessage, err);
},
/**
* Optional event hook.
* Called just prior to opening the new window
* and closing the splash screen.
*/
Expand All @@ -172,14 +179,17 @@ nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
});
```

In your main window that is displayed after the auto-update
In your main window that is displayed after the auto-update (probably `index.html`);

```js
```html
<script>
const nwSplasherAutoUpdate = require('nw-splasher-auto-update');
nwSplasherAutoUpdate.setCurrentWorkingDirectory();
nwSplasherAutoUpdate.closeSplashAndShowApp({
// Must match the port number used in the splash.html
port: 4443
});
</script>
```


Expand All @@ -193,6 +203,7 @@ Deleting old cache
*/
nwSplasherAutoUpdate.deletePastVersions({
/**
* Optional event hook.
* Called when any errors are encountered during deletion.
*
* @param {string} errorMessage Human readable error message
Expand All @@ -202,6 +213,7 @@ nwSplasherAutoUpdate.deletePastVersions({
console.log(errorMessage, err);
},
/**
* Optional event hook.
* When deletion attempt finishes, whether successful or not.
*/
onComplete: function () {
Expand Down Expand Up @@ -231,7 +243,7 @@ path.join(nw.App.dataPath, 'nwSplasherExtracts', version);
* Would use `nw-splasher` as a dependency
* Would use `fs-extra` to delete files
* Not sure what to use for network requests (versions.json), downloading zip (including progress updates), or extracting the zip file (including progress updates)
* We have a lot of beginner programmers. So although internally we may use async/await and promises, I'd like the API to be kept as a simple/approachable object with callbacks to be more approachable
* We have a lot of beginner programmers. So although internally we may use async/await and promises, I'd like to keep the API as a simple object with callbacks to be more approachable
* There are a lot of other features we might want to add in the future, like support for `.tar.gz`, `.rar`, `.7z`, etc but let's keep the scope small for now until those features are requested.


Expand All @@ -242,8 +254,12 @@ path.join(nw.App.dataPath, 'nwSplasherExtracts', version);
nwSplasherAutoUpdate.downloadLatestAppAndOpenWindowInBackground({
autoUpdate: {
versionUrl: 'https://example.com/versions.json',
confirmNewVersion: function (response, latestLocal) {},
downloadPath: function (response) {}
confirmNewVersion: function (response, latestLocal) {
return true || false;
},
downloadPath: function (response) {
return 'url to download zip file containing new app version'
}
}
});

Expand Down Expand Up @@ -272,6 +288,14 @@ If they release different auto-update packages for different NW.js versions.
We suggest ALL users of this library code in some UI to convey to users when an auto-update won't work, and they'll need to download the full version from the website again. So if a user is on a 3 year old version of NW.js that you want to drop support for, there is some way of conveying that cleanly in the UI that is compatible with the older version.


## How can I force the user to update to a newer NW.js version?

Two ways:

* **Thinking ahead:** Include some code in the splasher window to look at your end point response, notice a flag, and then display a message with a link "You must manually download and install the latest version", then the link opens in the user's default browser with `nw.Shell.openExternal('https://expample.com/download')`.
* **Not thinking ahead:** If you didn't preemptively include a way of handling this case, you can instead have the latest version of the app just be a window that directs people to download a new version. The new version's splasher could then be better designed to handle this scenario.


### For-profit software

If you are using NW.js to create for-profit software, then this style of auto-update may not work for you. If you require authenticating a license, key, or the user, or the download requires authentication, then this "splash + download a zip" approach is likely too simple for your needs, and you should consider writing your own solution custom to your use case.

0 comments on commit 686204c

Please sign in to comment.