KimuEngine โ
Rendering engine and template management that provides core functionality for rendering, template loading, and dynamic component management.
Description โ
KimuEngine acts as a bridge between the rendering system (Lit) and the asset manager, providing unified APIs for:
- Style injection in Shadow DOM
- HTML template loading and compilation
- Reactive rendering with Lit
- Dynamic component loading
All methods are static, making the class a central utility for rendering operations.
Usage โ
Style Injection โ
import { KimuEngine } from './core/kimu-engine';
// Inject style into a component
await KimuEngine.injectStyle(
this, // Target component
'assets/theme.css', // CSS path
'my-theme-style' // Unique ID (optional)
);Template Loading โ
// Load and compile HTML template
const renderFunction = await KimuEngine.loadTemplate('/extensions/my-app/view.html');
// Use the rendering function
KimuEngine.render(this, { title: 'Hello!' }, renderFunction);Direct Rendering โ
// Compile template from string
const templateString = '<h1>${title}</h1><p>${description}</p>';
const renderFn = KimuEngine.compileTemplate(templateString);
// Rendering with data
KimuEngine.render(this, {
title: 'Dynamic Title',
description: 'Updated content'
}, renderFn);API โ
Style Management โ
injectStyle(component, stylePath, styleId?): Promise<void> โ
Injects a CSS file into the component's Shadow DOM.
Parameters:
component: HTMLElement- Target componentstylePath: string- Path to CSS filestyleId: string | null- Unique ID for the style element (optional)
Example:
// Inject main style
await KimuEngine.injectStyle(this, 'assets/main.css', 'main-style');
// Inject conditional theme
if (isDarkMode) {
await KimuEngine.injectStyle(this, 'assets/dark-theme.css', 'dark-theme');
}Template Management โ
loadTemplate(path): Promise<Function> โ
Loads an HTML template file and compiles it into a Lit rendering function.
Parameters:
path: string- Path to template file
Returns: Promise<Function> - Compiled rendering function
Example:
// In a component
async connectedCallback(): Promise<void> {
const templatePath = `/extensions/${this.getMeta().basePath}/view.html`;
this._renderFn = await KimuEngine.loadTemplate(templatePath);
this.refresh();
}compileTemplate(template): Function โ
Compiles an HTML string into a Lit rendering function.
Parameters:
template: string- HTML template string
Returns: Function - Rendering function
Example:
// Dynamic template
const templateStr = `
<div class="card">
<h2>\${title}</h2>
<p>\${description}</p>
<button onclick="\${onClick}">\${buttonLabel}</button>
</div>
`;
const renderFn = KimuEngine.compileTemplate(templateStr);
// Immediate use
KimuEngine.render(this, {
title: 'Dynamic Card',
description: 'Generated at runtime',
buttonLabel: 'Click here',
onClick: 'handleClick()'
}, renderFn);Rendering โ
render(component, data, renderFn): void โ
Performs reactive rendering using Lit.
Parameters:
component: HTMLElement- Target componentdata: Record<string, any>- Data for the templaterenderFn: Function- Rendering function
Example:
// Rendering with dynamic data
const data = {
users: ['Alice', 'Bob', 'Charlie'],
currentTime: new Date().toLocaleString(),
isLoggedIn: true
};
KimuEngine.render(this, data, this._renderFn);Component Loading โ
loadComponent(tag, path): Promise<any> โ
Loads a component from a specific path and registers it if not already registered.
Parameters:
tag: string- Component tag namepath: string- Path to component module
Returns: Promise<any> - Loaded module
Example:
// Dynamic component loading
await KimuEngine.loadComponent(
'custom-widget',
'/extensions/widgets/custom-widget/component.js'
);
// Now the component can be used
const widget = document.createElement('custom-widget');Advanced Examples โ
Dynamic Theme System โ
class ThemeManager {
static async applyTheme(component: HTMLElement, themeName: string): Promise<void> {
// Remove previous theme
const oldTheme = component.shadowRoot?.getElementById('current-theme');
if (oldTheme) {
oldTheme.remove();
}
// Load new theme
await KimuEngine.injectStyle(
component,
`assets/themes/${themeName}.css`,
'current-theme'
);
}
}
// Usage
await ThemeManager.applyTheme(this, 'dark');Conditional Templates โ
class ConditionalRenderer {
static async renderByCondition(
component: HTMLElement,
condition: string,
data: any
): Promise<void> {
// Select template based on condition
const templateMap = {
'loading': 'templates/loading.html',
'error': 'templates/error.html',
'success': 'templates/content.html'
};
const templatePath = templateMap[condition] || templateMap['error'];
const renderFn = await KimuEngine.loadTemplate(templatePath);
KimuEngine.render(component, data, renderFn);
}
}
// Usage
await ConditionalRenderer.renderByCondition(this, 'loading', {
message: 'Loading in progress...'
});Dynamic Template Builder โ
class TemplateBuilder {
private static buildListTemplate(items: any[]): string {
const itemTemplates = items.map((_, index) =>
`<li class="item">\${items[${index}].name}</li>`
).join('');
return `
<div class="list-container">
<h3>\${title}</h3>
<ul class="items">
${itemTemplates}
</ul>
</div>
`;
}
static renderDynamicList(component: HTMLElement, data: any): void {
const template = this.buildListTemplate(data.items);
const renderFn = KimuEngine.compileTemplate(template);
KimuEngine.render(component, data, renderFn);
}
}
// Usage
TemplateBuilder.renderDynamicList(this, {
title: 'Dynamic List',
items: [
{ name: 'Item 1' },
{ name: 'Item 2' },
{ name: 'Item 3' }
]
});Rendering with Performance Monitoring โ
class PerformantRenderer {
static async renderWithProfiling(
component: HTMLElement,
data: any,
renderFn: Function,
label = 'render'
): Promise<void> {
// Start profiling
performance.mark(`${label}-start`);
try {
KimuEngine.render(component, data, renderFn);
// End profiling
performance.mark(`${label}-end`);
performance.measure(label, `${label}-start`, `${label}-end`);
const measure = performance.getEntriesByName(label)[0];
console.log(`๐ฏ Rendering ${label}: ${measure.duration.toFixed(2)}ms`);
} catch (error) {
console.error(`โ Rendering error ${label}:`, error);
} finally {
// Cleanup
performance.clearMarks(`${label}-start`);
performance.clearMarks(`${label}-end`);
performance.clearMeasures(label);
}
}
}Integration with Lit โ
KimuEngine internally uses Lit for reactive rendering:
import { html, render as litRender, TemplateResult } from 'lit';
// The compiled template uses Lit syntax
const template = html`
<div class="component">
<h1>${data.title}</h1>
<p>${data.content}</p>
</div>
`;
// Rendering in Shadow DOM
litRender(template, component.shadowRoot!);Best Practices โ
โ Error Handling โ
try {
const renderFn = await KimuEngine.loadTemplate(templatePath);
KimuEngine.render(this, data, renderFn);
} catch (error) {
console.error('Rendering error:', error);
// Fallback template
const fallbackFn = KimuEngine.compileTemplate('<p>Loading error</p>');
KimuEngine.render(this, {}, fallbackFn);
}โ Template Caching โ
private static templateCache = new Map<string, Function>();
static async getCachedTemplate(path: string): Promise<Function> {
if (!this.templateCache.has(path)) {
const renderFn = await KimuEngine.loadTemplate(path);
this.templateCache.set(path, renderFn);
}
return this.templateCache.get(path)!;
}โ Lazy Loading Components โ
static async loadComponentLazy(tag: string): Promise<void> {
if (!customElements.get(tag)) {
const path = `/extensions/${tag}/component.js`;
await KimuEngine.loadComponent(tag, path);
}
}Optimizations and Cache Management โ
Template Cache Management โ
KimuEngine includes an intelligent cache system with memory management.
configureCaching(maxSize: number): void (Static) โ
Configure template cache settings.
Parameters:
maxSize: number- Maximum cache size (default: 50)
Example:
// Cache configuration for large apps
KimuEngine.configureCaching(100);
// Conservative configuration for low-memory devices
KimuEngine.configureCaching(25);clearCaches(): void (Static) โ
Clear all caches (useful for debugging and testing).
// Clear caches for testing
KimuEngine.clearCaches();
// After template updates
if (developmentMode) {
KimuEngine.clearCaches();
}Advanced Asset Preloading โ
preloadAssets(paths: string[]): Promise<void> (Static) โ
Preload assets in batches to improve performance.
Features:
- Batch loading with concurrency control (5 assets at a time)
- Graceful error handling for missing assets
- Support for templates (.html), styles (.css), and generic assets
Example:
// Preload critical assets
await KimuEngine.preloadAssets([
'extensions/dashboard/view.html',
'extensions/dashboard/style.css',
'extensions/sidebar/view.html',
'extensions/navigation/style.css',
'assets/icons.css',
'assets/theme.css'
]);
// Conditional preloading
if (userPreferences.preloadEnabled) {
const criticalAssets = getCriticalAssetsForUser();
await KimuEngine.preloadAssets(criticalAssets);
}LRU (Least Recently Used) Cache โ
The cache system uses LRU algorithm for automatic memory management:
// Internal cache with access tracking
// - Automatic removal of least used entries
// - Evicts 20% when limit is reached
// - Timestamp tracking for LRU algorithm
// Cache monitoring (automatic console.log)
// "[KimuEngine] Evicted X old template cache entries"Performance Monitoring โ
class PerformanceMonitor {
static measureTemplateLoad(path: string) {
const start = performance.now();
return KimuEngine.loadTemplate(path).then(result => {
const duration = performance.now() - start;
console.log(`Template ${path} loaded in ${duration.toFixed(2)}ms`);
return result;
});
}
static async benchmarkPreloading(assets: string[]) {
const start = performance.now();
await KimuEngine.preloadAssets(assets);
const duration = performance.now() - start;
console.log(`Preloaded ${assets.length} assets in ${duration.toFixed(2)}ms`);
}
}See Also โ
- KimuRender - Lit rendering system
- KimuAssetManager - Asset management
- KimuComponentElement - Component base class
- Asset Loading - Loading pattern