@komputronika/kancil-js
v0.5.4
Published
Lightweight JavaScript utility library for web applications
Maintainers
Readme
Kancil.js
A lightweight, zero-dependency JavaScript utility library for modern web applications. Provides essential building blocks for building web apps including API client, authentication, shopping cart, state management, and UI components - all without requiring any external dependencies.
Features
- Api - HTTP client with caching & multi-server fallback
- Auth - JWT token handling & role-based access
- Cart - Shopping cart with localStorage persistence
- Storage - Simple localStorage wrapper with namespace support
- PubSub - Event pub/sub system for component communication
- State - Reactive state management
- UI - Dialogs, notifications, loading indicators (no Bootstrap required!)
Install
Option 1: Via NPM (recommended for bundlers)
npm install @komputronika/kancil-jsimport { Api, Auth, Cart, Storage, PubSub, State, UI, utils } from '@komputronika/kancil-js';Option 2: Via CDN (browser without bundler)
<!-- unpkg -->
<script src="https://unpkg.com/@komputronika/[email protected]/kancil.js"></script>
<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/@komputronika/[email protected]/kancil.js"></script>After loading, use the Kancil object:
const api = new Kancil.Api({ baseServer: ['https://api.example.com'] });
const cart = new Kancil.Cart();
const auth = new Kancil.Auth();
const ui = new Kancil.UI();Quick Start
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<h1 id="counter">Count: 0</h1>
<button onclick="increment()">Increment</button>
<script src="https://cdn.jsdelivr.net/npm/@komputronika/[email protected]/kancil.js"></script>
<script>
// Initialize reactive state
const state = Kancil.State({ count: 0 });
// Subscribe to changes
state.subscribe('count', val => {
document.getElementById('counter').textContent = 'Count: ' + val;
});
function increment() {
state.set('count', state.get('count') + 1);
}
</script>
</body>
</html>API Reference
Kancil.Api
HTTP client with built-in caching and multi-server fallback.
const api = new Kancil.Api({
baseServer: ['https://api.example.com'],
debug: true,
});
// Simple request
const users = await api.noCache('GET', '/users');
// With caching (5 minutes)
const products = await api.useCache('GET', '/products', null, true, 300000);
// POST request
await api.noCache('POST', '/orders', { item: 'Book' });Methods:
noCache(method, path, data, withToken)- Make request without cachinguseCache(method, path, data, withToken, ttl)- Make request with cachinggetCache(url)/setCache(url, data, ttl)/clearCache()- Cache management
Kancil.Auth
Authentication handler with JWT support.
const auth = new Kancil.Auth('my_token');
// Set token
auth.setToken('eyJhbGci...');
// Check login status
if (auth.isLoggedIn()) {
const user = auth.getUser();
console.log(user.name);
}
// Check role
if (auth.hasRole('admin')) {
// admin only
}
// Logout
auth.logout();Methods:
setToken(token)/getToken()- Token managementisLoggedIn()- Check if logged ingetUser()- Get decoded user from JWThasRole(role)- Check user roleisTokenExpired()- Check token expirationlogout()- Clear token
Kancil.Cart
Shopping cart with localStorage persistence.
const cart = new Kancil.Cart({ storageKey: 'my_cart' });
// Add item
cart.addItem({
id: 1,
name: 'Laptop',
price: 5000000,
quantity: 1,
});
// Update quantity
cart.updateItemQuantity(1, 2);
// Remove item
cart.removeItem(1);
// Get data
const items = cart.getItems();
const total = cart.getTotal();
const count = cart.getCount();
// Clear cart
cart.clear();Kancil.Storage
Simple localStorage wrapper with namespace support.
const storage = new Kancil.Storage('myapp');
// Set value
storage.set('user', { name: 'John', age: 30 });
storage.set('theme', 'dark');
// Get value
const user = storage.get('user'); // { name: 'John', age: 30 }
// Check existence
if (storage.has('theme')) {
}
// Remove
storage.remove('theme');
// Get all keys
const keys = storage.keys();
// Clear all with namespace
storage.clearAll();Kancil.PubSub
Event pub/sub for component communication.
const pubsub = new Kancil.PubSub();
// Subscribe
const unsubscribe = pubsub.subscribe('user:login', data => {
console.log('User logged in:', data);
});
// Publish
pubsub.publish('user:login', { name: 'John', id: 1 });
// Unsubscribe single
unsubscribe();
// Unsubscribe all
pubsub.unsubscribe('user:login');Kancil.State
Simple reactive state management.
const state = Kancil.State({
count: 0,
user: null,
});
// Get value
console.log(state.get('count'));
// Set value
state.set('count', 5);
state.set('user.name', 'John'); // nested
// Subscribe to changes
state.subscribe('count', newValue => {
console.log('Count changed to:', newValue);
});
// Computed values
state.computed('double', () => state.state.count * 2);
// Access state directly
state.state.count = 10; // triggers updatesKancil.UI
Dialogs, notifications, and loading indicators. No dependencies!
const ui = new Kancil.UI();
// Info dialog
ui.showInfoDialog('Operation successful!');
// Confirm dialog
ui.showConfirmDialog(
'Delete this item?',
() => {
console.log('Confirmed!');
},
() => {
console.log('Cancelled!');
}
);
// Snackbar/Toast
ui.showSnackbar('success', 'Saved!', 3000);
ui.showSnackbar('error', 'Error occurred!', 5000);
ui.showSnackbar('warning', 'Warning message');
ui.showSnackbar('info', 'Information');
// Snackbar at top
ui.showSnackbar('success', 'Message!', 3000, 'top');
// Loading
ui.showLoading();
// ... async work ...
ui.hideLoading();
// Alert
ui.showAlert('success', 'Success message!');
// Bottom Sheet (requires element with id="bottomSheet")
ui.openBottomSheet('bottomSheet', '<p>Content here</p>');
ui.closeBottomSheet('bottomSheet');Kancil.utils
Helper functions.
// Get current date (YYYY-MM-DD)
Kancil.utils.now(); // "2025-01-15"
Kancil.utils.now(0); // Today
Kancil.utils.now(7); // 7 days from now
// Get long date format
Kancil.utils.nowLong(); // "Wednesday, January 15, 2025"
// Title Case
Kancil.utils.titleCase('hello world'); // "Hello World"
// Navigate
Kancil.utils.navigate('https://example.com');Kancil.constants
Kancil.constants.TTL_3_JAM; // 10800000 ms (3 hours)
Kancil.constants.TTL_6_JAM; // 21600000 ms (6 hours)Configuration
Disable Debug Logs
// In browser console or before loading script
window.__KANCILE_DEV__ = false;Or in Node.js:
process.env.NODE_ENV = 'production';Browser Support
- Chrome / Edge / Firefox / Safari (latest 2 versions)
- No polyfills required
License
MIT License
Version History
0.5.4
- Fix bug in ESM export
0.5.2
- ESM export support for Node.js (for NPM/bundlers)
0.5.0
- UI class rewritten - no CSS framework dependency
- Added JSDoc comments
- Added unit tests (47 tests)
- Initial NPM release
