tiny-essentials 1.25.3 → 1.25.5

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 @@
1
+ (()=>{"use strict";var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{FuzzySet:()=>s,MamdaniInferenceSystem:()=>u,defuzzifyCentroid:()=>a,trapezoid:()=>n});const r=e=>{if(!Array.isArray(e))throw new TypeError("Parameter 'sets' must be an array.");if(!e.every(e=>e instanceof s))throw new TypeError("All elements in the array must be instances of FuzzySet.")},a=(e,t,a=.5)=>{i(e,"object","defuzzifyCentroid.fuzzyOutput");for(const t in e)i(e[t],"number",`fuzzyOutput['${t}']`);r(t),i(a,"number","defuzzifyCentroid.step");let n=0,s=0;for(let r=0;r<=100;r+=a){let a=0;t.forEach(t=>{const n=e[t.name]||0,i=Math.min(n,t.calculate(r));a=Math.max(a,i)}),n+=r*a,s+=a}return 0===s?0:n/s},n=(e,t,r,a,n)=>{if(e<=t||e>=n)return 0;if(e>=r&&e<=a)return 1;const i=t===r?1:(e-t)/(r-t),s=a===n?1:(n-e)/(n-a),u=Math.max(0,Math.min(i,1,s));return isNaN(u)?0:u},i=(e,t,r)=>{if(typeof e!==t)throw new TypeError(`Parameter '${r}' must be a ${t}.`)};class s{static trapezoid(e,t,r,a,i){return n(e,t,r,a,i)}#e="";#t=0;#r=0;#a=0;#n=0;get name(){return this.#e}set name(e){i(e,"string","FuzzySet.name"),this.#e=e}get a(){return this.#t}set a(e){i(e,"number","FuzzySet.a"),this.#t=e}get b(){return this.#r}set b(e){i(e,"number","FuzzySet.b"),this.#r=e}get c(){return this.#a}set c(e){i(e,"number","FuzzySet.c"),this.#a=e}get d(){return this.#n}set d(e){i(e,"number","FuzzySet.d"),this.#n=e}constructor(e,t,r,a,n){this.name=e,this.a=t,this.b=r,this.c=a,this.d=n}calculate(e){return i(e,"number","calculate.x"),s.trapezoid(e,this.#t,this.#r,this.#a,this.#n)}}class u{#i=new Map;addVariable(e,t){i(e,"string","addVariable.name"),r(t),this.#i.set(e,t)}removeVariable(e){return i(e,"string","removeVariable.name"),this.#i.delete(e)}getVariable(e){i(e,"string","getVariable.name");const t=this.#i.get(e);if(!t)throw new Error(`Linguistic variable '${e}' not found in the inference system.`);return[...t]}hasVariable(e){return i(e,"string","hasVariable.name"),this.#i.has(e)}fuzzify(e,t){i(e,"string","fuzzify.varName"),i(t,"number","fuzzify.value");const r=this.#i.get(e)||[],a={};return r.forEach(e=>{a[e.name]=e.calculate(t)}),a}}window.TinyMaInSys=t})();
@@ -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,8 @@ 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');
53
+ var TinyMamdaniInferenceSystem = require('./libs/TinyMamdaniInferenceSystem.cjs');
52
54
 
53
55
 
54
56
 
@@ -179,3 +181,8 @@ exports.TinyLoadingScreen = TinyLoadingScreen;
179
181
  exports.TinyColorValidator = TinyColorValidator;
180
182
  exports.TinyAnalogClock = TinyAnalogClock;
181
183
  exports.TinyTextDiffer = TinyTextDiffer;
184
+ exports.TinyArrayComparator = TinyArrayComparator;
185
+ exports.FuzzySet = TinyMamdaniInferenceSystem.FuzzySet;
186
+ exports.MamdaniInferenceSystem = TinyMamdaniInferenceSystem.MamdaniInferenceSystem;
187
+ exports.defuzzifyCentroid = TinyMamdaniInferenceSystem.defuzzifyCentroid;
188
+ exports.trapezoid = TinyMamdaniInferenceSystem.trapezoid;
@@ -1,3 +1,6 @@
1
+ import { FuzzySet } from './libs/TinyMamdaniInferenceSystem.mjs';
2
+ import { MamdaniInferenceSystem } from './libs/TinyMamdaniInferenceSystem.mjs';
3
+ import TinyArrayComparator from './libs/TinyArrayComparator.mjs';
1
4
  import TinyTextDiffer from './libs/TinyTextDiffer.mjs';
2
5
  import TinyAnalogClock from './libs/TinyAnalogClock.mjs';
3
6
  import TinyColorValidator from './libs/TinyColorValidator.mjs';
@@ -36,6 +39,8 @@ import TinyRateLimiter from './libs/TinyRateLimiter.mjs';
36
39
  import ColorSafeStringify from './libs/ColorSafeStringify.mjs';
37
40
  import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
38
41
  import TinyLevelUp from './libs/TinyLevelUp.mjs';
42
+ import { defuzzifyCentroid } from './libs/TinyMamdaniInferenceSystem.mjs';
43
+ import { trapezoid } from './libs/TinyMamdaniInferenceSystem.mjs';
39
44
  import { diffArrayList } from './basics/array.mjs';
40
45
  import { diffStrings } from './basics/text.mjs';
41
46
  import { breakdownDuration } from './basics/clock.mjs';
@@ -125,5 +130,5 @@ import { getTimeDuration } from './basics/clock.mjs';
125
130
  import { shuffleArray } from './basics/array.mjs';
126
131
  import { toTitleCase } from './basics/text.mjs';
127
132
  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 };
133
+ export { FuzzySet, MamdaniInferenceSystem, 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, defuzzifyCentroid, trapezoid, 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
134
  //# sourceMappingURL=index.d.mts.map
package/dist/v1/index.mjs CHANGED
@@ -47,7 +47,9 @@ 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';
51
+ import { FuzzySet, MamdaniInferenceSystem, trapezoid, defuzzifyCentroid, } from './libs/TinyMamdaniInferenceSystem.mjs';
50
52
  // import TinyHtmlElems from './libs/TinyHtml/index.mjs';
51
- export { TinyTextDiffer, TinyAnalogClock,
53
+ export { FuzzySet, MamdaniInferenceSystem, TinyArrayComparator, TinyTextDiffer, TinyAnalogClock,
52
54
  // TinyHtmlElems,
53
- 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, };
55
+ 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, defuzzifyCentroid, trapezoid, 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;