Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

IPeeSee (Inter-process communication)

IPeeSee is a JS module built for the sake of easing the pain while working with native IPC implementation in Electron.

IPeeSee is written in Typescript, is fully documented and provides all the necessary types.

Compared to some other modules, IPeeSee preserves the interfaces on both main and renderer process and tries to accomplish one-way / two-way communication in the simplest way possible.

Besides communication, IPeeSee implements custom IPCError and IPCResponse. Those are implemented for the sole sake of seperating errors/responses from other communication protocols.

Install

npm i ipeesee --save

API

.send(channel, data, options)

Sends a message to a channel.

Parameters

  • channel (string) - A channel to send a message to

  • data (any) - Data to send (optional)

  • options (object) - (optional)

    • window(BrowserWindow) - An instance of browserWindow to send a message to. Only required when using with ipcMain

    • reply(boolean) - By default, we always wait for the response. Setting this to false will make the communication one-way only. In simple words, we send a message and don't care about the response

    • timeout(number) - Time (seconds) to wait before we manually resolve the reply

Resolves either an IPCError or IPCResponse with the following statusCodes:

  • 204 - Resolved with no data in the response
  • 200 - Resolved with the data in the response
  • 408 - Resoled by manually timing out. This IPCResponse will also come with a message indicating the timeout and the channel we timed out at

Keep in mind that reply and timeout are mutually exclusive, meaning that setting timeout only makes sense when we are actually waiting for the reply. If we aren't (if reply is set to false or not passed at all), timeout will take no effect.


.reply(channel, callback)

Adds a listener that replies to the provided channel

Parameters

  • channel (string) - A channel to reply to

  • callback(data) (Function) - Receives a message with optional data and responds back to the channel. In order to reply back, it's mandatory to return from this function

Usage

IPeeSee interfaces are unified. This means that regardless if you are working with main or renderer process, methods and arguments are the same.

Constructor

IPeeSee constructor takes the process type (ipcMain, ipcRenderer) and an optional browserWindow that you want to send a message to.

If you don't pass the window (browserWindow) to the constructor, you will have to pass it to .send() each time you want to send a message from main to renderer process.

If your application only uses a single window, it's a good idea in that case to simply pass a window to the constructor and not worry about passing it while using .send().

constIPeeSee=require('ipeesee').default;// orimportIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain,yourWindow);ipc.send('foo',{foo: 'bar'}).then(...).catch(...);

Or if you don't pass the window to the constructor, you will have to specify it in each .send (only when sending messages from main to renderer)

ipc.send('foo',{foo: 'bar'},{window: yourBrowserWindow}).then(...).catch(...);

Send a message that expects no reply

ipc.send('foo',{foo: 'bar'},{reply: false});

Manually timeout the reply after N number of seconds

ipc.send('foo',{foo: 'bar'},{timeout: 30}).then(...).catch(...);

Renderer

import{ipcRenderer}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcRenderer);ipc.send('foo',{foo: 'bar'}).then(response=>{console.log(response);}).catch(error=>console.error(error));// { message: 'Cabooom! }

Main

import{ipcMain}from'electron';importIPeeSeefrom'ipeesee';constipc=newIPeeSee(ipcMain);ipc.reply('foo',data=>{returnnewPromise(resolve=>{console.log(data);// data from senderresolve({response: 'Foo is so Barish!'});// respond back to sender});});

Communicating from main to renderer is done exactly the same way.

Working with errors

IPC .send(channel, response) doesn't provide way to return node-like response e.g. (error, response). For that reason, we have to work with a single object and make the best out of it.

To work around this limitation, IPeeSee will check if your response object has .error property on it and if so, will reject it as IPCError. This means that no matter what, you will always resolve, either an error or a valid response.

Example with returning an IPCError

ipc.send('get-todos',{id: 1}).then(todo=>{console.log(todo);}).catch(error=>{console.log(error);});ipc.reply('get-todos',data=>{returnnewPromise(resolve=>{request(`https://jsonplaceholder.typicode.com/todos/${data.id}`,(error,response,body){if(error){resolve({ error })}else{resolve(response);}});});});

In case of an error, it's imperative that your response object has a property called .error. The error object itself can have any custom properties.

IPCError response object looks like this:

{type: 'IPC_ERROR',error: {}// error you previously resolved}

TODO

  • Add CI server and how to build section
  • Unit tests

About

Electron IPC on steroids. 💪Simplified async communication and proper error and response handling.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages