{"id":14954715,"url":"https://github.com/meteor-community-packages/meteor-desktop","last_synced_at":"2025-10-03T06:31:38.979Z","repository":{"id":42122543,"uuid":"294219291","full_name":"Meteor-Community-Packages/meteor-desktop","owner":"Meteor-Community-Packages","description":"Build a Meteor's desktop client with hot code push.","archived":false,"fork":true,"pushed_at":"2024-09-16T11:26:24.000Z","size":5233,"stargazers_count":38,"open_issues_count":6,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-16T19:49:44.406Z","etag":null,"topics":["desktop-app","electron","hacktoberfest","meteor"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"wojtkowiak/meteor-desktop","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Meteor-Community-Packages.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["storytellercz","jankapunkt"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-09-09T20:14:26.000Z","updated_at":"2024-10-31T07:44:47.000Z","dependencies_parsed_at":"2023-09-27T14:43:42.658Z","dependency_job_id":"8772678b-4c9c-413f-9f11-897594cafaa6","html_url":"https://github.com/Meteor-Community-Packages/meteor-desktop","commit_stats":{"total_commits":618,"total_committers":18,"mean_commits":"34.333333333333336","dds":"0.12944983818770228","last_synced_commit":"9b6753ed1aae82a7c2ed91f73a1c781fd1d188d9"},"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meteor-Community-Packages%2Fmeteor-desktop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meteor-Community-Packages%2Fmeteor-desktop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meteor-Community-Packages%2Fmeteor-desktop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meteor-Community-Packages%2Fmeteor-desktop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Meteor-Community-Packages","download_url":"https://codeload.github.com/Meteor-Community-Packages/meteor-desktop/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235086817,"owners_count":18933840,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["desktop-app","electron","hacktoberfest","meteor"],"created_at":"2024-09-24T13:04:58.237Z","updated_at":"2025-10-03T06:31:38.345Z","avatar_url":"https://github.com/Meteor-Community-Packages.png","language":"JavaScript","funding_links":["https://github.com/sponsors/storytellercz","https://github.com/sponsors/jankapunkt"],"categories":[],"sub_categories":[],"readme":"![Logo](docs/meteor-desktop.png)\n\n# Meteor Desktop\n###### aka Meteor Electron Desktop Client\n\u003e Build desktop apps with Meteor \u0026 Electron. Full integration with hot code push implementation.\n\n[![npm version](https://img.shields.io/npm/v/@meteor-community/meteor-desktop.svg)](https://npmjs.org/package/@meteor-community/meteor-desktop)\n\n![Demo](docs/demo.gif)\n\n## What is this?\n\nThis is a complete implementation of integration between `Meteor` and `Electron` aiming to achieve the same level of developer experience like `Meteor` gives.\nTo make it clear from the start, this is a **desktop client** - it is just like your mobile\nclients with `Cordova` - but this is for desktops with `Electron`. It also features a full hot code\npush implementation - which means you can release updates the same way you are used to.\n\n## Migrating from `meteor-desktop` to `@meteor-community/meteor-desktop`\nThis package was created by [wojtkowiak](https://github.com/wojtkowiak/) and was published under the name `meteor-desktop` up until version 2.2.5. After 2.2.6 it transitioned to being owned and published under the [Meteor-Community-Packages](https://github.com/Meteor-Community-Packages) GitHub and npm org.\n\nTo migrate from the original `meteor-desktop`:\n1. Replace the npm package\n   * Replace your package.json \"devDependencies\" entry for `\"meteor-desktop\"` to `\"@meteor-community/meteor-desktop\"`\n2. Replace the two Meteor Atmosphere packages\n   * Run `meteor remove omega:meteor-desktop-bundler` and `meteor add communitypackages:meteor-desktop-bundler`\n   * Run `meteor remove omega:meteor-desktop-watcher` and `meteor add communitypackages:meteor-desktop-watcher`\n\n## Prerequisites\n\n - Meteor \u003e= `1.12.1`\n - at least basic [Electron](http://electron.atom.io/) framework knowledge\n - mobile platform added to project\u003csup\u003e__*1__\u003c/sup\u003e  \n\n\u003csup\u003e__*1__ you can always build with `--server-only` if you do not want to have mobile clients,  you do not actually have to have android sdk or xcode to go on with your project\u003c/sup\u003e\n\n## Quick start\n```bash\ncd /your/meteor/app\nmeteor npm install --save-dev @meteor-community/meteor-desktop\nmeteor add-platform ios # or android\nnpm run desktop -- init\n\nmeteor --mobile-server=127.0.0.1:3000\n\n# open new terminal\nnpm run desktop\n```\n\nThe first time, you can also combine `npm run desktop -- init` and `npm run desktop` into `npm run desktop -- --scaffold` once meteor is running.\n\n## Usage `--help`\n\n```\n// Assumming you have a `desktop` script in npm scripts that equals to \"@meteor-community/meteor-desktop\"\nUsage: npm run desktop -- [command] [options]\n\n  Commands:\n\n    init                       scaffolds .desktop dir in the meteor app\n    run [ddp_url]              (default) builds and runs desktop app\n    build [ddp_url]            builds your desktop app\n    build-installer [ddp_url]  creates the installer\n    just-run                   alias for running `electron .` in `.meteor/desktop-build`\n    package [ddp_url]          runs electron packager\n    init-tests-support         prepares project for running functional tests of desktop app\n\n  Options:\n\n    -h, --help                            output usage information\n    -b, --build-meteor                    runs meteor to obtain the mobile build, kills it after\n    -t, --build-timeout \u003ctimeout_in_sec\u003e  timeout value when waiting for meteor to build, default 600sec\n    -p, --port \u003cport\u003e                     port on which meteor is running, when with -b this will be passed to meteor when obtaining the build\n    --production                          builds meteor app with the production switch, uglifies contents of .desktop, packs app to app.asar\n    -a, --android                         force adding android as a mobile platform instead of ios\n    -s, --scaffold                        will scaffold .desktop if not present\n    -i, --ignore-stderr [string]          only with -b, strings that when found will not terminate meteor build\n    --meteor-settings \u003cpath\u003e              only with -b, adds --settings options to meteor\n    --prod-debug                          forces adding dev tools to a production build\n    --ia32                                generate 32bit installer/package\n    --all-archs                           generate 32bit and 64bit installers\n    --win                                 generate Windows installer\n    --linux                               generate Linux installer\n    --mac                                 generate Mac installer\n    -d, --debug                           run electron with debug switch    \n    -V, --version                         output the version number\n\n\n  [ddp_url] - pass a ddp url if you want to use different one than used in meteor's --mobile-server\n              this will also work with -b\n```\n#### `--build-meteor`\nIf you just want to build the desktop app, package it or build installer without running the\n`Meteor` project separately you can just use `-b` and all will be done automatically - this is useful when\nfor example building on a CI etc.\n\n#### `--android`\nWhen there is no mobile platform in the project and `-b` is used, mobile platform is added\nautomatically and removed at the end of the build process. Normally an `ios` platform is added\nbut you can change this to `android` through this option.\n\nDocumentation\n=================\n  * [Architecture](#architecture)\n     * [How does this work with Meteor?](#how-does-this-work-with-meteor)\n     * [How the Electron app is structured?](#how-the-electron-app-is-structured)\n     * [Where is my app.on('ready')?](#where-is-my-apponready)\n  * [Scaffolding your desktop app](#scaffolding-your-desktop-app)\n     * [settings.json](#settingsjson)\n        * [Applying different window options for different OS](#applying-different-window-options-for-different-os)\n        * [Supported dependency version types](#supported-dependency-version-types)\n     * [desktop.js](#desktopjs)\n        * [skeletonApp](#skeletonapp)\n        * [eventsBus](#eventsbus)\n        * [modules](#modules)\n        * [Module](#module)\n  * [Writing modules](#writing-modules)\n     * [extract](#extract)\n  * [Hot code push support](#hot-code-push-support)\n  * [Meteor.isDesktop](#meteorisdesktop)\n  * [Accessing local filesystem in Meteor](#accessing-local-filesystem-in-meteor)\n  * [Accessing .desktop/assets in Meteor](#accessing-desktopassets-in-meteor)\n  * [\u003ccode\u003eDesktop\u003c/code\u003e and \u003ccode\u003eModule\u003c/code\u003e - communication between Meteor and Electron](#desktop-and-module)\n     * [Module - desktop side](#module---desktop-side)\n     * [Desktop - Meteor side](#desktop---meteor-side)\n  * [desktopHCP - .desktop hot code push](#desktophcp---desktop-hot-code-push)\n     * [How this works](#how-this-works)\n     * [Caveats](#caveats)\n  * [How to write plugins](#how-to-write-plugins)\n     * [meteorDependencies in \u003ccode\u003epackage.json\u003c/code\u003e](#meteordependencies-in-packagejson)\n        * [List of known plugins:](#list-of-known-plugins)\n  * [Squirrel autoupdate support](#squirrel-autoupdate-support)\n  * [Native modules support](#native-modules-support)\n  * [Testing desktop app and modules](#testing-desktop-app-and-modules)\n  * [MD_LOG_LEVEL](#md_log_level)\n  * [Packaging](#packaging)\n  * [Building installer](#building-installer)\n    * [Building for linux](#building-for-linux)\n    * [Building for Windows Store (AppX)](#building-for-windows-store-appx)\n  * [Roadmap](#roadmap)\n  * [Contribution](#contribution)\n  * [Built with meteor-desktop](#built-with-meteor-desktop)\n  * [FAQ](#faq)  \n  * [Changelog](CHANGELOG.md)\n\n## Architecture\n\nIf you have ever been using any `Cordova` plugins before you will find this approach alike. In `Cordova` every plugin exposes its native code through a JS api available in some global namespace like `cordova.plugins`. The approach used here is similar.\n\nIn `Electron` app, there are two processes running along in your app. The so-called `main\nprocess` and `renderer process`. Main process is just a JS code executed in `node`, and the\nrenderer is a `Chromium` process. In this integration your `Meteor` app is being run in the\n`renderer` process and your desktop specific code runs in the `main` process. They are\ncommunicating through IPC events. Basically, the desktop side publishes its API as an IPC event\nlisteners. In your `Meteor` code, calling it is as simple as `Desktop.send('module', 'event');`.  \n\nCode on the desktop side is preferred to be modular - that is just for simplifying testing and\nencapsulating functionalities into independent modules. However, you do not have to follow this style, there is an `import` dir in which you can structure your code however you want. The basics of an `Electron` app are already in place (reffered as `Skeleton App`) and your code is loaded like a plugin to it.\n\nBelow is a high level architecture diagram of this integration.\n\n![High level architecture](docs/high-level-arch.png)\n\n#### How does this work with Meteor?\n\u003e \u003csup\u003eor how hacky is this?\u003c/sup\u003e\n\nThe main goal was to provide a non hacky integration without actually submitting any desktop\noriented pull request to `Meteor`.\nThe whole concept is based on taking the `web.cordova` build, modifying it as little as possible\nand running it in the `Electron's` renderer process. The current `cordova` integration\narchitecture is more or less conceptually replicated.\n\nCurrently the only modification that the mobile build is subjected to is injecting the `Meteor.isDesktop` variable.\n\nTo obtain the mobile build, this integration takes the build from either\n`.meteor/local/cordova-build` (version `\u003c 1.3.4.1`) or from `.meteor/local/build/programs/web.cordova`.\nBecause `index.html` is not present in the `web.cordova` directory and `program.json` lacks\n`version` field, they are just downloaded from the running project.\n\n#### How the `Electron` app is structured?\n\nThe produced `Electron` app consists barely of 4 files:\n\n- `app.asar` - bundled `Skeleton App` and `node_modules` (including all your dependencies from\n`settings.json` and modules)\n- `meteor.asar` - your `Meteor` app bundled to an `.asar`\n- `desktop.asar` - processed contents from `.desktop`\n- `package.json` - `Electron` requires a `package.json` to be present\n\nWhile developing, the `app` is not asared so you can take a closer look at the `Skeleton` that is\n produced by this integration. You will find it in the `.meteor/desktop-build` directory.\n\n#### Where is my `app.on('ready')`?\n\nThe `app.on('ready')` is handled for you by the `Skeleton` app, but that does not mean you can\nnot hook into it. Basically, code that is in the constructor of `.desktop/desktop.js` and\nall constructors of your modules is executed while being inside `ready`. Remember that is always\na good practice not to do time consuming tasks inside the constructors but instead delay those tasks\nby hooking to `beforeDesktopJsLoad`, `desktopLoaded` or `afterInitialization` on the `eventsBus`.\n\n## Scaffolding your desktop app\n\nIf you have not run the example from the Quick start paragraph, first you need to scaffold a\n`.desktop` dir in which your `Electron's` main process code lives.\nTo do that run: (assuming `npm install --save-dev meteor-desktop` did add successfully a `desktop`\nentry in the `package.json scripts` section)\n```bash\nnpm run desktop -- init\n```\n\nThis will generate an exemplary `.desktop` dir. Lets take a look what we can find there:\n```\n.desktop\n├── assets                     # place all your assets here\n├── import                     # all code you do not want to structure into modules  \n├── modules                    # your desktop modules (check modules section for explanation)\n│    └── example               # module example\n│         ├── index.js         # entrypoint of the example module\n│         ├── example.test.js  # functional test for the example module\n│         └── module.json      # module configuration  \n├── desktop.js                 # your Electron main process entry point - treated like a module\n├── desktop.test.js            # functional test for you desktop app\n├── settings.json              # your app settings\n└── squirrelEvents.js          # handling of squirrel.windows events\n```\n\nTak a look into the files. Most of them have meaningful comments inside.\n\nSome files are described more in detail below..\n### settings.json\n\nThis is the main configuration file for your desktop app.\nBelow you can find brief descriptions of the fields.\n\nfield|description\n-----|-----------\n`name`|just a name for your project\n`version`|version of the desktop app\n`projectName`|this will be used as a `name` in the generated app's package.json\n`devTools`|whether to install and open `devTools`, set automatically to false when building with `--production`\n`singleInstance`|sets the single instance mode - [more](https://github.com/electron/electron/blob/master/docs/api/app.md#appmakesingleinstancecallback)\n`desktopHCP`|whether to use `.desktop` hot code push module - [more](#desktophcp---desktop-hot-code-push)\n\u003csup\u003e`desktopHCPIgnoreCompatibilityVersion`\u003c/sup\u003e|ignore the `.desktop` compatibility version and install new versions even if they can be incompatible\n`desktopHCPCompatibilityVersion`|allows to override `.desktop` compatibility version\n`squirrel.autoUpdateFeedUrl`| \u003csup\u003eDEPRECATED\u003c/sup\u003e url passed to [`autoUpdater.setFeedUrl`](https://github.com/electron/electron/blob/master/docs/api/auto-updater.md#autoupdatersetfeedurlurl-requestheaders), [more](#squirrel-autoupdate-support)\n`squirrel.autoUpdateFeedHeaders`| \u003csup\u003eDEPRECATED\u003c/sup\u003e http headers passed to [`autoUpdater.setFeedUrl`](https://github.com/electron/electron/blob/master/docs/api/auto-updater.md#autoupdatersetfeedurlurl-requestheaders)\n`squirrel.autoUpdateCheckOnStart`| \u003csup\u003eDEPRECATED\u003c/sup\u003e whether to check for updates on app start\n`rebuildNativeNodeModules`|turn on or off recompiling native modules, [more](#native-modules-support)\n`webAppStartupTimeout`|amount of time after which the downloaded version is considered faulty if Meteor app did not start - [more](#hot-code-push-support)\n`exposeLocalFilesystem`|turns on or off local filesystem exposure over url alias, [more](#accessing-local-filesystem-in-meteor)\n`exposedModules`|array of module names, exposes any renderer modules in `Desktop.electron` space, i.e. list `webFrame` here to acess it via `Desktop.electron.webFrame` in Meteor project code\n`showWindowOnStartupDidComplete`|normally, main window appears after Chromes `did-stop-loading` event, set this to `true` if you want to depened on Meteor's `startupDidComplete` event\n`window`|production options for the main window - see [here](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#new-browserwindowoptions)\n`windowDev`|development options for the main window, applied on top of production options\n`uglify`|whether to process the production build with uglify\n`plugins`|meteor-desktop plugins list\n`dependencies`|npm dependencies of your desktop app, the same like in `package.json`, only explicit versions are supported - check [here](#supported-dependency-version-types)\n`linkPackages`|array of packages names you want to link (runs `npm link \u003cpackageName\u003e` for every package listed)\n`packageJsonFields`|fields to add to the generated `package.json` in your desktop app\n`builderOptions`|[`electron-builder`](https://github.com/electron-userland/electron-builder) [options](https://github.com/electron-userland/electron-builder/wiki/Options)\n`builderCliOptions`|specify additional electron-builder CLI options e.g for [publishing artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts)\n`packagerOptions`|[`electron-packager`](https://github.com/electron-userland/electron-packager) [options](https://github.com/electron-userland/electron-packager/blob/master/docs/api.md)\n`extract`|array containing dependencies that should not be packed into asar (should not be needed as there is an automatic algorithm that will exclude all dependencies containing binary files)\n\n##### Applying different window options for different OS\n\nYou can use `_windows`, `_osx`, `_linux` properties to set additional settings for different OS.\nThe default `settings.json` is already using that for setting a different window icon for OSX.\n\n##### Supported dependency version types\n\nOnly explicit versions are supported to avoid potential problems with different versions being\ninstalled. It is no different from `Meteor` because the same applies to adding `Cordova` plugins.\n\nYou can however use a local path to a npm package - and that will not be forbidden. **You need**\nto keep track what has been distributed to your clients and what your current code is expecting\nwhen releasing a HCP update.\n\n### desktop.js\n\nThe `desktop.js` is the entrypoint of your desktop app. Let's take a look what references we\nreceive in the constructor.\n```javascript\n    /**\n     * @param {Object} log         - Winston logger instance\n     * @param {Object} skeletonApp - reference to the skeleton app instance\n     * @param {Object} appSettings - settings.json contents\n     * @param {Object} eventsBus   - event emitter for listening or emitting events\n     *                               shared across skeleton app and every module/plugin\n     * @param {Object} modules     - references to all loaded modules\n     * @param {Object} Module      - reference to the Module class\n     * @constructor\n     */\n    constructor({ log, skeletonApp, appSettings, eventsBus, modules, Module })\n```\nSome of the references are describe in detail below:\n\n#### `skeletonApp`\n\nThis is a reference to the Skeleton App. Currently there are only two methods you can call.  \n`isProduction` - whether this is a production build  \n`removeUncaughtExceptionListener` - removes the default handler so you can put your own in place\n\n#### `eventsBus`\n\nThis is just an `EventEmitter` that is an event bus meant to be used across all entities running\nin the `Electron's` main process (`.desktop`). Currently there are several events emitted on the\nbus by the `Skeleton App` that you may find useful:\n\nevent name|payload|description\n----------|-------|------------\n`unhandledException`| |emitted on any unhandled exceptions, by hooking to it you can run code before any other handler will be executed   \n`beforePluginsLoad`| |emitted before plugins are loaded\n`beforeModulesLoad`| |emitted before internal modules and modules from `.desktop` are loaded\n`beforeDesktopJsLoad`| |emitted before `desktop.js` is loaded\n`beforeLocalServerInit`| |emitted before local http server starts\n`desktopLoaded`|`(desktop)`|emitted after loading `desktop.js`, carries the reference to class instance exported from it\n`afterInitialization`| |emitted after initialization of internal modules like HCP and local HTTP server\n`startupFailed`| |emitted when the `Skeleton App` could not start you `Meteor` app  \n`beforeLoadFinish`| |emitted when the `Meteor` app finished loading, but just before the window is shown  \n`loadingFinished`| |emitted when the `Meteor` app finished loading (also after HCP reload)  \n`windowSettings`|`(windowSettings)`|emitted with the settings that will be passed to [`BrowserWindow`](https://github.com/electron/electron/blob/master/docs/api/browser-window.md) constructor - if needed the object can be modified in the event handler to override window settings from `settings.json`  \n`windowCreated`|`(window)`|emitted when the [`BrowserWindow`](https://github.com/electron/electron/blob/master/docs/api/browser-window.md) (`Chrome` window with `Meteor` app) is  created, passes a reference to this window\n`newVersionReady`|`(version, desktopVersion)`|emitted when a new `Meteor` bundle was downloaded and is ready to be applied  \n`revertVersionReady`|`(version)`|emitted just before the `Meteor` app version will be reverted (due to faulty version fallback mechanism) be applied  \n`beforfeLoadUrl`|`(port, lastPort)`|emitted before `webContents.loadURL` is invoked, in other words just before loading the Meteor app; `port` - the port on which the app is served, `lastPort` - the port on which the app was served previously (when HCP is applied)\n`beforeReload`|`(pendingVersion, containsDesktopUpdate)`|emitted just before HCP reload\n`moduleLoadFailed`|`(dirName, error)`|emitted if a module failed to load\n`childWindow`|`(openWindowHandlerResult, details)`| emitted when child window is created. Gives possibility to reject or set up BrowserWindowConstructorOptions. For details see [setWindowOpenHandler](https://www.electronjs.org/docs/latest/api/web-contents#contentssetwindowopenhandlerhandler)\n\nYour can also emit events on this bus as well. A good practice is to namespace them using dots,\nlike for instance `myModule.initalized`.\n\n#### `modules`\n\nObject with references to other modules and plugins. Plugins can be found under their names i.e.,\n`modules['meteor-desktop-splash-screen]`.  \nAny module can be found under the name from `module.json`.\nInternal modules such as `autoupdate` and `localServer` are also there. You can also get reference to the `desktop.js` from `modules['desktop']` (note that the reference is also passed in\nthe `desktopLoaded` event).\n\n#### `Module`\n\nClass that provides a way of defining API reachable by `Meteor` app - [more](#module---desktop-side).\n\n## Writing modules\n\nModule is just an encapsulated piece of code. Usually you would just provide certain type of\ngrouped functionality in it. You can treat it like a plugin to your desktop app.  \nOne important rule is that you should not import files from the outside of your module directory\nas this will cause you problems when writing tests.  \nYou can always reach to other modules through `modules` and you can as well add a module with\n some common code or utils.\nEvery module lives in its own directory and has to have a `module.json` file. Currently there are\n only four fields there supported:\n- `name` - name of your module, will be used as a key in `modules` object\n- `dependencies` - list of npm deps\n- `extract` - list of files that should be excluded from packing into `.asar` (e.g. executables,\nfiles meant to be changed etc)\n- `settings` - this object is passed as `settings` field in the object passed to module constructor\n\n#### `extract`\nA little bit more about this. Files should be listed in a form of relative path to the module\ndirectory without any leading slashes, for example `extract: [ \"dir/something.exe\" ]` will be\nmatched to `.desktop/modules/myModule/dir/something.exe`.\n\nTo path to your extracted files is added to your module `settings` as `extractedFilesPath`\n. So your module constructor can look like this:\n```javascript\nimport path from 'path';\nexport default class Desktop {\n    constructor({ log, skeletonApp, appSettings, eventsBus, modules, settings, Module }) {\n        this.pathToExe = path.join(settings.extractedFilesPath, 'dir/something.exe');\n    }\n}\n```\n**WARNING:** currently the path of the file is not reconstructed meaning `extract: [ \"dir1/something.exe\", \"dir2/something.exe' ]` will try to put both `something.exe` files to the same dir and that may fail or produce inconsistent result. So the bare file names without the path must be unique.\n\n## Hot code push support\n\nApplications produced by this integration are fully compatible with `Meteor`'s hot code push\nmechanism.  \nThe faulty version recovery is also in place - [more about it here](https://guide.meteor.com/mobile.html#recovering-from-faulty-versions). You can configure the timeout via\n`webAppStartupTimeout` field in `settings.json`.  \n\nVersions are downloaded and served from [`userData`](https://github.com/electron/electron/blob/master/docs/api/app.md#appgetpathname) directory.\nThere you can find `autoupdate.json` and `versions` dir. If you want to return to first\nbundled version just delete them.\n\nYou can also analyze `autoupdate.log` if you are experiencing any issues.\n\n## `Meteor.isDesktop`\n\nIn your `Meteor` app to run a part of the code only in the desktop context you can use `Meteor.isDesktop`. Use it the same way you would use `Meteor.isClient` or `Meteor.isCordova`.\n\n## Accessing local filesystem in Meteor\n\nLocal filesystem is exposed under and url alias (similarly to [Cordova integration](https://guide.meteor.com/mobile.html#accessing-local-files)).\nThis feature is disabled by default so you need to enable it first by setting\n`exposeLocalFilesystem` in your `settings.json` to `true`. Files are exposed under\n`/local-filesystem/\u003cabsolute-path\u003e` url.\n\nYou can use some convenience methods:\n- **`Desktop.getFileUrl(absolutePath)`** - returns an url to a file\n- **`Desktop.fetchFile(absolutePath)`** - invokes `fetch` on a file's url and returns it's\n`Promise`\n\n## Accessing `.desktop/assets` in Meteor\n\nAssets are exposed over an url alias `\\___desktop\\\u003casset-path\u003e`.\nSo to display an image named `test.png` from `.desktop/assets` you should use a\n`\\___desktop\\test.png` url.\n\nYou can use some convenience methods:\n- **`Desktop.getAssetUrl(assetPath)`** - returns an asset's url\n- **`Desktop.fetchAsset(assetPath)`** - invokes `fetch` on an asset's url and returns it's\n`Promise`\n\n## `Desktop` and `Module` - communication between Meteor and Electron\n\n### `Module` - desktop side\nUse it to declare your API on the desktop side which you can later call from Meteor project.\n```javascript\n    this.module = new Module('myModuleName');\n```\n[Documentation of the Module API](docs/api/module.md) - basically, it reflects [`ipcMain`](https://github.com/electron/electron/blob/master/docs/api/ipc-main.md).  \n\nThe only two additions are the `fetch` and `respond` methods:\n - **fetch```(event, timeout = 2000, ...args)```** - like send but returns a `Promise` that resolves to a response, timeouts after 2000ms by default\n - **call```(module, ...args)```** - `fetch` but without the need specify timeout\n - **setDefaultFetchTimeout```(timeout)```** - set the default timeout for `fetch` within this module\n - **respond```(event, fetchId, ...data)```** is a convenient method of sending response to `Desktop.fetch`. The `fetchId` is always the second argument received in `on`.  \nHere is an [usage example](https://github.com/wojtkowiak/meteor-desktop-localstorage/blob/master/src/index.js#L31).\n\n### `Desktop` - Meteor side\n[Documentation of the Desktop API](docs/api/desktop.md) - reflects partially [`ipcRenderer`](https://github.com/electron/electron/blob/master/docs/api/ipc-renderer.md)\u003csup\u003e*\u003c/sup\u003e.    \n\n\u003csup\u003e* `sendSync` and `sendToHost` are not available\u003c/sup\u003e\n\nUse it to call and listen for events from the desktop side.\n\nThe only difference is that you always need to precede arguments with module name.\nThere are two extra methods:  \n- **fetch```(module, event, timeout = 2000, ...args)```** - like send but returns a `Promise` that resolves to a response, timeouts after 2000ms by default\n- **call```(module, event, ...args)```** - `fetch` but without the need specify timeout\n- **setDefaultFetchTimeout```(timeout)```** - set the default timeout for `fetch`\n- **respond```(module, event, fetchId, ...data)```** is a convenient method of sending response to `Module.fetch`. The `fetchId` is always the second argument received in `on`.  \n- **sendGlobal** - alias for `ipcRenderer.send` - if you need to send an IPC that is not namespaced\n\nExample of `send` and `fetch` usage - [here](https://github.com/wojtkowiak/meteor-desktop-localstorage/blob/master/plugins/localstorage/localstorage.js#L9).  \n\n## desktopHCP - `.desktop` hot code push\n\u003e #### experimental!\n\nThere is an experimental support for hot code push of the `.desktop` directory.  \nIt works similarly to the `Meteor`'s builtin one. It also produces a `version` and\n`compatibilityVersion` to detect whether the update can be made.  \nIn `Meteor` whenever you change any of your `Cordova` dependencies (add/remove/change version)\nyou will make an incompatible change meaning that a new version will not be hot code pushed.  \nThe same applies here. In this case your desktop dependencies are npm packages.   \nTo make it clear, **npm packages are not hot code pushed** - only contents of `.desktop` are.\n\nThe `compatibilityVersion` is calculated from combined list of:\n - dependencies from `settings.json`\n - plugins from `settings.json`\n - dependencies from all modules in `.desktop/modules`\n - major version of `meteor-desktop` (X.Y.Z - only X is taken)\n - major version from `settings.json` (X.Y.Z - only X is taken).\n\nBe aware that when it comes to linked packages (via `linkPackages` in `settings.json`) the\nexplicitly declared version (the one in `settings.json` or modules) is taken into account, not the\nactual one from package's package.json. The same applies to packages added from local paths.  \nGenerally, it is a bad idea to build production app with linked/local packages. Changes in those will not trigger a compatibility version change so you migh accidentally push a new version with `desktopHCP` that will not work.\n\n\n#### How this works\nTwo Meteor plugins are added to your project - bundler and watcher. Bundler prepares the `desktop.asar` which is then added to you project as an asset.   \nWatcher just watches for file changes and triggers project rebuilds.   \n\n#### Caveats\n- desktop app needs to be restarted when a new bundle is applied\n- the bundled desktop app goes over normal HCP mechanism meaning that a `desktop.asar` file will\nalso be\ndistributed to your mobile clients and cause unnecessary updates in case you only made changes in\n `.desktop`\n- files that are excluded from `desktop.asar` (via `extract` settings in a desktop module) are\nnot updated, nor checked for changes!\n- if you had errors (i.e. syntax) in `.desktop` which prevented startup, watcher might not work correctly and further changes\n in `.desktop` will not trigger rebuilds, in that case you need to make any\nchange in `version` field in the `desktop.version` to trigger rebuild (this file is in the root of\nyour project) - this can be any change like just adding random char to the hash\n- after reload logs will no longer be shown in the console\n\n## How to write plugins\n\nPlugin is basically a module exported to a npm package. `module.json` is not needed and not taken\n into account because `name` and `dependencies` are already in `package.json`. Also you can not use\n the `extract` functionality as that only works in modules. Plugin `settings` are set and taken\n from the `plugins` section of `settings.json`. [Here](scaffold/settings.json#L26) is an example of passing settings to splash\n screen plugin.\n\n While developing you will probably need to make use of `linkPackages` in `settings.json`, so that\n your npm-packaged plugin would be linked instead of downloaded. However the advised approach is\n to make the development test driven - meaning that you should make your tests the main way of\n verifying whether the plugin does what it should.\n#### `meteorDependencies` in `package.json`\nOne extra feature is that you can also depend on Meteor packages through `meteorDependencies`\nfield in `package.json`. Check out [`meteor-desktop-localstorage`](https://github.com/wojtkowiak/meteor-desktop-localstorage/blob/master/package.json#L52) for example.  \nA good practice when your plugin contains a meteor plugin is to publish both at the same version.\nYou can then use `@version` in the `meteorDependecies` to indicate that the Meteor plugin's\nversion should be equal to npm package version.\n\nIf you made a plugin, please let us know so that it can be listed here.\n##### List of known plugins:\n[`meteor-desktop-system-notifications`](https://github.com/tzapu/meteor-desktop-system-notifications)  \n[`meteor-desktop-splashscreen`](https://github.com/wojtkowiak/meteor-desktop-splash-screen)  \n[`meteor-desktop-localstorage`](https://github.com/wojtkowiak/meteor-desktop-localstorage) (deprecated, do not use from `1.0.0`)  \n\n## Squirrel autoupdate support (DEPRECATED)\n\nSquirrel Window and OSX autoupdates are supported. So far the only tested server is\n[`electron-release-server`](https://github.com/ArekSredzki/electron-release-server) and the\ndefault url `http://127.0.0.1/update/:platform/:version` provided in `settings.json` assumes you\nwill be using it.  \nThe `:platform` and `:version` tags are automatically replaced by correct values.   \nYou can hook into Squirrel Windows events in `squirrelEvents.js` in `.desktop`.\n\nMore:  \nhttps://github.com/electron/electron/blob/master/docs/api/auto-updater.md  \nhttps://github.com/ArekSredzki/electron-release-server\n\n## Native modules support\n\nThis integration fully supports rebuilding native modules (npm packages with native node modules)\n against `Electron's` `node` version. The mechanism is enabled by default.\n\n## Testing desktop app and modules\n\nFor unit tests you should not have problems with using [electron-mocha](https://github.com/jprichardson/electron-mocha).  \nFor functional testing [Spectron](http://electron.atom.io/spectron) should be used.\n\nThere are two exemplary tests present in the default scaffold. Check them out as they have some\ncomments in them.  \nTo run them you need to init functional test support by invoking:\n```\nnpm run desktop -- init-tests-support\n```\nTwo tasks should be added to your `scripts` section: `test-desktop` and `test-desktop-watch`.\nFeel free to run the tests with: `npm run test-desktop`.\n\nFor testing modules there is a [test suite](https://github.com/wojtkowiak/meteor-desktop-test-suite) available.\nIt is used extensively in the plugins (splash screen \u0026 localstorage) tests so you can check there\nfor more examples.\n\n## `MD_LOG_LEVEL`\n`MD_LOG_LEVEL` env var is used to set the logger verbosity. It is set to\n`ALL` by default but you can change it to any of `INFO, WARN, ERROR, DEBUG, VERBOSE, TRACE`. You can also\nselect multiple levels joining them with a comma, for example: `INFO,WARN`.\n\n## Packaging\n\n`npm run desktop -- package \u003cddp-url\u003e`\n\nThis produces a package using [`electron-packager`](https://github.com/electron-userland/electron-packager).  \nPackage is produced and saved in `.desktop-package` directory. You can pass options via `packagerOptions` in\n`settings.json`.\n\n## Building installer\n\n`npm run desktop -- build-installer \u003cddp-url\u003e`\n\nThis packages and builds installer using [`electron-builder`](https://github.com/electron-userland/electron-builder).  \nInstaller is produced and saved in `.desktop-installer` directory. You can pass options via\n`builderOptions` in `settings.json`.  \nIf you do not pass any target platforms via `--win`, `--linux` or `--mac` it will build for your\ncurrent platform. If at least one the platform is specified, the current platform will not be\nadded automatically. So if you want to build Windows and Mac at the same time, being on Mac,\nyou need to pass `--win --mac`, not only `--win`. To check what targets you can build on certain platform and what does it require\ncheck [Multi-Platform-Build](https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Build)\n\nPlease note that `electron-builder` does not use `electron-packager` to create a package. So the\noptions from `packagerOptions` are not taken into account.\n\n##### Building for linux\nCurrently there are some defaults provided only for `Windows` and `Mac`. If you want to build for\n `Linux` you need to add a [`linux`](https://github.com/electron-userland/electron-builder/wiki/Options#LinuxBuildOptions) section in your `builderOptions` and comply to these\n [requirements](https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Build#linux).\n\n##### Building for Windows Store (AppX)\nChange `target: [\"appx\"]` in `win` section of `builderOptions`. In case of problems please refer to\n[electron-builder](https://github.com/electron-userland/electron-builder) documentation.\n\n## Developing meteor-desktop\n\nNo matter which method below you choose, run `npm run build-watch` in your local meteor-desktop folder before making changes to the code, if you want them reflected in Meteor apps that depend on the package.\n\n### Using devEnvSetup.js\nTo help you contribute, there is a development environment setup script. It also runs default tests.\n\nThis script assumes you have `npm`, `git` and `meteor` available from the command line. Note that by default, the script will install packages in the *parent* directory of where it is, so it is recommended to clone meteor-desktop inside an empty dir.\n\n```bash\nmkdir meteor-desktop-dev \u0026\u0026 cd meteor-desktop-dev\ngit clone https://github.com/Meteor-Community-Packages/meteor-desktop.git\ncd meteor-desktop\nnpm install\nnode devEnvSetup.js\n```\n\n### Without using devEnvSetup.js\n\n1. Clone and install meteor-desktop as above\n2. From a clean Meteor project, install meteor-desktop from its local folder: `meteor npm i --save-dev /path/to/meteor-desktop` (doesn't work with npm link, tbc)\n3. In your Meteor app's `package.json`:\n   1. Add a script `desktop` with `METEOR_PACKAGE_DIRS=/path/to/meteor-desktop/plugins node /path/to/meteor-desktop/dist/bin/cli.js`\n   2. Add `METEOR_PACKAGE_DIRS=/path/to/meteor-desktop/plugins` to the `start` script as well.\n\nThe last step is so that the desktop HCP Meteor packages are also taken from your local meteor-desktop repo. \nMake sure to run Meteor with `meteor npm start` rather than just `meteor`.\n\nFinally, follow the above \"Quick start\" steps (except the npm install) from your Meteor app.\n\n## Built with `meteor-desktop`\n\nBuilt an app using meteor-desktop? File an issue or PR to list it here.\n\n* [Coygo](https://www.coygo.app) - Multi-exchange cryptocurrency and digital asset trading tool\n\n## FAQ\n\n\u003e How to disable `zip` building when using `build-installer` on OSX.\n\nAdd `target: [\"dmg\"]` to `mac` section of `builderOptions`.\n\n## Changelog\n\nis [here](CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeteor-community-packages%2Fmeteor-desktop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeteor-community-packages%2Fmeteor-desktop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeteor-community-packages%2Fmeteor-desktop/lists"}