Skip to content

Commit

Permalink
refactor(main): Separate electron API Node.js api (#392)
Browse files Browse the repository at this point in the history
* chore(main): Remove electronApi loader workaround

* refactoring(main): Rename getName and getVersion to getAppName and getAppVersion

* refactor(main): Separate electron and node.js api

* fix(main): bind initialize method
  • Loading branch information
megahertz committed Jan 5, 2024
1 parent f1844e0 commit 0f9d340
Show file tree
Hide file tree
Showing 47 changed files with 721 additions and 625 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 5.1.0

- New entry point for NW.js / Node.js apps: `'electron-log/node'`

## 5.0.0

### Core
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ only log functions like `info`, `warn` and so on.
There are a few other ways how a logger can be initialized for a renderer
process. [Read more](docs/initialize.md).

### Node.js and NW.js

```typescript
import log from 'electron-log/node';
log.info('Log from the nw.js or node.js');
```

### electron-log v2.x, v3.x, v4.x

If you would like to upgrade to the latest version, read
Expand Down
6 changes: 6 additions & 0 deletions node.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { NodeLogger } from './src';

declare const Logger: NodeLogger & {
default: NodeLogger;
};
export = Logger;
5 changes: 5 additions & 0 deletions node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

const node = require('./src/node');

module.exports = node;
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "electron-log",
"version": "5.0.5-beta.2",
"version": "5.1.0-beta.1",
"description": "Just a simple logging module for your Electron application",
"main": "src/index.js",
"browser": "src/renderer/index.js",
Expand All @@ -24,6 +24,8 @@
"src/*",
"main.js",
"main.d.ts",
"node.js",
"node.d.ts",
"preload.js",
"renderer.js",
"renderer.d.ts"
Expand Down
15 changes: 10 additions & 5 deletions src/core/Logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const scopeFactory = require('./scope');
class Logger {
static instances = {};

dependencies = {};
errorHandler = null;
eventLogger = null;
functions = {};
Expand All @@ -26,6 +27,7 @@ class Logger {

constructor({
allowUnknownLevel = false,
dependencies = {},
errorHandler,
eventLogger,
initializeFn,
Expand All @@ -37,10 +39,12 @@ class Logger {
} = {}) {
this.addLevel = this.addLevel.bind(this);
this.create = this.create.bind(this);
this.initialize = this.initialize.bind(this);
this.logData = this.logData.bind(this);
this.processMessage = this.processMessage.bind(this);

this.allowUnknownLevel = allowUnknownLevel;
this.dependencies = dependencies;
this.initializeFn = initializeFn;
this.isDev = isDev;
this.levels = levels;
Expand All @@ -55,13 +59,13 @@ class Logger {
}

this.errorHandler = errorHandler;
errorHandler?.setOptions({ logFn: this.error });
errorHandler?.setOptions({ ...dependencies, logFn: this.error });

this.eventLogger = eventLogger;
eventLogger?.setOptions({ logger: this });
eventLogger?.setOptions({ ...dependencies, logger: this });

for (const [name, factory] of Object.entries(transportFactories)) {
this.transports[name] = factory(this);
this.transports[name] = factory(this, dependencies);
}

Logger.instances[logId] = this;
Expand Down Expand Up @@ -97,12 +101,13 @@ class Logger {
}

return new Logger({
...options,
dependencies: this.dependencies,
errorHandler: this.errorHandler,
initializeFn: this.initializeFn,
isDev: this.isDev,
transportFactories: this.transportFactories,
variables: { ...this.variables },
...options,
});
}

Expand All @@ -117,7 +122,7 @@ class Logger {
}

initialize(options = {}) {
this.initializeFn({ logger: this, ...options });
this.initializeFn({ logger: this, ...this.dependencies, ...options });
}

logData(data, options = {}) {
Expand Down
12 changes: 7 additions & 5 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,13 @@ declare namespace Logger {
): void;
}

interface MainLogger extends Logger {
interface NodeLogger extends Logger {
errorHandler: ErrorHandler<MainErrorHandlerOptions>;
eventLogger: EventLogger;
transports: MainTransports;
}

interface MainLogger extends NodeLogger {
initialize(
options?: {
getSessions?: () => object[];
Expand All @@ -624,10 +630,6 @@ declare namespace Logger {
spyRendererConsole?: boolean;
},
): void;

errorHandler: ErrorHandler<MainErrorHandlerOptions>;
eventLogger: EventLogger;
transports: MainTransports;
}

interface RendererLogger extends Logger {
Expand Down
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
const isRenderer = typeof process === 'undefined'
|| (process.type === 'renderer' || process.type === 'worker');

const isMain = typeof process === 'object' && process.type === 'browser';

if (isRenderer) {
// Makes sense when contextIsolation/sandbox disabled
require('./renderer/electron-log-preload');
module.exports = require('./renderer');
} else {
} else if (isMain) {
module.exports = require('./main');
} else {
module.exports = require('./node');
}
170 changes: 170 additions & 0 deletions src/main/ElectronExternalApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
'use strict';

const electron = require('electron');
const path = require('path');
const NodeExternalApi = require('../node/NodeExternalApi');

class ElectronExternalApi extends NodeExternalApi {
getAppName() {
try {
return electron.app?.name || electron.app?.getName();
} catch {
return super.getAppName();
}
}

getAppUserDataPath(appName) {
return this.getPath('userData') || super.getAppUserDataPath(appName);
}

getAppVersion() {
try {
return electron.app?.getVersion();
} catch {
return super.getAppVersion();
}
}

getElectronLogPath() {
return this.getPath('logs') || super.getElectronLogPath();
}

/**
* @private
* @param {any} name
* @returns {string|undefined}
*/
getPath(name) {
try {
return electron.app?.getPath(name);
} catch {
return undefined;
}
}

getVersions() {
return {
app: `${this.getAppName()} ${this.getAppVersion()}`,
electron: `Electron ${process.versions.electron}`,
os: this.getOsVersion(),
};
}

getSystemPathAppData() {
return this.getPath('appData') || super.getSystemPathAppData();
}

isDev() {
if (electron.app?.isPackaged !== undefined) {
return !electron.app.isPackaged;
}

if (typeof process.execPath === 'string') {
const execFileName = path.basename(process.execPath).toLowerCase();
return execFileName.startsWith('electron');
}

return super.isDev();
}

onAppEvent(eventName, handler) {
electron.app?.on(eventName, handler);

return () => {
electron.app?.off(eventName, handler);
};
}

onAppReady(handler) {
if (electron.app?.isReady()) {
handler();
} else if (electron.app?.once) {
electron.app?.once('ready', handler);
} else {
handler();
}
}

onEveryWebContentsEvent(eventName, handler) {
electron.webContents?.getAllWebContents().forEach((webContents) => {
webContents.on(eventName, handler);
});

electron.app?.on('web-contents-created', onWebContentsCreated);

return () => {
electron.webContents?.getAllWebContents().forEach((webContents) => {
webContents.off(eventName, handler);
});

electron.app?.off('web-contents-created', onWebContentsCreated);
};

function onWebContentsCreated(_, webContents) {
webContents.on(eventName, handler);
}
}

/**
* Listen to async messages sent from opposite process
* @param {string} channel
* @param {function} listener
*/
onIpc(channel, listener) {
electron.ipcMain?.on(channel, listener);
}

onIpcInvoke(channel, listener) {
electron.ipcMain?.handle?.(channel, listener);
}

/**
* @param {string} url
* @param {Function} [logFunction]
*/
openUrl(url, logFunction = console.error) { // eslint-disable-line no-console
electron.shell?.openExternal(url).catch(logFunction);
}

setPreloadFileForSessions({
filePath,
includeFutureSession = true,
getSessions = () => [electron.session?.defaultSession],
}) {
for (const session of getSessions().filter(Boolean)) {
setPreload(session);
}

if (includeFutureSession) {
this.onAppEvent('session-created', (session) => {
setPreload(session);
});
}

/**
* @param {Session} session
*/
function setPreload(session) {
session.setPreloads([...session.getPreloads(), filePath]);
}
}

/**
* Sent a message to opposite process
* @param {string} channel
* @param {any} message
*/
sendIpc(channel, message) {
electron.BrowserWindow?.getAllWindows().forEach((wnd) => {
if (wnd.webContents?.isDestroyed() === false) {
wnd.webContents.send(channel, message);
}
});
}

showErrorBox(title, message) {
electron.dialog?.showErrorBox(title, message);
}
}

module.exports = ElectronExternalApi;
2 changes: 1 addition & 1 deletion src/main/__specs__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const log = require('../index');

describe('index', () => {
describe('main/index', () => {
it('should contain all methods of Console API', () => {
const levels = [
'error',
Expand Down

0 comments on commit 0f9d340

Please sign in to comment.