# Develop your modules

### How it Works?

**Parallelix uses a modular system in order to provide a single API for different platforms. In essence, each module is a wrapper over the official API or SDK.**

1. The Parallelix client connects modules specified in the configuration by loading additional JS scripts;
2. After initializing the libraries, it sorts them by priority and calls the IsCurrentPlatform()[^1] module on each one
3. After the required platform is found - its initialization method is called and the client becomes ready to work, providing the required methods with a unified interface

{% hint style="warning" %}
**If no platform has been connected**, or the application was launched on an **unknown platform**, the default **web** module will be connected. Therefore, it is important that it is located in the folder with your modules and is available for connection.
{% endhint %}

Now let's take a look at the structure of the module.

***

### Module Structure

All modules are stored in the directory of your site, which is specified in the Parallelix configuration. From there they will be connected by name.

**It is important to respect the naming of your module:**

```
parallelix.YOUR_MODULE_NAME.js

for example:
parallelix.vk.js
```

All modules are inherited from the base virtual class **ParallelixWrapper**. Thus, the methods supported by a module can be described, while the rest will cause an exception.

**Let's understand the class structure of your new module:**

```javascript
// Your Parallelix module extends basic virtual ParallelixWrapper
class ParallelixMyModule extends ParallelixWrapper {
    // This constructor used at module initialization from Parallelix main class
    // instance = Parallelix main class instance
    // options  = Platform-specific options object from Parallelix config
    constructor(instance, options = {}) {
        const defaultOptions = {
            // Your Default Options
        };
        
        // Extend Default options by constructor options
        let extendedOptions = {...defaultOptions, ...options};
        super(instance, extendedOptions);
        this.options = extendedOptions;
        
        // Add Platform Instance (Required!)
        this.platform = instance;
        
        // Initialization Flag
        this.isInitialized = false;
        
        // API or SDK Client Instance (for Example vkBridge object)
        this.invoker = null;
        
        // Add Event Handlers
        this.OnError = (options?.OnError && typeof options?.OnError === "function") ? options.OnError : (error) => {
            console.error(`Parallelix Web Wrapper Error: ${error.message}`);
        };
        this.OnInitialized = (options?.OnInitialized && typeof options?.OnInitialized === "function") ? options.OnInitialized : (data) => {
            console.log(`Parallelix Web Wrapper Initialized`);
        };
    }
    
    /**
     * Get Module Priority for Platform Detection
     * @returns {number} from 0 to 999
     */
    get Priority(){
        return 1;
    }
    
    /**
     * Check if this module is for current platform
     * @returns {boolean}
     */
    IsCurrentPlatform(){
        // Here you can determine platform
        return true;
    }
    
    /**
     * Initialize Your Platform SDK
     */
    Initialize(){
        self.invoker = self;            // Put here Your Platform-specific SDK
        self.isInitialized = true;      // Initialization Flag
        self.OnInitialized({});         // Call Initialization Ends Handler
        self.HandleEvents();            // Handle All events from platform-specific SDK
    }
    
    /**
     * Handle All Web Events
     */
    HandleEvents(){
        let self = this;

        // Check if your module is initialized
        if(!self.isInitialized) {
            onError(new Error("My Module is not initialized"));
            return;
        }   

        // Subscribe to Web App Events
        window.addEventListener("message", (event) => {
            if(!event.data) return;

            const { type, data } = event.data;
            self.GetEventListener(type)?.(data);
        });
    }
    
    // *****
    // Other Methods Implementation
    // *****
}

// It is important to use the same identifier for the object as in the module file name.
Parallelix._platformClasses["YOUR_MODULE_NAME"] = ParallelixMyModule;
```

Next, you can create method implementations that will be used for your module on your platform. [**For this you can refer to the documentation of common classes**](https://neurosell.gitbook.io/parallelix/api-reference/general-client).

***

### Platform Detection

When discovering a platform, your module must check for certain attributes that a Web application can use to realize that it should currently be using your module.

Also, don't forget to prioritize your module check via the **Priority()** field. The **minimum priority is 0**, the **maximum is 999.**

***

### Publish your Modules

Your help is always welcome. [Submit your new modules directly to us on GitHub](https://github.com/Neurosell/parallelix). We will be sure to add it to new releases.

[^1]: This method checks some attributes by which the platform is defined and returns their presence
