# Debug

## DebugThread object

### thread.log(options)

```typescript
import { DebugThread } from '@empathize/framework';

function exampleFunction()
{
    const debugThread = new DebugThread('exampleFunction', 'Initialized');
    
    // do some stuff
    
    debugThread.log({
        message: [
            'list',
            'of',
            'lines'
        ]
    });
}
```

## DebugOptions

| Name      | Type                          | Description                                                                                                  |
| --------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------ |
| message   | string \| string\[] \| object | Message to log. If string - single line; list of strings - multiple lines; object - in format `[key]: value` |
| function? | string                        | Name of function log should be written as                                                                    |
| thread?   | number                        | Id of a thread (random number)                                                                               |

## Debug class

### Debug.log(options)

```typescript
import { Debug } from '@empathize/framework';

function exampleFunction(a, b)
{
    Debug.log({
        function: 'exampleFunction',
        message: {
            'a value': a,
            'b value': b
        }
    });
}
```

### Debug.merge(records)

Merges log records with currently stored. Windows in neutralino work as separate processes, so `Debug` class in the main window will be different from `Debug` class in the about window. So, to have a complete log from all the windows, you should send them by, for example, `IPC.write()` method to your main window, and then merge it by this method

![How Debug.merge() should be used](https://4291835564-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fm77hcDeqeOAYWWBuMMpM%2Fuploads%2FeXYnATbJ4Q8krujftzvN%2FScreenshot%20from%202022-01-14%2018-14-49.png?alt=media\&token=7766bbaf-7816-4c66-8601-614897a9191c)

#### About window

```typescript
import { Debug, IPC } from '@empathize/framework';

declare const Neutralino;

// This event will be called before window closing
// Be careful because this event works only when
// exitProcessOnClose = false
Neutralino.events.on('windowClose', async () => {
    // Wait before it will be stored
    await IPC.write({
        type: 'log',
        log: Debug.getRecords()
    });
    
    // And then we need to manually close this process
    Neutralino.app.exit();
});
```

#### Main window

```typescript
import { Debug, IPC } from '@empathize/framework';

IPC.read().then((records) => {
    records.forEach((record) => {
        if (record.data.type === 'log')
        {
            // And don't forget to call .pop() method
            // to remove this record from the IPC.read() pool
            Debug.merge(record.pop().data.log);
        }
    });
});
```

### Debug.getRecords()

System class that used primarily with `Debug.merge()`

### Debug.get()

Returns list of strings

```typescript
import { Debug, fs, path, dir } from '@empathize/framework';

const pathToFile = path.join(dir.app, 'logs', `${Debug.startedAt}.log`);
const debugLog = Debug.get().join('\r\n');

fs.write(pathToFile, debugLog);
```

### Debug.handler(callback)

```typescript
import { Debug } from '@empathize/framework';

Debug.handler((record) => {
    console.log(`Made new log record:\r\n${record.log.join('\r\n')}`);
});
```

### Debug.loggable(func)

This method will return a new function that will log some user-specified strings at the start and at the end of its work

![How Debug.loggable() works](https://4291835564-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fm77hcDeqeOAYWWBuMMpM%2Fuploads%2F1OmsYNwMUy4crLej8kUs%2FScreenshot%20from%202022-01-14%2018-06-32.png?alt=media\&token=ca61c46b-21f0-4371-b8d2-f865294a288e)

#### Sync functions

```typescript
import { Debug } from '@empathize/framework';

// sum(1, 2) -> 3
let sum = (a: number, b: number): number => a + b;

// Replace this sum function with a new one, generated by Debug.loggable(()
// This new function will generate a log at the start and finish of its work
// Also <number> can be replaced with <ReturnType<typeof sum>>
// which is the same, but generates automatically by the TypeScript
sum = Debug.loggable<number>(sum, {
    // Function name to log
    function: 'sum',
    
    // DebugOptions to log at start
    start: (thread, ...args) => `Calculating ${args[0]} + ${args[1]}`,
    
    // DebugOptions to log at finish
    finish: (thread, output) => `Calculated ${output}`
});

console.log(`1 + 2 = ${sum(1, 2)}`);
```

#### Async functions

```typescript
import { Debug } from '@empathize/framework';

// await sum(1, 2) -> 3
let sum = (a: number, b: number): Promise<number> => {
    return new Promise((resolve) => {
        setTimeout(() => resolve(a + b), 3000);
    });
};

// Here I use <ReturnType<typeof sum>>, but it also
// acceptable to use <Promise<number>>
sum = Debug.loggable<ReturnType<typeof sum>>(sum, {
    // Function name to log
    function: 'sum',
    
    // DebugOptions to log at start
    start: (thread, ...args) => `Calculating ${args[0]} + ${args[1]}`,
    
    // DebugOptions to log at finish
    finish: (thread, output) => `Calculated ${output}`
});

sum(1, 2).then((result) => console.log(`1 + 2 = ${result}`));
```

This function is highly useful to generate log generation in your already existing code without modifying it. For example:

```typescript
import { Debug, Configs } from '@empathize/framework';

// We're rewriting Configs.get() function and then
// it will automatically generate log output
Configs.get = Debug.loggable<ReturnType<typeof Configs.get>>(Configs.get, {
    function: 'Configs.get',
    context: Configs,
    start: (thread, ...args) => `Getting ${args[0]} config value`,
    finish: (thread, output) => `Resolved value: ${output}`
});
```

Property context means an object or class at which name this function should be called. Because we're making a copy of the original function - this copy will have no access to `this`, and to manually give this function `this` value - you should specify its _context_ - parent class or object this function belongs to&#x20;
