{"_id":"@aabuhijleh/electron-remote","_rev":"1-12d3127d019276a9bebbd8a65cd490e0","name":"@aabuhijleh/electron-remote","dist-tags":{"latest":"1.4.0"},"versions":{"1.4.0":{"name":"@aabuhijleh/electron-remote","version":"1.4.0","description":"Execute JavaScript in remote Electron processes, but more betterer","scripts":{"doc":"esdoc -c ./esdoc.json","compile":"git clean -xdf ./lib && babel -d lib/ src/ && cp ./src/*.html ./lib/","prepublish":"npm run compile","test-renderer":"electron-mocha --renderer --require ./test/support.js ./test","test-browser":"electron-mocha --require ./test/support.js ./test/renderer-require","test":"npm run test-renderer && npm run test-browser","node":"cross-env ELECTRON_RUN_AS_NODE=1 ./node_modules/electron-prebuilt-compile/node_modules/.bin/electron"},"repository":{"type":"git","url":"git+https://github.com/paulcbetts/electron-remote.git"},"keywords":["remote","electron","rx"],"author":{"name":"Paul Betts","email":"paul@paulbetts.org"},"license":"MIT","bugs":{"url":"https://github.com/paulcbetts/electron-remote/issues"},"main":"lib/index.js","homepage":"https://github.com/paulcbetts/electron-remote","dependencies":{"debug":"^2.5.1","hashids":"^1.1.1","lodash.get":"^4.4.2","pify":"^2.3.0","rxjs":"^5.0.0-beta.12","xmlhttprequest":"^1.8.0"},"devDependencies":{"babel-cli":"^6.16.0","babel-eslint":"^7.0.0","babel-plugin-transform-async-to-generator":"^6.16.0","babel-plugin-transform-runtime":"^6.15.0","babel-preset-es2016-node5":"^1.1.2","babel-register":"^6.16.3","chai":"^3.5.0","chai-as-promised":"^6.0.0","cross-env":"^3.0.0","electron-mocha":"^6.0.3","electron-prebuilt-compile":"4.0.0","esdoc":"^1.1.0","esdoc-es7-plugin":"0.0.3","esdoc-plugin-async-to-sync":"^0.5.0","eslint":"^3.7.1"},"directories":{"lib":"lib","test":"test"},"gitHead":"b5c1f21d0cd528388f0d35b1a2cbe94ce0ca8256","_id":"@aabuhijleh/electron-remote@1.4.0","_nodeVersion":"12.5.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-EG4ZXxqbFY4lpX55vctwz14mFrEOcOHFCMLH5z5lOl6fiviTqscy86tSlKwEE3/o3ExtdPr2tECgCogYYL7d+g==","shasum":"bd5a7eb150fd4ef2ab0eaa31f392e5f6ac488835","tarball":"https://registry.npmjs.org/@aabuhijleh/electron-remote/-/electron-remote-1.4.0.tgz","fileCount":38,"unpackedSize":120582,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdKskrCRA9TVsSAnZWagAAQlIP/1g9HaAOxZgORBiYFOnr\ns+13BxZ3R0huZMf4L4/objI4hTuhQP74DkvHzhQXAE/aeWH3/NkdM1J9+Z1E\n87xuhWKgROSqeFk/osLdnRvA+FADh9GPXZ+eaSUzc4liZD6x83cNo75ZRR6V\nMKXYSCxyHqYpZszTrHDEQcTLbLen3Qf55UzigTMH9anEc++jMSU8DPRhu6PG\n4ztyBOlhSKsFL2rkAurDByJB5b+0mTPN9AvYFWoIe32STCGIKeuP+cW39otk\nklXV8lJITNSDf2H2Xwbb0NpQr9KfJx0qt+ZwFkopVHoK0HN+8z/4dagvp1uB\nmBw9slrx+FW5NY+EsaqG/fl1Oe9Haf6ze7RlNZQdzjMHerf9Z9lpJPr+zGXJ\nOSZOgnkARSeMV4znqtGo3LNE5tqwGQB9Mum24QDgFRrlvPVR6UMVShoVU9DM\nCyLpFwBm6n6CuX5hNhyKqkAPr6JcGol7cqPOjzo5cUPgThNb2gZr9/E5/Ava\nyGTfgwsoiA50RqPTgqM4sawVpXrh9gPRPiJ3B71V4hqoyaWaE/v6fyIJNm3S\nK4WMe00g3qkEC938+Qhz53VuCD3MdAvBiBR5KnJNVVsKO1PbmYtvcOtN2/qx\n5sI72PxPE6/y69yI2xL50g14VJc+gsSOXCZW1EoqF4ONLow6yxEuWGRKYAec\neJqZ\r\n=NBkJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAGeaTs2oEHSLDYefBvzUyXCt5SNgGCUoYB8cORr8Ts1AiAq8/JGJEhIgV1Eo3QHVQ4R86c8UIj9BVavQlOxngS31A=="}]},"maintainers":[{"name":"aabuhijleh","email":"aabuhijleh@asaltech.com"}],"_npmUser":{"name":"aabuhijleh","email":"aabuhijleh@asaltech.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/electron-remote_1.4.0_1563085098866_0.6484517817176061"},"_hasShrinkwrap":false}},"time":{"created":"2019-07-14T06:18:18.664Z","1.4.0":"2019-07-14T06:18:19.001Z","modified":"2022-04-04T10:54:52.580Z"},"maintainers":[{"name":"aabuhijleh","email":"aabuhijleh@asaltech.com"}],"description":"Execute JavaScript in remote Electron processes, but more betterer","homepage":"https://github.com/paulcbetts/electron-remote","keywords":["remote","electron","rx"],"repository":{"type":"git","url":"git+https://github.com/paulcbetts/electron-remote.git"},"author":{"name":"Paul Betts","email":"paul@paulbetts.org"},"bugs":{"url":"https://github.com/paulcbetts/electron-remote/issues"},"license":"MIT","readme":"# DEPRECATED: electron-remote: an asynchronous 'remote', and more\r\n\r\n[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)\r\n\r\nThis project is no longer maintained, pull requests are no longer being reviewed or merged and issues are no longer being responded to. \r\n\r\n---\r\n\r\n![](https://img.shields.io/npm/dm/electron-remote.svg) <a href=\"http://paulcbetts.github.io/electron-remote/docs\">![](http://paulcbetts.github.io/electron-remote/docs/badge.svg)</a>\r\n\r\n\r\nelectron-remote provides an alternative to Electron's `remote` module based around Promises instead of synchronous execution. It also provides an automatic way to use BrowserWindows as \"background processes\" that auto-scales based on usage, similar to Grand Central Dispatch or the .NET TPL Taskpool.\r\n\r\n## The Quickest of Quick Starts\r\n\r\n###### Calling main process modules from a renderer\r\n\r\n```js\r\nimport { createProxyForMainProcessModule } from 'electron-remote';\r\n\r\n// app is now a proxy for the app module in the main process\r\nconst app = createProxyForMainProcessModule('app');\r\n\r\n// The difference is all methods return a Promise instead of blocking\r\nconst memoryInfo = await app.getAppMemoryInfo();\r\n```\r\n\r\n###### Calling code in other windows\r\n\r\n```js\r\nimport { createProxyForRemote } from 'electron-remote';\r\n\r\n// myWindowJs is now a proxy object for myWindow's `window` global object\r\nconst myWindowJs = createProxyForRemote(myWindow);\r\n\r\n// Functions suffixed with _get will read a value\r\nuserAgent = await myWindowJs.navigator.userAgent_get()\r\n```\r\n\r\n###### Renderer Taskpool\r\n\r\n```js\r\nimport { requireTaskPool } from 'electron-remote';\r\n\r\nconst myCoolModule = requireTaskPool(require.resolve('./my-cool-module'));\r\n\r\n// This method will run synchronously, but in a background BrowserWindow process\r\n// so that your app will not block\r\nlet result = await myCoolModule.calculateDigitsOfPi(100000);\r\n```\r\n\r\n## But I like Remote!\r\n\r\nRemote is super convenient! But it also has some downsides - its main downside is that its action is **synchronous**. This means that both the main and window processes will _wait_ for a method to finish running. Even for quick methods, calling it too often can introduce scroll jank and generally cause performance problems.\r\n\r\nelectron-remote is a version of remote that, while less ergonomic, guarantees that it won't block the calling thread.\r\n\r\n## Using createProxyForRemote\r\n\r\n`createProxyForRemote` is a replacement for places where you would use Electron's `executeJavaScript` method on BrowserWindow or WebView instances - however, it works a little differently. Using a new feature in ES2015 called [proxy objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), we create an object which represents the `window` object on a remote context, and all method calls get sent as messages to that remote instead of being run immediately, which feels very similar to the `remote` Electron module.\r\n\r\nThis provides a number of very important advantages:\r\n\r\n* `createProxyForRemote` uses asynchronous IPC instead of blocking\r\n* Parameters are serialized directly, so you don't have to try to build strings that can be `eval`d, which is a dangerous endeavor at best.\r\n* Calling methods on objects is far more convenient than trying to poke at things via a remote eval.\r\n\r\n#### How do I get properties if everything is a Promise tho???\r\n\r\nAstute observers will note, that getting the value of a property is always a synchronous operation - to facilitate that, any method with `_get()` appended to it will let you fetch the value for the property.\r\n\r\n```js\r\nimport { createProxyForRemote } from 'electron-remote';\r\n\r\n// myWindowJs is now a proxy object for myWindow's `window` global object\r\nconst myWindowJs = createProxyForRemote(myWindow);\r\n\r\n// Functions suffixed with _get will read a value\r\nmyWindowJs.navigator.userAgent_get()\r\n  .then((agent) => console.log(`The user agent is ${agent}`));\r\n```\r\n\r\n#### But do this first!\r\n\r\nBefore you use `createProxyForRemote`, you **must** call `initializeEvalHandler()` in the target window on startup. This sets up the listeners that electron-remote will use.\r\n\r\n#### Bringing it all together\r\n\r\n```js\r\n// In my window's main.js\r\ninitializeEvalHandler();\r\nwindow.addNumbers = (a,b) => a + b;\r\n\r\n\r\n// In my main process\r\nlet myWindowProxy = createProxyForRemote(myWindow);\r\nmyWindowProxy.addNumbers(5, 5)\r\n  .then((x) => console.log(x));\r\n\r\n>>> 10\r\n```\r\n\r\n#### Using createProxyForMainProcessModule\r\nThis is meant to be a drop-in replacement for places you would have used `remote` in a renderer process. It's almost identical to `createProxyForRemote`, but instead of `eval`ing JavaScript it can only call methods on main process modules. It still has all the same benefits: asynchronous IPC instead of an `ipc.sendSync`.\r\n\r\n## Here Be Dragons\r\n\r\nelectron-remote has a number of significant caveats versus the remote module that you should definitely be aware of:\r\n\r\n* Remote values must be Serializable\r\n\r\nObjects that you return to the calling process must be serializable (i.e. you can call `JSON.stringify` on it and get a valid thing)- this means that creating Classes won't work, nor will return objects like BrowserWindows or other Electron objects. For example:\r\n\r\n```js\r\nlet myWindowProxy = createProxyForRemote(myWindow);\r\n\r\n// XXX: BAD - HTML elements aren't serializable\r\nlet obj = myWindowProxy.document.createElement('h1');\r\n```\r\n\r\n* Remote event listeners aren't supported\r\n\r\nAnything that involves an event handler isn't going to work:\r\n\r\n```js\r\n// XXX: BAD - You can't add event handlers\r\nmyWindowProxy.document.addEventListener('onBlur', (e) => console.log(\"Blur!\"));\r\n```\r\n\r\n## The Renderer Taskpool\r\n\r\nRenderer Taskpools provide an automatic way to use BrowserWindows as \"background processes\" that auto-scales based on usage, similar to Grand Central Dispatch or the .NET TPL Taskpool. This works by allowing you to provide a Module that you'd like to load in the remote processes, which will be loaded and unloaded on the fly according to demand.\r\n\r\nLet's look at the example again:\r\n\r\n```js\r\nimport { requireTaskPool } from 'electron-remote';\r\n\r\nconst myCoolModule = requireTaskPool(require.resolve('./my-cool-module'));\r\n\r\n// This method will run synchronously, but in a background BrowserWindow process\r\n// so that your app will not block\r\nlet result = await myCoolModule.calculateDigitsOfPi(100000);\r\n```\r\n\r\nBy default, `requireTaskPool` will create up to four background processes to concurrently run JS code on. As these processes become busy, requests will be queued to different processes and wait in line implicitly.\r\n\r\n##### More Dragons\r\n\r\nSince `requireTaskPool` will create and destroy processes as needed, this means that global variables or other state will be destroyed as well. You can't rely on setting a global variable and having it persist for a period of time longer than one method call.\r\n\r\n## The remote-ajax module\r\n\r\nOne module that is super useful to have from the main process is a way to make network requests using Chromium's networking stack, which correctly does things such as respecting the system proxy settings. To this end, electron-remote comes with a convenient wrapper around Rx-DOM's AJAX methods called `remote-ajax`.\r\n\r\n```js\r\nimport { requireTaskPool } from 'electron-remote';\r\n\r\nconst remoteAjax = requireTaskPool(require.resolve('electron-remote/remote-ajax'));\r\n\r\n// Result is the object that XmlHttpRequest gives you\r\nlet result = await remoteAjax.get('https://httpbin.org/get');\r\nconsole.log(result.url)\r\n\r\n>>> 'https://httpbin.org/get'\r\n```\r\n\r\nSee the documentation for [Rx-DOM](https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/modules/main-ajax/readme.md) for how these methods work.\r\n\r\nAnother method that is included is `downloadFileOrUrl`, which lets you download a file to a target:\r\n\r\n```js\r\n/**\r\n * Downloads a path as either a file path or a HTTP URL to a specific place\r\n *\r\n * @param  {string} pathOrUrl   Either an HTTP URL or a file path.\r\n * @return {string}             The contents as a UTF-8 decoded string.\r\n */\r\nfunction downloadFileOrUrl(pathOrUrl, target)\r\n```\r\n","readmeFilename":"README.md"}