App Development

Build custom apps for the Fiberwise ecosystem using Web Components and the integrated FiberWise SDK.

Quick Start

Fiberwise apps are JavaScript bundles that integrate with the platform via standard initialize() and render() functions. Apps use Web Components for UI and the built-in FIBER SDK for platform APIs.

1. Main App Entry Point

Create your main index.js file with the standard Fiberwise app pattern:

// index.js - Your app's main entry point
import FiberWise from 'fiberwise';

// Create FIBER SDK instance
export const FIBER = new FiberWise();

/**
 * Required: Platform calls this function to initialize your app
 * @param {Object} appBridge - Platform integration bridge
 * @param {Object} manifest - Your app's manifest data
 */
export async function initialize(appBridge, manifest) {
  console.log('[App] Initializing app...');
  FIBER.initialize(appBridge, manifest);
  return true;
}

/**
 * Required: Platform calls this to render your app
 * @param {HTMLElement} mountPoint - Where to mount your app
 */
export function render(mountPoint) {
  console.log('[App] Rendering app...');
  const el = document.createElement('my-app');
  mountPoint.appendChild(el);
}

// Import your components
import './my-app.js';

2. Web Component Implementation

Create Web Components using the Fiberwise pattern with separate HTML, CSS, and JS files:

// my-app.js
import htmlTemplate from './my-app.html?raw';
import cssStyles from './my-app.css?inline';
import { FIBER } from './index.js';

export class MyApp extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  async connectedCallback() {
    // Render component with template and styles
    this.shadowRoot.innerHTML = `
      
      ${htmlTemplate}
    `;

    // Use FIBER SDK for platform operations
    try {
      const chats = await FIBER.data.listItems('chats');
      this.render(chats);
    } catch (error) {
      console.error('Failed to load app data:', error);
    }
  }

  render(data) {
    this.innerHTML = `
      

My FiberwiseApp

Found ${data.agents.length} agents

`; } renderError(error) { this.innerHTML = `
Error: ${error.message}
`; } } customElements.define('my-app', MyApp);

How It Works

  1. Router launches app: When a route is accessed, the router dynamically imports your app module
  2. AppBridge injection: The router passes an AppBridge instance to your app's initialize() function
  3. SDK access: Your app gets the FiberwiseSDK via appBridge.getFiberWise()
  4. Clean isolation: Each app receives its own SDK instance without global pollution

Real-World Example: Function Tester App

Learn from a complete working example that demonstrates key app development patterns and integrations.

App Overview

The Function Tester app showcases:

  • Function Integration: Creating and executing functions via the Fiberwise SDK
  • Dynamic UI: Form generation based on function schemas
  • Real-time Updates: Live execution results and history tracking
  • AppBridge Pattern: Proper dependency injection and isolation

Key Implementation Patterns

1. App Manifest with Functions

# app_manifest.yaml
app:
  name: Function Tester
  app_slug: function-tester
  version: 0.0.35
  description: Test function execution with results tracking
  entryPoint: index.js
  category: development

routes:
- path: /functions-tester
  component: function-test-app
  title: Function Tester

functions:
- name: helloWorldFunction
  description: Multi-language greeting function
  implementation_path: functions/hello_world.py
  input_schema:
    type: object
    properties:
      name: { type: string, description: "Name to greet" }
      language: 
        type: string
        enum: [English, Spanish, French]
    required: [name]
  output_schema:
    type: object
    properties:
      message: { type: string }
      timestamp: { type: string }
      language: { type: string }

2. Function Implementation

# functions/hello_world.py
import datetime

def run(input_data):
    """Entry point for all Fiberwise functions"""
    name = input_data.get("name", "World")
    language = input_data.get("language", "English")
    
    # Multi-language support
    greetings = {
        "Spanish": f"Β‘Hola, {name}!",
        "French": f"Bonjour, {name}!",
        "English": f"Hello, {name}!"
    }
    
    return {
        "message": greetings.get(language, greetings["English"]),
        "timestamp": datetime.datetime.now().isoformat(),
        "language": language
    }

3. SDK Integration with Function Execution

// Component that executes functions
class FunctionTestApp extends HTMLElement {
  async executeFunction(functionId, params) {
    try {
      this.isLoading = true;
      this.render();
      
      // Execute function via SDK
      const result = await FIBER.func.activate(functionId, params);
      
      // Show success result
      this.executionResult = result;
      this.showNotification('Function executed successfully!', 'success');
      
      // Refresh execution history
      await this.loadFunctionHistory();
      
    } catch (error) {
      console.error('Function execution failed:', error);
      this.showNotification(`Error: ${error.message}`, 'error');
    } finally {
      this.isLoading = false;
      this.render();
    }
  }

  async loadFunctionHistory() {
    // Get execution history via SDK
    const response = await FIBER.func.list();
    
    // Process and display results
    this.functionHistory = response.items.map(item => ({
      ...item,
      inputData: this.parseJSON(item.input_data),
      outputData: this.parseJSON(item.output_data),
      executionTime: this.calculateExecutionTime(item)
    }));
    
    this.render();
  }
}

4. Dynamic Form Generation

renderInputField(param) {
  switch (param.type) {
    case 'enum':
      return `
        `;
        
    case 'number':
      return ``;
                     
    default: // string and other types
      return ``;
  }
}

