Loading resources...
If the screen stays blank, please try refreshing.
During multiple frontend development cycles, I frequently encountered repetitive data processing modules (date formatting, user validation, currency notation, crypto operations, etc.) being newly built from scratch each time. This led to maintainability trade-offs and fragmented module dependencies.
To resolve these core inefficiencies, I engineered a centralized library designed to secure system-wide code consistency, maximize production efficiency by reusing fully optimized logic, and provide continuous long-term maintainability.
Jest, drastically boosting production-grade reliability.package.json to publish frictionless, plug-and-play modules into the global NPM registry ecosystem.A set of JavaScript utilities for use in the browser.
npm install isa-util
yarn add isa-util
import {
isArray,
getQuery,
encryptData,
decryptData,
generateSalt,
generatePassword,
generatePasswordWithSaltAndEncrypt,
decryptPasswordWithSalt
} from 'isa-util';
async function demoEncryption() {
const message = 'Secret message';
const { password, salt, encryptedData } = await generatePasswordWithSaltAndEncrypt(16, message);
const decrypted = await decryptPasswordWithSalt(
encryptedData.encryptedData,
encryptedData.iv,
password,
salt
);
console.log(decrypted); // 'Secret message'
}
demoEncryption();
---
isArray([1, 2, 3]); // true
isString('hello'); // true
isObject({ a: 1 }); // true
const query = getQuery();
console.log(query.get('page')); // e.g. '1'
query.set('page', '2');
setQuery(query); // URL μ
λ°μ΄νΈ
addComma(1234567); // '1,234,567'
camelCase('@#@assd-wsd_asd fkfk'); // assdWsdAsdFkfk
formatClass(
'a',
{ b: true, c: false },
['d', { e: true, f: 0 }, ['g', ['', null]]],
0,
undefined,
); //a b d e g 0
loadCDN('jquery', 'https://code.jquery.com/jquery-3.6.0.min.js');
const blob = new Blob(['Hello world'], { type: 'text/plain' });
download(blob, 'hello.txt', 'text/plain');
const debounced = debounce(() => console.log('called'), 300);
debounced();
debounced(); // λ§μ§λ§ νΈμΆλ§ μ€νλ¨
const throttled = throttle(() => console.log('tick'), 1000);
throttled();
throttled(); // 1μ΄μ ν λ²λ§ μ€νλ¨
getPlatform(); // { os: 'iOS', browser: 'Safari', mobile: true }
isMobile(); // true/false
isDarkMode(); // true/false
const salt = generateSalt();
const password = generatePassword(16);
const encrypted = await encryptData('secret', password, salt);
const decrypted = await decryptData(
encrypted.encryptedData,
encrypted.iv,
password,
salt,
);
formatDate(new Date(), 'YYYY-MM-DD'); // '2025-05-13'
timeAgo(new Date(Date.now() - 60000)); // '1 minute ago'
isToday(new Date()); // true
setLocalStorage('key', { name: 'isa' });
getLocalStorage('key'); // { name: 'isa' }
removeLocalStorage('key');
const db = await idb.open('my-db', {
version: 1,
schema: {
users: { keyPath: 'id', autoIncrement: true },
},
});
console.log(db.objectStoreNames); // ["users"]
addClass(document.body, 'dark');
hasClass(document.body, 'dark'); // true
toggleClass(document.body, 'dark'); // toggle
// FlushQueue
const fq = new FlushQueue();
fq.add('job1', async () => console.log('job 1'));
fq.add('job2', async () => console.log('job 2'));
await fq.flush(); // λ³λ ¬ μ€ν
// JobQueue
const jq = new JobQueue<string>(async (job) => {
console.log('processing', job);
await new Promise((r) => setTimeout(r, 300));
});
jq.enqueue('task A');
jq.enqueue('task B'); // μμ°¨ μ€ν
isArray(arg: any): boolean
Checks if the argument is an array.
Usage Example:
isArray([1, 2, 3]); // true
isArray('hello'); // false
isFunction(arg: any): boolean
Checks if the argument is a function.
Usage Example:
isFunction(() => {}); // true
isFunction(123); // false
isObject(arg: any): boolean
Checks if the argument is an object.
Usage Example:
isObject({ key: 'value' }); // true
isObject([1, 2, 3]); // false
isString(arg: any): boolean
Checks if the argument is a string.
Usage Example:
isString('Hello, world!'); // true
isString(123); // false
isNumber(arg: any): boolean
Checks if the argument is a number.
Usage Example:
isNumber(42); // true
isNumber('Hello'); // false
isSymbol(arg: any): boolean
Checks if the argument is a symbol.
Usage Example:
isSymbol(Symbol('test')); // true
isSymbol('not a symbol'); // false
isBlob(arg: any): boolean
Checks if the argument is a Blob.
Usage Example:
isBlob(new Blob()); // true
isBlob('not a blob'); // false
isUndefined(arg: any): boolean
Checks if the argument is undefined.
Usage Example:
isUndefined(undefined); // true
isUndefined(null); // false
isFalsy(arg: any): boolean
Checks if the argument is falsy (false, 0, "", null, undefined, NaN).
isUndefined(undefined); // true
isUndefined(null); // false
isFalsy(arg: any): boolean
Checks if the argument is falsy (false, 0, "", null, undefined, NaN).
Usage Example:
isFalsy(null); // true
isFalsy(0); // true
isFalsy('hello'); // false
isTruthy(arg: any): boolean
Checks if the argument is truthy (not falsy).
Usage Example:
isTruthy(1); // true
isTruthy(''); // false
getQuery(): URLSearchParams
Retrieves the current URL query parameters as a URLSearchParams object.
Usage Example:
const queryParams = getQuery();
console.log(queryParams.get('user')); // prints the value of 'user' query parameter
setQuery(arg: URLSearchParams): void
Sets the URL query parameters using a URLSearchParams object.
Usage Example:
const params = new URLSearchParams();
params.append('page', '1');
setQuery(params); // Updates the URL's query params to ?page=1
addComma(arg: number): string
Formats a number by adding commas as thousand separators.
Usage Example:
addComma(1000000); // "1,000,000"
camelCase(input: string): string
Formats a string by camelCase.
Usage Example:
camelCase('@#@assd-wsd_asd fkfk'); // assdWsdAsdFkfk
pascalCase(input: string): string
Formats a string by pascalCase.
Usage Example:
pascalCase('@#@assd-wsd_asd fkfk'); // AssdWsdAsdFkfk
snakeCase(input: string): string
Formats a string by snakeCase.
Usage Example:
snakeCase('@#@assd-wsd_asd fkfk'); // assd_wsd_asd_fkfk
formatClass(...args: any): string | cx(...args): string
Formats args by className.
Usage Example:
formatClass('a', 0, 1); // 'a 0 1'
loadCDN(id: string, src: string, options?: ScriptAttribute): Promise<void>
Dynamically loads a script from a CDN with optional attributes.
Usage Example:
loadCDN(
'lodash',
'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js',
);
download(data: Blob, name: string, type: string): void
Triggers a download for a given Blob with the specified filename and MIME type.
Usage Example:
const blob = new Blob(['Hello, world!'], { type: 'text/plain' });
download(blob, 'hello.txt', 'text/plain');
debounce(func: Function, wait: number): Function & { cancel: () => void; pending: () => boolean; }
Creates a debounced function that delays invoking func until after wait milliseconds have passed. Returns a function with cancel and pending methods.
Usage Example:
const handler = debounce(() => console.log('called!'), 300);
handler();
handler(); // Only the last call within 300ms will be executed
throttle<T extends any[], R>(func: FuncType<T, R>, wait: number): (...args: T) => R | void
Creates a throttled function that only invokes func at most once per wait milliseconds.
Usage Example:
const throttledLog = throttle(() => console.log('Logged!'), 1000);
throttledLog();
throttledLog(); // Will log only once per 1000ms
getPlatform(): { os: string, browser: string, mobile: boolean } | null
Returns an object containing the user's platform information, including the operating system, browser, and whether the user is on a mobile device.
Usage Example:
const platform = getPlatform();
console.log(platform.os, platform.browser); // logs current platform info
JobQueue<T>(processJob: (job: T) => Promise<void>): enqueue(job: T)
A class that manages a queue of asynchronous jobs and processes them one at a time. Jobs are added to the queue using enqueue, and the class ensures they are processed sequentially.
Usage Example:
const queue = new JobQueue<string>(async (job) => {
console.log(`Processing job: ${job}`);
await new Promise((resolve) => setTimeout(resolve, 1000)); // 1μ΄ λκΈ°
});
queue.enqueue('Job 1');
queue.enqueue('Job 2');
queue.enqueue('Job 3');
FlushQueue(options: FlushQueueOptions): add(id: string, job: AsyncJob)
A class that manages a queue of asynchronous jobs with optional debounce and custom start/finish handlers. Jobs can be added, canceled, and flushed either in parallel or sequentially.
Usage Example:
const queue = new FlushQueue({
debounceMs: 300, // Debounce for 300ms before flushing
onStart: (id) => console.log(`Starting job ${id}`),
onFinish: (id, error) => {
if (error) {
console.error(`Job ${id} failed`, error);
} else {
console.log(`Job ${id} finished`);
}
},
});
const job1: AsyncJob = async () => {
console.log('Processing Job 1');
await new Promise((resolve) => setTimeout(resolve, 1000));
};
const job2: AsyncJob = async () => {
console.log('Processing Job 2');
await new Promise((resolve) => setTimeout(resolve, 1000));
};
queue.add('job1', job1);
queue.add('job2', job2);
// Force flush all jobs sequentially
queue.flush(false);
sleep(ms: number): Promise<void>
A utility function that pauses the execution for the specified number of milliseconds by returning a Promise that resolves after the given delay.
Usage Example:
async function example() {
console.log('Start');
await sleep(1000); // Sleep for 1 second
console.log('End after 1 second');
}
example();
Note: Encryption uses AES-GCM with 256-bit keys derived via PBKDF2 (SHA-256, 100,000 iterations).
encryptData(data: string, password: string, salt: string): Promise<{ iv: number[], encryptedData: number[] }>
Encrypts a string using AES-GCM with a password-derived key and returns the IV and encrypted data.Usage Example:
const { iv, encryptedData } = await encryptData('Hello', 'password', 'salt');
console.log(encryptedData);
decryptData(encryptedData: number[], iv: number[], password: string, salt: string): Promise<string>
Decrypts AES-GCM encrypted data using the provided IV, password, and salt.
Usage Example:
const decrypted = await decryptData(encryptedData, iv, 'password', 'salt');
console.log(decrypted); // 'Hello'
generateSalt(): string
Generates a 16-byte random salt string.
generatePassword(length: number): string
Generates a random password of the specified length.
generatePasswordWithSalt(length: number): { password: string, salt: string }
Generates a random password and salt.
generatePasswordWithSaltAndEncrypt(length: number, data: string): Promise<{ password: string, salt: string, encryptedData: { iv: number[], encryptedData: number[] } }>
Generates a password and salt, encrypts the provided data, and returns all components.
decryptPasswordWithSalt(encryptedData: number[], iv: number[], password: string, salt: string): Promise<string>
Decrypts data using the given encryptedData, IV, password, and salt.
decryptPasswordWithSaltAndEncrypt(encryptedData: number[], iv: number[], password: string, salt: string, data: string): Promise<string>
Decrypts and verifies that the decrypted data matches the original input.
formatDate(date: Date, format: string): string
Formats a JavaScript Date object into a custom string format like 'YYYY-MM-DD HH:mm:ss'.
Usage Example:
formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'); // "2025-05-13 12:34:56"
timeAgo(date: Date | string): string
Returns a human-readable time difference string like "5 minutes ago" or "2 days ago".
Usage Example:
timeAgo(new Date('2025-05-12')); // "1 day ago"
isToday(date: Date): boolean
Returns true if the given date is today.
Usage Example:
isToday(new Date('2005-05-12')); // "false"
isMobile(): boolean
Detects whether the current device is a mobile device.
isDarkMode(): boolean
Detects whether the user's system prefers dark mode.
isTouchDevice(): boolean
Checks if the current device supports touch interactions.
setLocalStorage(key: string, value: any): void
Sets a value in localStorage.
Usage Example:
setLocalStorage('user', { name: 'Alice' });
getLocalStorage(key: string): any
Retrieves a value from localStorage.
Usage Example:
const user = getLocalStorage('user');
console.log(user.name); // "Alice"
removeLocalStorage(key: string): void
Removes a value from localStorage.
interface IDBOpenOptions: {
version?: number;
schema?: Record<string, IDBObjectStoreParameters>;
}
interface CursorOptions<T = any> {
range?: IDBKeyRange | null;
offset?: number;
limit?: number;
filter?: (value: T, key: IDBValidKey) => boolean;
sort?: (a: T, b: T) => number;
}
idb.open(name: string, options?: IDBOpenOptions): Promise<IDBDatabase>
Opens an IndexedDB database, creating object stores if they donβt exist.
Usage Example:
const db = await idb.open('my-db', {
version: 1,
schema: {
users: { keyPath: 'id', autoIncrement: true },
},
});
console.log(db.objectStoreNames); // ["users"]
idb.get<T>(dbName: string, store: string, key: IDBValidKey): Promise<T | undefined>
Retrieves a single item from the specified object store by key.
Usage Example:
const user = await idb.get('my-db', 'users', 1);
console.log(user?.name); // "Alice"
idb.put<T>(dbName: string, store: string, value: T): Promise<IDBValidKey>
Inserts or updates an item in the object store.
Usage Example:
const key = await idb.put('my-db', 'users', { name: 'Alice' });
console.log(key); // 1
idb.clear(dbName: string, store: string): Promise<void>
Removes all items from the specified object store.
Usage Example:
await idb.clear('my-db', 'users');
idb.deleteDB(name: string): Promise<void>
Deletes the entire database.
Usage Example:
await idb.deleteDB('my-db');
idb.cursor.each<T>(dbName: string, store: string, callback: (value: T, key: IDBValidKey, cursor: IDBCursorWithValue) => void): Promise<void>
Iterates over all items in the store and executes the callback for each.
Usage Example:
await idb.cursor.each('my-db', 'users', (value, key) => {
console.log(key, value.name);
});
idb.cursor.query<T>(dbName: string, store: string, options?: CursorOptions<T>): Promise<T[]>
Advanced cursor query with optional filter, sort, offset, and limit.
Usage Example:
const users = await idb.cursor.query('my-db', 'users', {
filter: (user) => user.age >= 18,
sort: (a, b) => a.age - b.age,
offset: 1,
limit: 2,
});
console.log(users);
hasClass(el: Element, className: string): boolean
Checks if an element contains a class.
Usage Example:
hasClass(document.body, 'dark-mode'); // true/false
addClass(el: Element, className: string): void
Adds a class to an element.
Usage Example:
addClass(document.body, 'dark-mode');
removeClass(el: Element, className: string): void
Removes a class from an element.
Usage Example:
removeClass(document.body, 'dark-mode');
toggleClass(el: Element, className: string): void
Toggles a class on an element.
This project is licensed under the MIT License. For more details, see the LICENSE.