# Extending

{% hint style="info" %}
**For more information on the available hooks see:** \
[Actinium Hooks](https://atomic-reactor.github.io/Actinium/#api-Hooks)
{% endhint %}

### Actinium SDK&#x20;

Suppose you're creating a plugin and you want to share the functionality with other plugins. You can opt to extend the Actinium SDK by creating a namespace on the Actinium global.&#x20;

{% tabs %}
{% tab title="Plugin" %}
{% code title="/src/app/MyPlugin/plugin.js" %}

```javascript


// Extend Actinium SDK 
Actinium.MyPlugin = require('./sdk');
```

{% endcode %}
{% endtab %}

{% tab title="MyPlugin SDK" %}
{% code title="/src/app/MyPlugin/sdk.js" %}

```javascript
const COLLECTION = 'SomeCollection';

const MyPluginSDK = {}; 

MyPluginSDK.create = async (req, options) => {
    
    // Get params from request object 
    let { params } = req; 
    
    // Run a hook so other plugins can do some thangs to the params
    await Actinium.Hook.run('some-collection-before-create', params, req, options);
    
    // Create the new object
    const obj = new Actinium.Object(COLLECTION);
    
    // Save the object
    let savedObj = await obj.save(params, options);
    
    if (!savedObj) { 
        return new Error('Unable to save SomeCollection object'); 
    }
    
    // Convert the Actinium.Object into a JavaScript Object. 
    savedObj = saveObj.toJSON(); 
    
    // Run a hook so other plugins can do some thangs 
    await Actinium.Hook.run('some-collection-created', savedObj, req, options);
    
    return savedObj;
};

module.exports = MyPluginSDK;
```

{% endcode %}
{% endtab %}
{% endtabs %}

In the above example your Actinium extension will be available regardless of your plugin's active status. If you want your extension to only be available if your plugin is active you'll want to register a **plugin-load** hook and define it after validating that your plugin is active using [**Actinium.Plugin.isActive**](https://atomic-reactor.github.io/Actinium/#api-Actinium-Plugin_isActive)**.**

{% code title="/src/app/MyPlugin/plugin.js" %}

```javascript
const SDK = require('./sdk'); 

const PLUGIN = {
    ID: 'MyPlugin',
    name: 'My Awesome Plugin',
    description: 'The name says it all bro',
    version: {
        actinium: '>=3.0.5',
        plugin: '0.0.1',
    },
};

Actinium.Plugin.register(PLUGIN);

Actinium.Hook.register('plugin-load', async ({ ID }) => {
    if (ID !== PLUGIN.ID) return;
    if (!Actinium.Plugin.isActive(ID)) return;
    
    Actinium.MyPlugin = SDK;
});
```

{% endcode %}

{% hint style="warning" %}
**Note:** In the above example your extension will not be available in the file scope.
{% endhint %}

### Cloud Functions

Cloud functions are another way to extend Actinium functionality. Cloud functions are accessible to other plugins and the Actinium client SDK via **Actinium.Cloud.run**. You can define a cloud function in a **plugin.js** file. A typical cloud function may look like:

{% code title="/src/app/MyPlugin/plugin.js" %}

```javascript
const SDK = require('./sdk'); 
const { CloudRunOptions } = require(`${ACTINIUM_DIR}/lib/utils`);

const PLUGIN = {
    ID: 'MyPlugin',
    name: 'My Awesome Plugin',
    description: 'The name says it all bro',
    version: {
        actinium: '>=3.0.5',
        plugin: '0.0.1',
    },
};

Actinium.Plugin.register(PLUGIN);

Actinium.Cloud.define('my-plugin-create', req => {
    const options = CloudRunOptions(req); 
    return SDK.create(req, options); 
});
```

{% endcode %}

{% hint style="info" %}
If your cloud function requires capabilities or roles be sure to create the **options** object via the **CloudRunOptions** helper.&#x20;
{% endhint %}

{% tabs %}
{% tab title="Client Side Usage" %}
{% code title="Usage: Reactium \~ services.js" %}

```javascript
import Actinium from 'appdir/api'; 

const create = params => Actinium.Cloud.run('my-plugin-create', params);

export default {
    create,
};
```

{% endcode %}
{% endtab %}

{% tab title="Other Plugin Usage" %}
{% code title="Usage: Actinium \~ plugin.js" %}

```javascript
const { CloudRunOptions } = require(`${ACTINIUM_DIR}/lib/utils`);

Actinium.Cloud.define('some-other-plugin', async req => {
    const options = CloudRunOptions(req);
    const params = { someparam: 'somevalue' };
    const newObj = await Actinium.Cloud.run('my-plugin-create', params, options); 
    
    // do something else like transform the newObj with a hook 
    await Actinium.Hook.run('some-other-plugin-hook', newObj, req, options); 
    
    return newObj;  
};
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Express Middleware

You can extend the underlying Express app by registering middleware that will be loaded on start-up. Register middleware using the **Actinium.Middleware.register** function.

```javascript
const express = require('express');
const { myPluginMiddleware } = require('./sdk'); 

Actinium.Middleware.register('my-plugin-mw', app => {
    // custom middleware 
    app.use(myPluginMiddleware()); 
    
    // custom route handler
    const router = express.Router();
    
    router.use('/some/route/*', (req, res, next) => {
        console.log('Log something'); 
        res.send('Send something to browser'); 
    });
    
    // mount the router on app
    app.use(router);
});
```

{% hint style="info" %}
**For more information on middleware see:** \
[Express Middleware](https://expressjs.com/en/guide/using-middleware.html)
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.reactium.io/actinium/actinium-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
