# Advanced Topics

This document dives into advanced aspects of Vellum, targeting experienced developers who want to push its capabilities further. Topics include dynamic mod loading, strategies for mod unloading, performance optimizations, security considerations, and best practices for building large-scale applications. These concepts build on Vellum’s core features, offering deeper control and flexibility.

For foundational knowledge, see [Understanding Mods](./mods.md), [Toolkit API](./toolkit.md), and [Action System](./actions.md).

---

## Dynamic Mod Loading

Vellum supports adding mods at runtime using a `MutationObserver` to detect new `<vellum-mod>` elements in the DOM. This allows applications to load functionality dynamically without a full page reload.

### How It Works
- **Observation**: Vellum’s `modObserver` watches for DOM changes (`childList` and `subtree`).
- **Processing**: When a new mod element is added, Vellum:
  1. Extracts metadata (`src`, `name`, etc.).
  2. Fetches the mod script.
  3. Sorts it based on dependencies and priority.
  4. Executes its `init` function.
- **Events**: Emits `'vellum:mod-loaded'` or `'vellum:mod-load-failed'` as it processes.

### Example
```javascript
// Add a mod dynamically
const modElement = document.createElement('vellum-mod');
modElement.setAttribute('src', '/new-mod.mjs');
document.querySelector('vellum-app').appendChild(modElement);
```
- **Result**: Vellum detects and initializes the new mod seamlessly.

### Implications
- **Flexibility**: Load features on demand (e.g., based on user actions).
- **Complexity**: Ensure new mods integrate with existing action handlers or layouts.

---

## Mod Unloading (Future Consideration)

Vellum currently lacks built-in mod unloading, but it’s a valuable concept for resource management in dynamic apps. Here’s how it could be implemented:

### Potential Approach
- **Action**: Introduce `'action:unload'` for mods to signal removal.
  ```javascript
  toolkit.dispatchAction({
    type: 'action:unload',
    detail: { modName: 'my-mod' }
  });
  ```
- **Cleanup**: A handling mod could:
  - Unregister action handlers.
  - Remove DOM content tied to the mod.
  - Free memory (e.g., clear event listeners).
- **Vellum Support**: Update `disconnectedCallback` to clean up all mods if the `<vellum-app>` is removed.

### Current Workaround
Manually unregister handlers and update layouts:
```javascript
toolkit.dispatchAction({
  type: 'action:unregister',
  detail: { actionType: 'my:action', modName: 'my-mod' }
});
```

### Why It Matters
Unloading prevents memory leaks and keeps the app lightweight as mods come and go.

---

## Performance Optimizations

For large-scale applications, consider these strategies:

### Mod Loading
- **Batching**: Instead of loading all mods concurrently with `fetchMods`, batch them:
  ```javascript
  async function loadInBatches(modList, batchSize = 5) {
    for (let i = 0; i < modList.length; i += batchSize) {
      await Promise.all(modList.slice(i, i + batchSize).map(loadModule));
    }
  }
  ```
- **Lazy Loading**: Load mods only when needed (e.g., on user interaction).

### Action Handling
- **Debounce Frequent Actions**: For rapid-fire actions (e.g., `'counter:updated'`), debounce handlers to reduce updates:
  ```javascript
  let timeout;
  const debouncedHandler = (detail) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => updateUI(detail), 100);
  };
  ```

### Rendering
- **Efficient Renderers**: Use framework-specific renderers (e.g., Lit’s incremental updates) instead of full DOM wipes.

---

## Security Considerations

Vellum’s dynamic `import()` for mods introduces potential risks if sources aren’t trusted.

### Risks
- **Malicious Code**: Unverified mod scripts could execute harmful code.
- **Uncontrolled Sources**: External URLs might change unexpectedly.

### Mitigation
- **Whitelist**: Implement an optional whitelist in a consumer mod:
  ```javascript
  const allowedSources = ['/mods/', 'https://trusted.com/'];
  function isAllowed(src) {
    return allowedSources.some(base => src.startsWith(base));
  }
  // Filter in a custom loadModule wrapper
  ```
- **CSP**: Use Content Security Policy to restrict script sources.
- **Validation**: Check mod integrity (e.g., hashes) before loading.

### Best Practice
Document security guidelines for mod developers, emphasizing trusted sources.

---

## Best Practices

### Structuring Large Applications
- **Mod Naming**: Use unique `name` attributes to avoid handler conflicts.
- **Action Naming**: Adopt a convention (e.g., `'namespace:action'`) for clarity:
  ```javascript
  toolkit.dispatchAction({ type: 'ui:refresh', detail: {} });
  ```
- **Single Responsibility**: Keep mods focused (e.g., one for layout, one for data).

### Error Handling
- **Robust Handlers**: Wrap action handlers in try-catch:
  ```javascript
  const handler = (detail) => {
    try {
      processDetail(detail);
    } catch (e) {
      toolkit.dispatchAction({ type: 'system:error', detail: { error: e } });
    }
  };
  ```

### Testing
- **Unit Test Mods**: Mock the toolkit to test `init` logic:
  ```javascript
  const toolkit = { dispatchAction: jest.fn() };
  await myMod.init(toolkit);
  expect(toolkit.dispatchAction).toHaveBeenCalledWith(expect.any(Object));
  ```

---

## Next Steps
- **Dynamic Mods**: Experiment with runtime loading in [Examples and Tutorials](./examples/).
- **Actions Deep Dive**: Explore decoupling in [Action System](./actions.md).
- **Core Details**: See [API Reference](./api-reference.md) for technical specifics.