Quick Reference
Framework Methods
- XTool.init()- Initialize framework
- XTool.directive()- Register directive
- XTool.registerComponent()- Register component
- XTool.loadComponents()- Load external components
Component Context
- this.$el- Root element
- this.$destroy()- Destroy component
- this.$nextTick()- Next DOM update
- this.$mutate()- Mutate reactive data
Type Generics
- <TData>- Component data type
- <TMethods>- Methods type
- <TComputed>- Computed type
- <T>- Directive value type
              import { XTool } from 'fynejs'; XTool.init({ debug: true });
            
          Framework Interface
Core framework methods and configuration options for initializing and customizing FyneJS.
XToolFramework
Main framework interface providing initialization, directive registration, and component management.
init
                    Syntax
init(config?: XToolConfig): XToolFramework
                    Description
Initialize the framework with optional configuration settings.
Parameters
| Parameter | Type | Required | Description | 
|---|---|---|---|
| config | XToolConfig | Optional | Configuration options for the framework | 
Example
// Initialize with default settings
XTool.init();
// Initialize with custom configuration
XTool.init({
  container: '.app',
  debug: true,
  staticDirectives: true,
  prefix: 'x',
  delegate: false,
  sandboxExpressions: false,
  allowGlobals: ['Math', 'Date']
});directive<T>
                    Syntax
directive<T>(name: string, directive: CustomDirective<T>): XToolFramework
                    Description
Register a custom directive with bind, update, and unbind lifecycle hooks.
Parameters
| Parameter | Type | Required | Description | 
|---|---|---|---|
| name | string | Required | Directive name (without prefix) | 
| directive | CustomDirective<T> | Required | Directive definition with lifecycle hooks | 
Example
XTool.directive('tooltip', {
  bind(element, value, expression, component) {
    element.setAttribute('title', value);
  },
  update(element, value) {
    element.setAttribute('title', value);
  },
  unbind(element) {
    element.removeAttribute('title');
  }
});METHOD registerComponent(definition): XToolFramework
Register a reusable component with name, template, and lifecycle hooks. Returns the framework instance for chaining.
Syntax
registerComponent(definition: RegisteredComponentDefinition): XToolFramework
                  Parameters
| Parameter | Type | Required | Description | 
|---|---|---|---|
| definition | RegisteredComponentDefinition | Required | Component definition with required name and optional template | 
Example
XTool.registerComponent({
  name: 'counter',
  template: `<div>
    <span x-text="count"></span>
    <button x-on:click="increment">+</button>
  </div>`,
  data: { count: 0 },
  methods: {
    increment() { this.count++; }
  }
});METHOD loadComponents(sources): Promise<ComponentLoaderResult>
Load external component definitions with different loading strategies. Returns a promise with load results.
Syntax
loadComponents(sources: Array<string | ComponentSource>): Promise<ComponentLoaderResult>
                  Parameters