Development Benefits Demonstrated

πŸ”— Schema-Driven UI

Forms automatically generated from function input schemas

πŸ“Š Real-time Feedback

Live execution status, results, and error handling

πŸ”„ History Tracking

Complete execution history with performance metrics

⚑ SDK Integration

Clean API access through AppBridge dependency injection

AppBridge API Reference

The AppBridge provides a standardized interface for apps to access platform services without global dependencies.

Core Methods

getFiberWise()

Returns: Object - The FiberwiseSDK instance

Gets the main platform SDK instance for making API calls, managing data, and accessing platform services.

export async function initialize(appBridge, context) {
  const sdk = appBridge.getFiberWise();

  // Use SDK for platform operations
  const agents = await sdk.agents.list();
  const data = await sdk.storage.get('key');

  return true;
}

createFiberWiseInstance(config)

Parameters: config (Object) - Configuration options

Returns: Object - A new SDK instance with custom configuration

Creates a customized SDK instance with specific settings like base URL, timeout, or custom headers.

export async function initialize(appBridge, context) {
  // Create custom SDK instance for external API
  const customSDK = appBridge.createFiberWiseInstance({
    baseUrl: 'https://api.external-service.com/v1',
    timeout: 10000,
    headers: {
      'Custom-Header': 'value'
    }
  });

  return true;
}

App Lifecycle

Understanding the app initialization and rendering lifecycle:

1

Route Matched

User navigates to app route, router detects match

2

Dynamic Import

Router dynamically imports app module from bundle

3

AppBridge Injection

Router calls initialize(appBridge, context)

4

SDK Setup

App gets SDK via appBridge.getFiberWise()

5

Component Rendering

App creates and mounts UI components

Build and Deploy

Fiberwiseuses an automated build and deployment process with the fiber CLI:

Development Workflow

1. Build Your App

# Build with Vite or your preferred bundler
npm run build

This creates optimized files in your dist/ directory.

2. Install with Auto-Build

# Install with automatic build (recommended)
fiber install app . --verbose

# Or skip build if already built
fiber install app . --no-build --verbose

The --verbose flag shows detailed progress and helps with debugging.

What happens during installation:

  1. Auto-build: Runs npm install and npm run build (unless --no-build)
  2. Bundle creation: Creates zip archive from dist/ directory
  3. Manifest processing: Validates and installs app manifest
  4. Bundle upload: Uploads built files to platform
  5. Route registration: Registers app routes with router
  6. Cleanup: Removes temporary files

Bundle Structure

Your built app bundle should contain:

dist/
β”œβ”€β”€ index.js              # Main entry point with AppBridge pattern
β”œβ”€β”€ index.js.map          # Source map for debugging
└── assets/
    β”œβ”€β”€ app.css           # Bundled stylesheets
    └── *.js              # Additional JavaScript chunks

⚠️ Common Issues

  • Old bundles: Delete *.zip files before reinstalling
  • Build failures: Ensure npm is in PATH and package.json exists
  • Import errors: Use AppBridge pattern, not global imports

Migration from Old Pattern

❌ Old Pattern (Deprecated)

import fiber from 'fiberwise';  // ❌ Fails - no global module
const FIBER = fiber.createInstance();

βœ… New Pattern (Current)

export let FIBER = null;

export async function initialize(appBridge, context) {
  FIBER = appBridge.getFiberWise();  // βœ… Clean dependency injection
  return true;
}

Troubleshooting

Common issues and solutions when developing Fiberwiseapps:

🚫 App fails to load with module script errors

Failed to load module script: Expected a JavaScript module but got text/html

Cause: Using old import syntax or incorrect file serving

Solution: Ensure you're using the AppBridge pattern instead of global imports:

// ❌ Wrong - causes module errors
import fiber from 'fiberwise';

// βœ… Correct - AppBridge pattern
export let FIBER = null;
export async function initialize(appBridge, context) {
  FIBER = appBridge.getFiberWise();
}

πŸ” FIBER is null in components

TypeError: Cannot read property 'getData' of null

Cause: Component trying to use FIBER before app initialization

Solution: Ensure initialize() function properly sets FIBER:

export async function initialize(appBridge, context) {
  console.log('AppBridge received:', !!appBridge);

  FIBER = appBridge.getFiberWise();

  if (!FIBER) {
    console.error('Failed to get FiberwiseSDK from AppBridge');
    return false;
  }

  return true;
}

πŸ“¦ Old bundle being uploaded

App installs but still has old import statements

Cause: Install process using cached bundle instead of fresh build

Solution: Clean old bundles and rebuild:

# Remove old bundle files
rm *.zip

# Build fresh bundle
npm run build

# Install with verbose output
fiber install app . --verbose

πŸ”§ Build step not running

⚠️ npm not found, skipping build step

Cause: npm not available in PATH or missing package.json

Solution: Ensure npm is installed and package.json exists, or use --no-build flag:

# Manual build then install
npm run build
fiber install app . --no-build --verbose

# Or ensure npm is in PATH
where npm  # Should show npm location

Benefits

πŸ—οΈ Clean Architecture

No global variable pollution

πŸ§ͺ Better Testing

Easy to mock AppBridge in tests

πŸ”’ Isolation

Apps don't interfere with each other

πŸš€ Future-Proof

Easy to extend with new platform services

Next Steps