@balancy/utils
v1.2.3
Published
Balancy utility functions and helpers
Readme
@balancy/utils
Utility functions and helpers for the Balancy ecosystem.
⭐ Main Features
- IndexedDB FileHelper - Complete file system integration with IndexedDB for browser environments
- Utility Functions - Collection of useful helper functions for development
Installation
npm install @balancy/utils🚀 Quick Start with IndexedDB FileHelper
import { IndexedDBFileHelperAdapter } from '@balancy/utils';
import { Balancy } from '@balancy/core';
// Create and initialize the file helper
const fileHelperAdapter = await IndexedDBFileHelperAdapter.create({
cachePath: '.balancy'
});
// Get cache statistics
const stats = fileHelperAdapter.getCacheStats();
console.log(`📁 Files: ${stats.fileCount}, 💾 Memory: ${stats.memoryUsage}`);
// Initialize Balancy (DataObjectsManager integration is automatic)
await Balancy.Main.initializeFileHelper(fileHelperAdapter);🛠️ Using Utility Functions
import { isEmpty, deepClone, formatNumber, generateId, delay, retry } from '@balancy/utils';
// Check for empty values
console.log(isEmpty('')); // true
console.log(isEmpty([])); // true
console.log(isEmpty({})); // true
// Deep clone objects
const original = { a: 1, b: { c: 2 } };
const cloned = deepClone(original);
// Format numbers
console.log(formatNumber(1234567)); // "1,234,567"
// Generate random IDs
console.log(generateId()); // "AbC12xyz"
console.log(generateId(12)); // "AbC12xyzDeFg"
// Delay execution
await delay(1000); // wait 1 second
// Retry with exponential backoff
const result = await retry(async () => {
// some async operation
return await fetchData();
}, 3, 1000); // 3 attempts, 1s base delay📁 IndexedDB FileHelper API
IndexedDBFileHelperAdapter.create(config)
Main method to create a file system adapter.
interface FileHelperPaths {
cachePath: string; // Cache path (required)
codePath?: string; // Generated code path
resourcesPath?: string; // Resources path
}Alternative creation methods:
// Fast creation without preloading
const fastAdapter = await IndexedDBFileHelperAdapter.createFast({
cachePath: '.balancy'
});
// Creation with partial preloading
const partialAdapter = await IndexedDBFileHelperAdapter.createWithPartialPreload({
cachePath: '.balancy'
});Main methods:
getBinaryFile(key: string): Promise<Uint8Array | null>
Loads a binary file by key.
saveBinaryFile(key: string, data: Uint8Array): Promise<boolean>
Saves binary data.
hasFile(key: string): Promise<boolean>
Checks if file exists.
deleteFile(key: string): Promise<boolean>
Deletes file from cache.
getCacheStats(): CacheStats
Returns cache usage statistics.
interface CacheStats {
fileCount: number; // Number of files in cache
memoryUsage: string; // Memory usage (human readable)
hitRate?: number; // Cache hit rate percentage
totalRequests?: number; // Total number of requests
cacheHits?: number; // Number of cache hits
}🔧 Utility Functions
isEmpty(value: any): boolean
Checks if value is empty (null, undefined, empty string, empty array, empty object).
deepClone<T>(obj: T): T
Performs deep cloning of objects.
formatNumber(num: number, locale?: string): string
Formats numbers with thousand separators. Uses 'en-US' locale by default.
generateId(length?: number): string
Generates random ID of specified length (default 8 characters).
delay(ms: number): Promise<void>
Creates a delay for specified milliseconds.
retry<T>(fn: () => Promise<T>, maxAttempts?: number, baseDelay?: number): Promise<T>
Executes function with retry attempts on errors. Uses exponential backoff between attempts.
📖 Usage Examples
Game Data Integration
// Save game data
const gameData = {
playerLevel: 42,
coins: 1500,
achievements: ['first_win', 'level_10']
};
const jsonData = JSON.stringify(gameData);
await adapter.saveBinaryFile('player_data.json', new TextEncoder().encode(jsonData));
// Load game data
const savedData = await adapter.getBinaryFile('player_data.json');
if (savedData) {
const parsedData = JSON.parse(new TextDecoder().decode(savedData));
console.log('Game data:', parsedData);
}Performance Monitoring
const stats = adapter.getCacheStats();
console.log(`Cache hit rate: ${stats.hitRate}%`);
console.log(`Memory usage: ${stats.memoryUsage}`);
console.log(`Total files: ${stats.fileCount}`);🏗️ Preloading Strategies
The package supports different preloading strategies for optimal performance:
'full'- Loads ALL files into memory at initialization. Maximum performance, higher memory usage.'partial'- Loads only cache files. Balance between speed and memory.'none'- No preloading. Minimal memory usage, files loaded on demand.
📋 TypeScript Interfaces
// Main interfaces for FileHelper
interface FileHelperPaths {
cachePath: string;
codePath?: string;
resourcesPath?: string;
}
// Utility interfaces
interface RetryOptions {
maxAttempts?: number;
baseDelay?: number;
}
interface UtilsConfig {
defaultLocale?: string;
defaultIdLength?: number;
}🚨 Important Notes
Integration with Balancy Core
The @balancy/utils package is designed as an optional dependency of @balancy/core. This means:
✅ Can be used independently for IndexedDB functionality
✅ Can be integrated with Balancy Core for full functionality
✅ TypeScript support works fully in both cases
// Independent usage
import { IndexedDBFileHelperAdapter } from '@balancy/utils';
const adapter = await IndexedDBFileHelperAdapter.create({ cachePath: '.balancy' });
// Integration with Balancy (requires @balancy/core)
import { Balancy } from '@balancy/core';
import { IndexedDBFileHelperAdapter } from '@balancy/utils';
const adapter = await IndexedDBFileHelperAdapter.create({ cachePath: '.balancy' });
await Balancy.Main.initializeFileHelper(adapter); // Auto-configures DataObjectsManagerPerformance
- Strategy
'full'recommended for production applications - Strategy
'partial'suitable for development - Strategy
'none'for resource-constrained environments
Compatibility
- ✅ Modern browsers with IndexedDB support
- ✅ Web Workers (with limitations)
- ❌ Node.js (IndexedDB not available)
- ❌ React Native (requires polyfill)
License
MIT
Support
For questions and support, contact the Balancy team.
