tiny-essentials 1.25.3 → 1.25.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var TinyArrayComparator = require('../libs/TinyArrayComparator.cjs');
4
+
5
+
6
+
7
+ exports.TinyArrayComparator = TinyArrayComparator;
@@ -0,0 +1,3 @@
1
+ export { TinyArrayComparator };
2
+ import TinyArrayComparator from '../libs/TinyArrayComparator.mjs';
3
+ //# sourceMappingURL=TinyArrayComparator.d.mts.map
@@ -0,0 +1,2 @@
1
+ import TinyArrayComparator from '../libs/TinyArrayComparator.mjs';
2
+ export { TinyArrayComparator };
package/dist/v1/index.cjs CHANGED
@@ -49,6 +49,7 @@ var TinyLoadingScreen = require('./libs/TinyLoadingScreen.cjs');
49
49
  var TinyColorValidator = require('./libs/TinyColorValidator.cjs');
50
50
  var TinyAnalogClock = require('./libs/TinyAnalogClock.cjs');
51
51
  var TinyTextDiffer = require('./libs/TinyTextDiffer.cjs');
52
+ var TinyArrayComparator = require('./libs/TinyArrayComparator.cjs');
52
53
 
53
54
 
54
55
 
@@ -179,3 +180,4 @@ exports.TinyLoadingScreen = TinyLoadingScreen;
179
180
  exports.TinyColorValidator = TinyColorValidator;
180
181
  exports.TinyAnalogClock = TinyAnalogClock;
181
182
  exports.TinyTextDiffer = TinyTextDiffer;
183
+ exports.TinyArrayComparator = TinyArrayComparator;
@@ -1,3 +1,4 @@
1
+ import TinyArrayComparator from './libs/TinyArrayComparator.mjs';
1
2
  import TinyTextDiffer from './libs/TinyTextDiffer.mjs';
2
3
  import TinyAnalogClock from './libs/TinyAnalogClock.mjs';
3
4
  import TinyColorValidator from './libs/TinyColorValidator.mjs';
@@ -125,5 +126,5 @@ import { getTimeDuration } from './basics/clock.mjs';
125
126
  import { shuffleArray } from './basics/array.mjs';
126
127
  import { toTitleCase } from './basics/text.mjs';
127
128
  import { toTitleCaseLowerFirst } from './basics/text.mjs';
