UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

446 lines (303 loc) β€’ 13.5 kB
### πŸ“– `readBase64Blob(file: File, isDataUrl?: boolean | string): Promise<string>` Reads a file and returns its Base64 content using the FileReader API, with optional formatting as a full Data URL. #### πŸ“₯ Parameters * `file` *(File)*: The file object selected by the user (e.g., from an `<input type="file">` element). * `isDataUrl` *(boolean | string, optional)*: * If `false` *(default)*: returns only the Base64 portion. * If `true`: returns the original Data URL string from `FileReader`. * If a string: treated as a custom MIME type for building a new Data URL. #### πŸ“€ Returns * `Promise<string>`: Resolves with either the Base64 string or a complete Data URL, depending on `isDataUrl`. #### ⚠️ Throws * `TypeError` if: * The result is not a string. * The `isDataUrl` argument is not a boolean or a string. * `Error` if: * The string is not a valid Base64 or Data URL format. * The MIME string format is invalid. * `DOMException` if the file cannot be read by `FileReader`. #### πŸ§ͺ Example ```js const input = document.querySelector('input[type="file"]'); input.addEventListener('change', async () => { try { const base64 = await readBase64Blob(input.files[0], false); console.log(base64); // Logs only the Base64 string } catch (err) { console.error('Error reading file:', err.message); } }); ``` --- ### πŸ“– `readFileBlob(file: File, method: 'readAsArrayBuffer' | 'readAsDataURL' | 'readAsText' | 'readAsBinaryString'): Promise<any>` Reads the contents of a file using a specified FileReader method. #### πŸ“₯ Parameters * `file` *(File)*: The file object selected by the user (e.g., from an `<input type="file">` element). * `method` *(string)*: The FileReader method to use: * `'readAsArrayBuffer'` β€” for binary buffers * `'readAsDataURL'` β€” for Base64 encoded data URLs * `'readAsText'` β€” for plain text * `'readAsBinaryString'` β€” for legacy binary string output #### πŸ“€ Returns * `Promise<any>`: Resolves with the file content, depending on the method used. #### ⚠️ Throws * `Error` if an unexpected error occurs while resolving the result. * `DOMException` if `FileReader` encounters a failure during the read process. #### πŸ§ͺ Example ```js const input = document.querySelector('input[type="file"]'); input.addEventListener('change', async () => { try { const text = await readFileBlob(input.files[0], 'readAsText'); console.log(text); // Logs the file content as plain text } catch (err) { console.error('Error reading file:', err.message); } }); ``` --- ### πŸ“– `readJsonBlob(file: File): Promise<any>` Reads and parses a JSON file using the FileReader API. #### πŸ“₯ Parameters * `file` *(File)*: The file object selected by the user (e.g., from an `<input type="file">` element). #### πŸ“€ Returns * `Promise<any>`: Resolves with the parsed JSON object, or rejects with an error if the content is invalid. #### ⚠️ Throws * An error if the content is not valid JSON. * An error if the file can't be read. #### πŸ§ͺ Example ```js const input = document.querySelector('input[type="file"]'); input.addEventListener('change', async () => { try { const result = await readJsonBlob(input.files[0]); console.log(result); } catch (err) { alert(err.message); } }); ``` --- ### πŸ’Ύ `saveJsonFile(filename: string, data: any, spaces: number = 2): void` Converts a JavaScript object to JSON and triggers a download in the browser. #### πŸ“₯ Parameters * `filename` *(string)*: The name of the file to save (e.g., `"data.json"`). * `data` *(any)*: The JavaScript object to convert to JSON. * `spaces` *(number)* *(optional)*: Indentation level for formatting the JSON string. Default is `2`. #### πŸ“€ Returns * `void` #### πŸ“‚ Behavior Creates a temporary `<a>` element, downloads the file, and cleans up the URL. #### πŸ§ͺ Example ```js const data = { name: 'Yasmin', type: 'dev' }; saveJsonFile('yasmin.json', data); ``` ### 🌐 `fetchTemplate(...)` Loads data from a remote URL using the Fetch API, with support for custom HTTP methods, retries, timeouts, headers, and even external abort controllers. #### πŸ“₯ Parameters * `url` *(string)*: The full URL to fetch from (must start with `http://`, `https://`, `/`, `./`, or `../`). * `options` *(object)* *(optional)*: * `signal` *(`AbortSignal` | `null`)*: Custom abort signal. * `method` *(string)*: The HTTP method to use (e.g., `GET`, `POST`, `PUT`, `DELETE`, etc.). * `timeout` *(number)*: Request timeout in milliseconds. Default is `0` (no timeout). * `retries` *(number)*: Number of retry attempts if the request fails. Default is `0`. * `headers` *(object)*: Additional headers to include in the request. * `body` *(object)*: Request body. If the value is a plain object, it will be automatically stringified as JSON. * `onProgress` *((loaded: number, total: number) => void)*: Track the load progress. #### `trackFetchProgress(response, onProgress)` Intercepts a standard Fetch API Response to track the download progress of its body stream. * **Parameters**: * `response` *(Response)*: The original response object to be tracked. * `options` *(FetchOnProgressResult)*: The callback function to handle progress events (loaded and total numbers). * **Returns**: `Response` β€” A new Response object with the tracked stream. --- #### `fetchJson(url, options?)` Loads and parses a remote JSON file. * **Parameters**: * `url` *(string)*: URL to fetch the JSON from. * `options` *(object)* *(optional)*: Same structure as `fetchTemplate`. * **Returns**: `Promise<any[] | Record<string | number | symbol, unknown>>` β€” The parsed JSON data. * **Throws**: * `Error` if the fetch fails, times out, or returns invalid JSON. * `Error` if the `Content-Type` is not `application/json`. --- #### `fetchBlob(url, allowedMimeTypes?, options?)` Loads a remote file as a Blob object. * **Parameters**: * `url` *(string)*: URL of the remote file. * `allowedMimeTypes` *(string\[])* *(optional)*: List of accepted MIME types. * `options` *(object)* *(optional)*: Same structure as `fetchTemplate`. * **Returns**: `Promise<Blob>` * **Throws**: * `Error` if fetch fails or the MIME type is not allowed. * `Error` if the response is not OK. --- #### `fetchText(url, allowedMimeTypes?, options?)` Loads a remote file as **plain text** using the Fetch API. * **Parameters**: * `url` *(string)*: Full URL of the file to fetch. * `allowedMimeTypes` *(string\[])* *(optional)*: List of accepted MIME types (e.g., `['text/plain']`). * `options` *(object)* *(optional)*: Same structure as `fetchTemplate`. * **Returns**: `Promise<string>` β€” The content of the file as a text string. * **Throws**: * `Error` if the fetch fails or the response is not OK. * `Error` if the MIME type is not in the allowed list (when provided). --- #### πŸ“€ Returns (for all helpers) * `Promise<any>` β€” Depends on the function: * `fetchJson`: Parsed JSON * `fetchBlob`: File as a Blob * `fetchText`: File as plain text --- #### ⚠️ Throws All functions may throw the following: * `Error` if the request fails or the response times out. * `Error` if `Content-Type` does not match expected type (JSON, Blob, Text, etc). * `Error` if response is malformed or rejected by MIME type filter. --- #### 🧠 Tip Using a custom `signal` disables both `timeout` and `retries`. This is useful when you want to handle cancellation yourself, like in user interfaces or abortable workflows. #### πŸ§ͺ Example ```js const controller = new AbortController(); const data = await fetchJson('https://api.example.com/data', { method: 'POST', body: { name: 'Yasmin' }, headers: { 'Content-Type': 'application/json' }, timeout: 5000, retries: 2, signal: controller.signal, // optional }); ``` ```js const text = await fetchText('/example.txt', ['text/plain'], { timeout: 3000, }); ``` ```js const blob = await fetchBlob('/image.jpg', ['image/jpeg']); ``` --- ### πŸ“¦ `HtmlElBoxSides` Type ```ts type HtmlElBoxSides = { x: number; // Total horizontal size (left + right) y: number; // Total vertical size (top + bottom) left: number; right: number; top: number; bottom: number; } ``` A common return format used to describe the box model dimensions (borders, padding, margin) of an HTML element. --- ### πŸ“„ `installWindowHiddenScript` Automatically toggles CSS classes on a given element based on the browser window or tab **visibility** and **focus** state. Perfect for UI states like dimming, pausing animations, or showing "away" statuses. #### 🧠 Features * βœ… Adds or removes custom CSS classes depending on page visibility or focus * βœ… Supports modern and legacy browsers (including IE9) * βœ… Automatically dispatches an initial state check on load * βœ… Allows custom **callbacks** for visibility changes (`onVisible`, `onHidden`) * βœ… Returns a cleanup function to remove all listeners #### πŸ§ͺ Usage ```js import { installWindowHiddenScript } from 'tiny-essentials'; const uninstall = installWindowHiddenScript({ element: document.getElementById('app'), hiddenClass: 'is-hidden', visibleClass: 'is-visible', onVisible: () => console.log('Window is now visible'), onHidden: () => console.log('Window is now hidden'), }); // To remove all listeners later uninstall(); ``` #### βš™οΈ Options | Option | Type | Default | Description | | -------------- | ------------- | ----------------- | ----------------------------------------------------------------- | | `element` | `HTMLElement` | `document.body` | The element to which the visibility classes will be applied | | `hiddenClass` | `string` | `'windowHidden'` | Class name to apply when the window is **not visible or blurred** | | `visibleClass` | `string` | `'windowVisible'` | Class name to apply when the window is **visible or focused** | | `onVisible` | `() => void` | `undefined` | Optional callback fired when the window becomes visible | | `onHidden` | `() => void` | `undefined` | Optional callback fired when the window becomes hidden | #### πŸ”„ Return Value ```ts () => void ``` Returns a function that, when called, will: * 🧹 Remove all attached event listeners * ❌ Remove both visibility classes from the target element #### 🚦 Events Supported The script handles multiple events depending on browser support: * `visibilitychange`, `webkitvisibilitychange`, `mozvisibilitychange`, `msvisibilitychange` * `focus`, `blur`, `focusin`, `focusout` * `pageshow`, `pagehide` * IE fallback: `onfocusin`, `onfocusout` #### πŸ” Initial Trigger Immediately after installation, the script simulates a `focus` or `blur` event based on the current visibility state to **ensure the classes and callbacks are applied from the start**. #### 🧯 Uninstalling Don’t forget to call the returned function if you dynamically load/unload components or scripts: ```js const stopWatching = installWindowHiddenScript(...); stopWatching(); // later ``` #### 🎨 CSS Example ```css .windowVisible { opacity: 1; pointer-events: auto; transition: opacity 0.3s ease; } .windowHidden { opacity: 0.4; pointer-events: none; transition: opacity 0.3s ease; } ``` --- ### πŸ“– `loadImage(options): Promise<object>` A robust, asynchronous utility for loading images in the browser. It captures critical lifecycle events and provides a normalized result object, making it much easier to handle image loading states and performance metrics. #### ✨ Features * **Asynchronous:** Returns a clean `Promise`. * **Performance Tracking:** Automatically calculates the time taken to load the image. * **Memory Safe:** Includes a cleanup mechanism for event listeners. * **Normalized Output:** Returns consistent data structures for both success and edge cases. #### πŸ“₯ Parameters | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `url` | `string` | **Required** | The source URL of the image. | | `crossOrigin` | `string` | `'anonymous'` | The CORS policy for the request. | | `onLoading` | `function` | `undefined` | Callback fired when the browser starts the network request. | #### πŸ“€ Returns The promise resolves to an object containing: * **`element`**: `HTMLImageElement` - The actual image object. * **`isSuccess`**: `boolean` - True if the image loaded correctly. * **`event`**: `Event` - The raw event captured from the browser. * **`status`**: `string` - `'loaded'` or `'aborted'`. * **`loadTimeMs`**: `number` - Total duration of the request in milliseconds. * **`dimensions`**: `Object` - Contains `width`, `height`, `naturalWidth`, and `naturalHeight`. #### πŸ§ͺ Example ```javascript import { loadImage } from './html.mjs'; const handleLoading = (event, startTime) => { console.log('Started loading at:', startTime); }; const result = await loadImage({ url: 'https://example.com/image.png', onLoading: handleLoading, crossOrigin: 'anonymous' }); if (result.isSuccess) { console.log(`Image loaded in ${result.loadTimeMs.toFixed(2)}ms`); document.body.appendChild(result.element); } ``` > **Note:** The utility uses `performance.now()` for high-resolution timestamps, ensuring accurate performance monitoring of your assets.