| Parameter | Type | Required | Description | 
|---|---|---|---|
| sources | Array<string | ComponentSource> | Required | Array of component paths or source objects with loading options | 
Example
// Load components with different modes
await XTool.loadComponents([
  'components/button.js',  // preload (default)
  { path: 'components/modal.js', mode: 'defer' },
  { path: 'components/chart.js', mode: 'lazy', name: 'data-chart' }
]);
// Returns: { settled: 2, failed: 0 }Configuration
Framework configuration options for customizing behavior, performance, and security.
XToolConfig
Configuration interface for framework initialization with type-safe options.
Configuration Properties
| Property | Type | Default | Description | 
|---|---|---|---|
| containerOptional | string | 'body' | Container selector for auto-discovery of components | 
| debugOptional | boolean | false | Enable debug logging for development | 
| staticDirectivesOptional | boolean | true | Enable static directive optimization for performance | 
| prefixOptional | string | 'x' | Directive prefix for custom attribute names | 
| delegateOptional | boolean | false | Enable event delegation for better performance | 
| sandboxExpressionsOptional | boolean | false | Restrict globals in expressions for security | 
| allowGlobalsOptional | string[] | undefined | Whitelist of globals when sandboxExpressions is enabled | 
Configuration Example
// Complete configuration example
XTool.init({
  container: '.app-container',    // Custom container
  debug: true,                  // Enable debugging
  staticDirectives: true,      // Optimize static directives
  prefix: 'data',               // Use 'data-' prefix
  delegate: true,              // Enable event delegation
  sandboxExpressions: true,    // Secure expressions
  allowGlobals: [               // Allowed global objects
    'Math', 'Date', 'JSON', 'console'
  ]
});Component Interfaces
TypeScript interfaces for defining components with proper type safety and IntelliSense support.
ComponentDefinition<TData, TMethods, TComputed>
Base interface for defining reactive components with typed data, methods, and computed properties.
PROPERTY data?: TData
Reactive data object with typed properties that trigger UI updates when changed.
// Define typed data interface
interface UserData {
  name: string;
  email: string;
  isActive: boolean;
}
// Use in component
const component = {
  data: {
    name: 'John Doe',
    email: 'john@example.com',
    isActive: true
  } as UserData
};PROPERTY methods?: WithThisForMethods<ComponentContext>
Component methods with proper context binding and type safety. Methods have access to component data and the full ComponentContext.
const component = {
  data: { count: 0 },
  methods: {
    increment() {
      this.count++; // 'this' is properly typed
    },
    setCount(value: number) {
      this.count = value;
    }
  }
};PROPERTY computed?: BindComputed<ComponentContext>
Computed properties with automatic caching and dependency tracking. Values are recalculated only when dependencies change. Computed functions have access to the ComponentContext.
const component = {
  data: { 
    firstName: 'John', 
    lastName: 'Doe' 
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    },
    initials() {
      return `${this.firstName[0]}${this.lastName[0]}`;
    }
  }
};PROPERTY propEffects?: PropEffectsMap<ComponentContext>
Reactive handlers for component prop changes with old/new value tracking. Handlers receive the new and old values and have access to the ComponentContext.
const component = {
  data: { message: 'Hello' },
  propEffects: {
    userId(newValue, oldValue) {
      console.log(`User changed: ${oldValue} → ${newValue}`);
      this.loadUserData(newValue);
    },
    theme(newTheme) {
      this.updateStyles(newTheme);
    }
  }
};PROPERTY template?: string | Promise<string> | (() => string | Promise<string>)
Component template for rendering. Supports static strings, promises, or factory functions.
// Static template
const component1 = {
  template: `<div>
    <h1 x-text="title"></h1>
    <p x-text="description"></p>
  </div>`
};
// Async template
const component2 = {
  template: async () => {
    const response = await fetch('/templates/card.html');
    return await response.text();
  }
};PROPERTY name?: string
Optional component name for registration and debugging. Required for registered components.
const component = {
  name: 'user-card',
  data: { user: null },
  template: `<div class="card">
    <h3 x-text="user?.name"></h3>
  </div>`
};LIFECYCLE Lifecycle Hooks
Component lifecycle methods with proper context typing and execution order. All lifecycle hooks have access to the full ComponentContext.
Mount Lifecycle
- beforeMount?(this: ComponentContext)- Before element is attached
- mounted?(this: ComponentContext)- After element is attached and reactive
Update Lifecycle
- updated?(this: ComponentContext)- After reactive data changes
Unmount Lifecycle
- beforeUnmount?(this: ComponentContext)- Before component cleanup
- unmounted?(this: ComponentContext)- After component cleanup
Destroy Lifecycle
- beforeDestroy?(this: ComponentContext)- Before permanent destruction
- destroyed?(this: ComponentContext)- After permanent destruction
const component = {
  data: { isReady: false },
  
  // Mount lifecycle
  beforeMount() {
    console.log('About to mount', this.$el);
  },
  mounted() {
    this.isReady = true;
    console.log('Component mounted', this.$el);
  },
  
  // Update lifecycle
  updated() {
    console.log('Component updated');
  },
  
  // Unmount lifecycle
  beforeUnmount() {
    this.cleanup();
  },
  unmounted() {
    console.log('Component unmounted');
  }
};RegisteredComponentDefinition<TData, TMethods, TComputed>
Extended component definition for reusable components with required name and additional configuration options.
EXTENDS ComponentDefinition<TData, TMethods, TComputed>
Inherits all properties from ComponentDefinition plus additional required fields.
name: string Required
Unique component name used for registration and template references.
makeData?: (props: Record<string, string>) => Record<string, unknown>
Factory function to generate base data from component props/attributes.
init?: (props: Record<string, any>) => ComponentDefinition | void
Instance augmentation function to customize component per usage.
Registered Component Example
const counterComponent: RegisteredComponentDefinition = {
  name: 'counter',
  template: `<div>
    <span x-text="count"></span>
    <button x-on:click="increment">+</button>
  </div>`,
  data: { count: 0 },
  methods: {
    increment() {
      this.count++;
    }
  },
  makeData(props) {
    return { count: parseInt(props.start) || 0 };
  }
};ComponentContext<TData, TMethods, TComputedVals>
Component context available in methods, computed properties, and expressions with proper type safety.
PROPERTIES Special Properties
- $el- Component's root element
- $id- Component's unique ID
- $isMounted- Mount status
- $isDestroyed- Destruction status
- $isSealed- Sealed mode status
- $isFrozen- Frozen status
- $parent- Parent component
- $children- Child components
METHODS Utility Methods
- $destroy()- Destroy component
- $forceUpdate()- Force re-render
- $addCleanupFunction()- Add cleanup
- $nextTick()- Next DOM update
- $mutate()- Mutate reactive data
- $seal()- Toggle sealed mode
- $log()- Debug logging
Component Context Usage
const component = {
  data: { message: 'Hello' },
  methods: {
    logInfo() {
      this.$log('Component ID:', this.$id);
      this.$log('Element:', this.$el);
      this.$log('Is mounted:', this.$isMounted);
    },
    scheduleUpdate() {
      this.$nextTick(() => {
        console.log('DOM updated');
      });
    },
    forceChange() {
      this.$mutate(() => {
        this.message = 'Changed!';
      });
    }
  }
};Directive Interfaces
Interfaces for creating custom directives with proper lifecycle management and type safety.
CustomDirective<T>
Interface for defining custom directives with typed value handling and lifecycle management.
METHOD bind?(element, value, expression, component, ...)
Called once when directive is first bound to an element. Use for initial setup and event listeners.
const fadeDirective: CustomDirective<number> = {
  bind(element, value, expression, component) {
    element.style.transition = 'opacity 0.3s';
    element.style.opacity = value.toString();
  }
};METHOD update?(element, value, expression, component, ...)
Called whenever reactive dependencies change. Use to update the DOM based on new values.
const fadeDirective: CustomDirective<number> = {
  update(element, value) {
    element.style.opacity = value.toString();
  }
};METHOD unbind?(element, component)
Called when directive is removed (cleanup). Use to remove event listeners and clean up resources.
const fadeDirective: CustomDirective<number> = {
  unbind(element) {
    element.style.transition = '';
    element.style.opacity = '';
  }
};update?(element, value, expression, component, modifiers?, evaluator?)
Called whenever reactive dependencies change.
const fadeDirective: CustomDirective<number> = {
  update(element, value) {
    element.style.opacity = value.toString();
  }
};unbind?(element, component)
Called when directive is removed (cleanup).
const fadeDirective: CustomDirective<number> = {
  unbind(element) {
    element.style.transition = '';
    element.style.opacity = '';
  }
};Complete Example
Full directive implementation with TypeScript.
interface TooltipConfig {
  text: string;
  position?: 'top' | 'bottom' | 'left' | 'right';
  delay?: number;
}
const tooltipDirective: CustomDirective<TooltipConfig> = {
  bind(element, value, expression, component, modifiers) {
    const config = typeof value === 'string' ? { text: value } : value;
    
    // Create tooltip element
    const tooltip = document.createElement('div');
    tooltip.className = 'tooltip';
    tooltip.textContent = config.text;
    
    // Store for cleanup
    (element as any)._tooltip = tooltip;
    
    // Add event listeners
    element.addEventListener('mouseenter', showTooltip);
    element.addEventListener('mouseleave', hideTooltip);
  },
  
  update(element, value) {
    const tooltip = (element as any)._tooltip;
    if (tooltip) {
      const config = typeof value === 'string' ? { text: value } : value;
      tooltip.textContent = config.text;
    }
  },
  
  unbind(element) {
    const tooltip = (element as any)._tooltip;
    if (tooltip) {
      tooltip.remove();
      delete (element as any)._tooltip;
    }
    element.removeEventListener('mouseenter', showTooltip);
    element.removeEventListener('mouseleave', hideTooltip);
  }
};Type Utilities
Advanced TypeScript utilities for enhanced type safety and developer experience.
Type Helpers
Advanced TypeScript utilities used internally by the framework for enhanced type safety.
TYPE DeepReadonly<T>
Deep readonly utility preventing mutations in computed getters.
// Data is DeepReadonly in computed
computed: {
  summary() {
    // this.users is DeepReadonly<User[]>
    // Prevents: this.users.push(newUser)
    return this.users.length;
  }
}TYPE ComputedValues<TComputed>
Derives computed value types from getter functions.
const computed = {
  fullName(): string { /* ... */ },
  age(): number { /* ... */ }
};
// ComputedValues<typeof computed> = {
//   fullName: string;
//   age: number;
// }TYPE WithThisForMethods<TCtx, TMethods>
Injects proper 'this' context into method signatures.
// Original method signature
const methods = {
  updateUser(id: number, data: UserData) { /* ... */ }
};
// With proper 'this' binding:
// (this: ComponentContext, id: number, data: UserData) => voidTYPE HtmlTag
Template literal type for HTML template strings.
import { html } from 'fynejs';
const template = html`
  <div class="${className}">
    <h1>${title}</h1>
    <p>${content}</p>
  </div>
`;TYPE ComponentSource
Configuration object for component loading with path, mode, and optional name.
interface ComponentSource {
  path: string;                          // Component file path
  mode?: 'preload' | 'defer' | 'lazy';    // Loading strategy
  name?: string;                         // Override component name
}
// Usage in loadComponents
const sources = [
  'components/button.js',                     // string (preload mode)
  { path: 'modal.js', mode: 'defer' },          // ComponentSource
  { path: 'chart.js', mode: 'lazy', name: 'data-chart' }
];TYPE ComponentLoaderResult
Return type from loadComponents() showing load success counts and failures.
interface ComponentLoaderResult {
  settled: number;    // Successfully loaded (preload + defer modes)
  failed: number;     // Failed immediate loads
}
// Example result
const result = await XTool.loadComponents(['a.js', 'b.js']);
console.log(`Loaded: ${result.settled}, Failed: ${result.failed}`);Global Declarations
Global types and module declarations for both browser and bundler environments.
Browser Environment
Global declarations available in browser environments via script tags.
Global Window Objects
// Available on window object
declare global {
  interface Window {
    XTool: XToolFramework;
    FyneJS: XToolFramework;  // Alias
  }
}
// Usage in browser
<script src="..."></script>
<script>
  // Both are available
  XTool.init();
  FyneJS.init();  // Same instance
</script>Both XTool and FyneJS reference the same framework instance.
Module Exports
ESM and CommonJS module declarations for modern bundlers and Node.js environments.
ESM ES Module Imports
// Named imports
import { XTool, FyneJS, html } from 'fynejs';
import type { ComponentDefinition, XToolConfig } from 'fynejs';
// Default import
import XTool from 'fynejs';CJS CommonJS Requires
// Destructured require
const { XTool, FyneJS, html } = require('fynejs');
// Default require
const XTool = require('fynejs').default;HELPER HTML Template Helper
Tagged template literal for HTML strings with syntax highlighting support in IDEs.
import { html } from 'fynejs';
// Template literal with syntax highlighting
const template = html`
  <div x-data="{ count: 0 }">
    <span x-text="count"></span>
    <button x-on:click="count++">Increment</button>
  </div>
`;