128
- export { TinyTextDiffer, TinyAnalogClock, TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
129
+ export { TinyArrayComparator, TinyTextDiffer, TinyAnalogClock, TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
129
130
  //# sourceMappingURL=index.d.mts.map
package/dist/v1/index.mjs CHANGED
@@ -47,7 +47,8 @@ import TinyLoadingScreen from './libs/TinyLoadingScreen.mjs';
47
47
  import TinyColorValidator from './libs/TinyColorValidator.mjs';
48
48
  import TinyAnalogClock from './libs/TinyAnalogClock.mjs';
49
49
  import TinyTextDiffer from './libs/TinyTextDiffer.mjs';
50
+ import TinyArrayComparator from './libs/TinyArrayComparator.mjs';
50
51
  // import TinyHtmlElems from './libs/TinyHtml/index.mjs';
51
- export { TinyTextDiffer, TinyAnalogClock,
52
+ export { TinyArrayComparator, TinyTextDiffer, TinyAnalogClock,
52
53
  // TinyHtmlElems,
53
54
  TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
@@ -0,0 +1,130 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Array comparison utility.
5
+ * @module TinyArrayComparator
6
+ */
7
+
8
+ /**
9
+ * @typedef {Object} InternalState
10
+ * Holds the internal tracking variables during the comparison process.
11
+ * @property {Map<string, any>} oldItemsMap - A map storing the hash as the key and the original item as the value.
12
+ * @property {AffectedItems} affectedItems - The final array that collects added or deleted items.
13
+ */
14
+
15
+ /**
16
+ * The final array that collects added or deleted items.
17
+ * @typedef {Array<{item: any, status: 'added'|'deleted'}>} AffectedItems
18
+ */
19
+
20
+ /**
21
+ * Compares two arrays efficiently by hashing their items to detect additions and deletions.
22
+ */
23
+ class TinyArrayComparator {
24
+ /**
25
+ * Generates a simple 32-bit integer hash converted to a base36 string.
26
+ * @param {any} item - The item to be hashed (can be an object, array, string, or number).
27
+ * @returns {string} The unique hash representing the item's value.
28
+ */
29
+ static generateHash(item) {
30
+ const stringified = typeof item === 'object' ? JSON.stringify(item) : String(item);
31
+ let hash = 0;
32
+
33
+ for (let i = 0, len = stringified.length; i < len; i++) {
34
+ const char = stringified.charCodeAt(i);
35
+ hash = (hash << 5) - hash + char;
36
+ hash |= 0; // Convert to 32bit integer
37
+ }
38
+
39
+ return hash.toString(36);
40
+ }
41
+
42
+ /**
43
+ * Internal storage for the base array.
44
+ * @type {any[]}
45
+ */
46
+ #oldArray = [];
47
+
48
+ /**
49
+ * Gets the current base array used for comparisons.
50
+ * @returns {any[]} The current initial state of the array.
51
+ */
52
+ get oldArray() {
53
+ return this.#oldArray;
54
+ }
55
+
56
+ /**
57
+ * Sets a new base array for future comparisons.
58
+ * @param {Array<any>} oldArray - The initial state of the array.
59
+ * @throws {TypeError} Throws an error if the provided value is not an array.
60
+ */
61
+ set oldArray(oldArray) {
62
+ if (!Array.isArray(oldArray))
63
+ throw new TypeError('The provided oldArray must be a valid Array.');
64
+ this.#oldArray = oldArray;
65
+ }
66
+
67
+ /**
68
+ * Initializes the comparator with an optional base array.
69
+ * @param {Array<any>} [oldArray] - The initial state of the array to be stored.
70
+ */
71
+ constructor(oldArray) {
72
+ if (typeof oldArray !== 'undefined') this.oldArray = oldArray;
73
+ }
74
+
75
+ /**
76
+ * Proxy to generates a hash converted to a string.
77
+ * @param {any} item - The item to be hashed (can be an object, array, string, or number).
78
+ * @returns {string} The unique hash representing the item's value.
79
+ * @private
80
+ */
81
+ _generateHash(item) {
82
+ return TinyArrayComparator.generateHash(item);
83
+ }
84
+
85
+ /**
86
+ * Compares the stored older array with a newer array and identifies missing or new items.
87
+ *
88
+ * @param {Array<any>} newArray - The modified state of the array.
89
+ * @returns {AffectedItems} An array containing the affected items and their status.
90
+ * @throws {TypeError} Throws an error if the provided value is not an array.
91
+ */
92
+ compare(newArray) {
93
+ if (!Array.isArray(newArray))
94
+ throw new TypeError('The provided newArray must be a valid Array.');
95
+
96
+ /** @type {InternalState} */
97
+ const state = {
98
+ oldItemsMap: new Map(),
99
+ affectedItems: [],
100
+ };
101
+
102
+ // Step 1: Hash and store all items from the first array
103
+ for (const item of this.#oldArray) {
104
+ const hashKey = this._generateHash(item);
105
+ state.oldItemsMap.set(hashKey, item);
106
+ }
107
+
108
+ // Step 2: Iterate through the second array to find matches or additions
109
+ for (const item of newArray) {
110
+ const hashKey = this._generateHash(item);
111
+
112
+ if (state.oldItemsMap.has(hashKey)) {
113
+ // Item exists in both, so it is unchanged. Remove from map.
114
+ state.oldItemsMap.delete(hashKey);
115
+ } else {
116
+ // Item was not in the old array, so it is an addition.
117
+ state.affectedItems.push({ item, status: 'added' });
118
+ }
119
+ }
120
+
121
+ // Step 3: Any item left in the oldItemsMap was not present in the new array (deleted)
122
+ for (const item of state.oldItemsMap.values()) {
123
+ state.affectedItems.push({ item, status: 'deleted' });
124
+ }
125
+
126
+ return state.affectedItems;
127
+ }
128
+ }
129
+
130
+ module.exports = TinyArrayComparator;
@@ -0,0 +1,79 @@
1
+ export default TinyArrayComparator;
2
+ /**
3
+ * Holds the internal tracking variables during the comparison process.
4
+ */
5
+ export type InternalState = {
6
+ /**
7
+ * - A map storing the hash as the key and the original item as the value.
8
+ */
9
+ oldItemsMap: Map<string, any>;
10
+ /**
11
+ * - The final array that collects added or deleted items.
12
+ */
13
+ affectedItems: AffectedItems;
14
+ };
15
+ /**
16
+ * The final array that collects added or deleted items.
17
+ */
18
+ export type AffectedItems = Array<{
19
+ item: any;
20
+ status: "added" | "deleted";
21
+ }>;
22
+ /**
23
+ * @fileoverview Array comparison utility.
24
+ * @module TinyArrayComparator
25
+ */
26
+ /**
27
+ * @typedef {Object} InternalState
28
+ * Holds the internal tracking variables during the comparison process.
29
+ * @property {Map<string, any>} oldItemsMap - A map storing the hash as the key and the original item as the value.
30
+ * @property {AffectedItems} affectedItems - The final array that collects added or deleted items.
31
+ */
32
+ /**
33
+ * The final array that collects added or deleted items.
34
+ * @typedef {Array<{item: any, status: 'added'|'deleted'}>} AffectedItems
35
+ */
36
+ /**
37
+ * Compares two arrays efficiently by hashing their items to detect additions and deletions.
38
+ */
39
+ declare class TinyArrayComparator {
40
+ /**
41
+ * Generates a simple 32-bit integer hash converted to a base36 string.
42
+ * @param {any} item - The item to be hashed (can be an object, array, string, or number).
43
+ * @returns {string} The unique hash representing the item's value.
44
+ */
45
+ static generateHash(item: any): string;
46
+ /**
47
+ * Initializes the comparator with an optional base array.
48
+ * @param {Array<any>} [oldArray] - The initial state of the array to be stored.
49
+ */
50
+ constructor(oldArray?: Array<any>);
51
+ /**
52
+ * Sets a new base array for future comparisons.
53
+ * @param {Array<any>} oldArray - The initial state of the array.
54
+ * @throws {TypeError} Throws an error if the provided value is not an array.
55
+ */
56
+ set oldArray(oldArray: Array<any>);
57
+ /**
58
+ * Gets the current base array used for comparisons.
59
+ * @returns {any[]} The current initial state of the array.
60
+ */
61
+ get oldArray(): any[];
62
+ /**
63
+ * Proxy to generates a hash converted to a string.
64
+ * @param {any} item - The item to be hashed (can be an object, array, string, or number).
65
+ * @returns {string} The unique hash representing the item's value.
66
+ * @private
67
+ */
68
+ private _generateHash;
69
+ /**
70
+ * Compares the stored older array with a newer array and identifies missing or new items.
71
+ *
72
+ * @param {Array<any>} newArray - The modified state of the array.
73
+ * @returns {AffectedItems} An array containing the affected items and their status.
74
+ * @throws {TypeError} Throws an error if the provided value is not an array.
75
+ */
76
+ compare(newArray: Array<any>): AffectedItems;
77
+ #private;
78
+ }
79
+ //# sourceMappingURL=TinyArrayComparator.d.mts.map
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @fileoverview Array comparison utility.
3
+ * @module TinyArrayComparator
4
+ */
5
+ /**
6
+ * @typedef {Object} InternalState
7
+ * Holds the internal tracking variables during the comparison process.
8
+ * @property {Map<string, any>} oldItemsMap - A map storing the hash as the key and the original item as the value.
9
+ * @property {AffectedItems} affectedItems - The final array that collects added or deleted items.
10
+ */
11
+ /**
12
+ * The final array that collects added or deleted items.
13
+ * @typedef {Array<{item: any, status: 'added'|'deleted'}>} AffectedItems
14
+ */
15
+ /**
16
+ * Compares two arrays efficiently by hashing their items to detect additions and deletions.
17
+ */
18
+ class TinyArrayComparator {
19
+ /**
20
+ * Generates a simple 32-bit integer hash converted to a base36 string.
21
+ * @param {any} item - The item to be hashed (can be an object, array, string, or number).
22
+ * @returns {string} The unique hash representing the item's value.
23
+ */
24
+ static generateHash(item) {
25
+ const stringified = typeof item === 'object' ? JSON.stringify(item) : String(item);
26
+ let hash = 0;
27
+ for (let i = 0, len = stringified.length; i < len; i++) {
28
+ const char = stringified.charCodeAt(i);
29
+ hash = (hash << 5) - hash + char;
30
+ hash |= 0; // Convert to 32bit integer
31
+ }
32
+ return hash.toString(36);
33
+ }
34
+ /**
35
+ * Internal storage for the base array.
36
+ * @type {any[]}
37
+ */
38
+ #oldArray = [];
39
+ /**
40
+ * Gets the current base array used for comparisons.
41
+ * @returns {any[]} The current initial state of the array.
42
+ */
43
+ get oldArray() {
44
+ return this.#oldArray;
45
+ }
46
+ /**
47
+ * Sets a new base array for future comparisons.
48
+ * @param {Array<any>} oldArray - The initial state of the array.
49
+ * @throws {TypeError} Throws an error if the provided value is not an array.
50
+ */
51
+ set oldArray(oldArray) {
52
+ if (!Array.isArray(oldArray))
53
+ throw new TypeError('The provided oldArray must be a valid Array.');
54
+ this.#oldArray = oldArray;
55
+ }
56
+ /**
57
+ * Initializes the comparator with an optional base array.
58
+ * @param {Array<any>} [oldArray] - The initial state of the array to be stored.
59
+ */
60
+ constructor(oldArray) {
61
+ if (typeof oldArray !== 'undefined')
62
+ this.oldArray = oldArray;
63
+ }
64
+ /**
65
+ * Proxy to generates a hash converted to a string.
66
+ * @param {any} item - The item to be hashed (can be an object, array, string, or number).
67
+ * @returns {string} The unique hash representing the item's value.
68
+ * @private
69
+ */
70
+ _generateHash(item) {
71
+ return TinyArrayComparator.generateHash(item);
72
+ }
73
+ /**
74
+ * Compares the stored older array with a newer array and identifies missing or new items.
75
+ *
76
+ * @param {Array<any>} newArray - The modified state of the array.
77
+ * @returns {AffectedItems} An array containing the affected items and their status.
78
+ * @throws {TypeError} Throws an error if the provided value is not an array.
79
+ */
80
+ compare(newArray) {
81
+ if (!Array.isArray(newArray))
82
+ throw new TypeError('The provided newArray must be a valid Array.');
83
+ /** @type {InternalState} */
84
+ const state = {
85
+ oldItemsMap: new Map(),
86
+ affectedItems: [],
87
+ };
88
+ // Step 1: Hash and store all items from the first array
89
+ for (const item of this.#oldArray) {
90
+ const hashKey = this._generateHash(item);
91
+ state.oldItemsMap.set(hashKey, item);
92
+ }
93
+ // Step 2: Iterate through the second array to find matches or additions
94
+ for (const item of newArray) {
95
+ const hashKey = this._generateHash(item);
96
+ if (state.oldItemsMap.has(hashKey)) {
97
+ // Item exists in both, so it is unchanged. Remove from map.
98
+ state.oldItemsMap.delete(hashKey);
99
+ }
100
+ else {
101
+ // Item was not in the old array, so it is an addition.
102
+ state.affectedItems.push({ item, status: 'added' });
103
+ }
104
+ }
105
+ // Step 3: Any item left in the oldItemsMap was not present in the new array (deleted)
106
+ for (const item of state.oldItemsMap.values()) {
107
+ state.affectedItems.push({ item, status: 'deleted' });
108
+ }
109
+ return state.affectedItems;
110
+ }
111
+ }
112
+ export default TinyArrayComparator;
package/docs/v1/README.md CHANGED
@@ -62,6 +62,7 @@ This folder contains the core scripts we have worked on so far. Each file is a m
62
62
  - 🎨 **[TinyColorValidator](./libs/TinyColorValidator.md)** — A comprehensive CSS color validation and parsing utility supporting HEX, HEXA, RGB, RGBA, HSL, HSLA, HWB, Lab, LCH, standard HTML color names, and special keywords, with automatic type detection and parsing.
63
63
  * 📝 **[TinyTextDiffer](./libs/TinyTextDiffer.md)** — A granular text comparison utility using the LCS algorithm to detect additions, deletions, and unchanged segments between multiple history versions, returning a clean, parseable diff structure.
64
64
  * 🕒 **[TinyAnalogClock](./libs/TinyAnalogClock.md)** — A lightweight analog clock engine for managing time-based rotations, supporting custom offsets, smooth transitions, and easy binding to CSS variables rendering.
65
+ * 🔍 **[TinyArrayComparator](./libs/TinyArrayComparator.md)** — A lightweight, highly optimized JavaScript utility class designed to compare two arrays and efficiently detect which items were **added** or **deleted**.
65
66
 
66
67
  ### 3. **`fileManager/`**
67
68
  * 📁 **[Main](./fileManager/main.md)** — A Node.js file/directory utility module with support for JSON, backups, renaming, size analysis, and more.
@@ -0,0 +1,101 @@
1
+ # 🔍 TinyArrayComparator
2
+
3
+ A lightweight, highly optimized JavaScript utility class designed to compare two arrays and efficiently detect which items were **added** or **deleted**.
4
+
5
+ ## ✨ Features
6
+
7
+ - **Fast Comparison:** Uses a Map and hash-based lookups for $O(N)$ performance.
8
+ - **Stateful Design:** Store your base array once and compare it multiple times.
9
+ - **Zero Dependencies:** Pure Vanilla JavaScript.
10
+ - **Deep Compatibility:** Safely hashes strings, numbers, arrays, and deep objects.
11
+ - **Clean Architecture:** Built as an ES6 Module with strict JSDoc typing and input validation.
12
+
13
+ ---
14
+
15
+ ## 🚀 Quick Start
16
+
17
+ ### 1. Import the Class
18
+ Since this project uses modern ES6 modules, simply import it into your working file.
19
+
20
+ ```javascript
21
+ import TinyArrayComparator from './TinyArrayComparator.js';
22
+ ```
23
+
24
+ ### 2. Prepare Your Arrays
25
+ Set up the initial state (`oldArray`) and the modified state (`newArray`) that you want to compare.
26
+
27
+ ```javascript
28
+ const oldList = [
29
+ { id: 1, role: 'admin' },
30
+ { id: 2, role: 'user' },
31
+ { id: 3, role: 'moderator' }
32
+ ];
33
+
34
+ const newList = [
35
+ { id: 1, role: 'admin' }, // Unchanged
36
+ { id: 3, role: 'moderator' }, // Unchanged
37
+ { id: 4, role: 'guest' } // Added
38
+ // User ID 2 was deleted
39
+ ];
40
+ ```
41
+
42
+ ### 3. Initialize and Compare
43
+ Instantiate the class passing the initial array. Then, call the `compare` method with your new array.
44
+
45
+ ```javascript
46
+ const comparator = new TinyArrayComparator(oldList);
47
+ const results = comparator.compare(newList);
48
+
49
+ console.log(results);
50
+ ```
51
+
52
+ **Output:**
53
+ ```json
54
+ [
55
+ {
56
+ "item": { "id": 4, "role": "guest" },
57
+ "status": "added"
58
+ },
59
+ {
60
+ "item": { "id": 2, "role": "user" },
61
+ "status": "deleted"
62
+ }
63
+ ]
64
+ ```
65
+
66
+ ---
67
+
68
+ ## 🛠️ API Reference
69
+
70
+ ### `constructor([oldArray])`
71
+ Creates a new comparator instance.
72
+ * **`oldArray`** `(Array<any>)` *(Optional)*: The initial state of the array to be stored. Throws a `TypeError` if the provided value is not an Array.
73
+
74
+ ### `compare(newArray)`
75
+ Evaluates differences between the internally stored `oldArray` and the provided `newArray`. Throws a `TypeError` if the provided value is not an Array.
76
+ * **`newArray`** `(Array<any>)`: The new array containing current modifications.
77
+ * **Returns:** An array of objects. Each object contains the original `item` and a `status` string (either `'added'` or `'deleted'`).
78
+
79
+ ### `get oldArray` / `set oldArray(value)`
80
+ Allows you to retrieve or update the base array stored inside the instance.
81
+ * **Throws:** `TypeError` if attempting to set a non-array value.
82
+
83
+ ### `static generateHash(item)`
84
+ A static helper method if you ever need to generate a unique base36 hash string for an item outside the comparison flow.
85
+ * **`item`** `(any)`: The target object, string, or number to hash.
86
+ * **Returns:** A `string` representing the unique hash.
87
+
88
+ ```javascript
89
+ const myHash = TinyArrayComparator.generateHash({ pony: 'Pudding' });
90
+ console.log(myHash); // Returns a base36 string like "1b4x9z"
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 💡 Best Practices
96
+
97
+ * **Order Doesn't Matter:** Because this utility relies on value-hashing, the index order of items inside the arrays does not affect the comparison. It strictly checks for the existence of the values.
98
+ * **Object References:** The returned array preserves the exact references to the items passed in the parameters, allowing you to seamlessly integrate the output back into your application logic.
99
+ * **Reusability:** You can easily update the base state by assigning a new array to `comparator.oldArray = [...]` without creating a new instance.
100
+
101
+ Happy coding! 💻✨
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-essentials",
3
- "version": "1.25.3",
3
+ "version": "1.25.4",
4
4
  "description": "Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.",
5
5
  "scripts": {
6
6
  "test": "npm run test:mjs && npm run test:cjs && npm run test:js",
@@ -220,6 +220,10 @@
220
220
  "require": "./dist/v1/libs/TinyTextDiffer.cjs",
221
221
  "import": "./dist/v1/libs/TinyTextDiffer.mjs"
222
222
  },
223
+ "./libs/TinyArrayComparator": {
224
+ "require": "./dist/v1/libs/TinyArrayComparator.cjs",
225
+ "import": "./dist/v1/libs/TinyArrayComparator.mjs"
226
+ },
223
227
  "./libs/TinyDragDropDetector": {
224
228
  "require": "./dist/v1/libs/TinyDragDropDetector.cjs",
225
229
  "import": "./dist/v1/libs/TinyDragDropDetector.mjs"