tiny-essentials 1.26.3 → 1.27.0
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.
- package/.github/workflows/node.js.yml +1 -1
- package/README.md +0 -1
- package/changelog/1/26/4.md +10 -0
- package/changelog/1/27/0.md +24 -0
- package/dist/v1/ColorSafeStringify.min.js +1 -1
- package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyAnalogClock.min.js +1 -1
- package/dist/v1/TinyArrayComparator.min.js +1 -1
- package/dist/v1/TinyArrayPaginator.min.js +1 -1
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyClassManager.min.js +1 -1
- package/dist/v1/TinyClipboard.min.js +1 -1
- package/dist/v1/TinyColorConverter.min.js +1 -1
- package/dist/v1/TinyColorValidator.min.js +1 -1
- package/dist/v1/TinyCookieConsent.min.js +1 -1
- package/dist/v1/TinyDayNightCycle.min.js +1 -1
- package/dist/v1/TinyDomReadyManager.min.js +1 -1
- package/dist/v1/TinyDragDropDetector.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyElementObserver.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyEvents.min.js +1 -1
- package/dist/v1/TinyGamepad.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyI18.min.js +1 -1
- package/dist/v1/TinyIframeEvents.min.js +1 -1
- package/dist/v1/TinyInventory.min.js +1 -1
- package/dist/v1/TinyInventoryTrader.min.js +1 -1
- package/dist/v1/TinyLevelUp.min.js +1 -1
- package/dist/v1/TinyLoadingScreen.min.js +1 -1
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyMaInSys.min.js +1 -1
- package/dist/v1/TinyMediaPlayer.min.js +1 -0
- package/dist/v1/TinyNeedBar.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.min.js +1 -1
- package/dist/v1/TinyNotifications.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyPromiseQueue.min.js +1 -1
- package/dist/v1/TinyRadioFm.min.js +1 -0
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinySimpleDice.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyTextDiffer.min.js +1 -1
- package/dist/v1/TinyTextRangeEditor.min.js +1 -1
- package/dist/v1/TinyTextarea.min.js +1 -1
- package/dist/v1/TinyTimeout.min.js +1 -1
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/index.cjs +5 -0
- package/dist/v1/basics/index.d.mts +5 -1
- package/dist/v1/basics/index.mjs +2 -1
- package/dist/v1/basics/mediaContent.cjs +644 -0
- package/dist/v1/basics/mediaContent.d.mts +296 -0
- package/dist/v1/basics/mediaContent.mjs +557 -0
- package/dist/v1/build/TinyMediaPlayer.cjs +7 -0
- package/dist/v1/build/TinyMediaPlayer.d.mts +3 -0
- package/dist/v1/build/TinyMediaPlayer.mjs +2 -0
- package/dist/v1/build/TinyRadioFm.cjs +7 -0
- package/dist/v1/build/TinyRadioFm.d.mts +3 -0
- package/dist/v1/build/TinyRadioFm.mjs +2 -0
- package/dist/v1/index.cjs +9 -0
- package/dist/v1/index.d.mts +7 -1
- package/dist/v1/index.mjs +5 -2
- package/dist/v1/libs/ColorSafeStringify.d.mts +1 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.cjs +16 -3
- package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +7 -3
- package/dist/v1/libs/TinyAfterScrollWatcher.mjs +13 -3
- package/dist/v1/libs/TinyArrayComparator.cjs +14 -11
- package/dist/v1/libs/TinyArrayComparator.d.mts +22 -19
- package/dist/v1/libs/TinyArrayComparator.mjs +14 -11
- package/dist/v1/libs/TinyArrayPaginator.cjs +23 -16
- package/dist/v1/libs/TinyArrayPaginator.d.mts +57 -30
- package/dist/v1/libs/TinyArrayPaginator.mjs +22 -16
- package/dist/v1/libs/TinyClassManager/TinyPluginInliner.cjs +265 -0
- package/dist/v1/libs/TinyClassManager/TinyPluginInliner.d.mts +92 -0
- package/dist/v1/libs/TinyClassManager/TinyPluginInliner.mjs +223 -0
- package/dist/v1/libs/TinyClassManager.cjs +124 -23
- package/dist/v1/libs/TinyClassManager.d.mts +33 -13
- package/dist/v1/libs/TinyClassManager.mjs +108 -23
- package/dist/v1/libs/TinyColorValidator.d.mts +16 -16
- package/dist/v1/libs/TinyDragDropDetector.cjs +9 -34
- package/dist/v1/libs/TinyDragDropDetector.d.mts +7 -21
- package/dist/v1/libs/TinyDragDropDetector.mjs +9 -24
- package/dist/v1/libs/TinyDragger.cjs +5 -5
- package/dist/v1/libs/TinyDragger.d.mts +4 -3
- package/dist/v1/libs/TinyDragger.mjs +5 -5
- package/dist/v1/libs/TinyElementObserver.cjs +6 -21
- package/dist/v1/libs/TinyElementObserver.d.mts +6 -15
- package/dist/v1/libs/TinyElementObserver.mjs +6 -20
- package/dist/v1/libs/TinyEvents.cjs +7 -0
- package/dist/v1/libs/TinyEvents.d.mts +4 -0
- package/dist/v1/libs/TinyEvents.mjs +6 -0
- package/dist/v1/libs/TinyGamepad.cjs +4 -6
- package/dist/v1/libs/TinyGamepad.d.mts +1 -1
- package/dist/v1/libs/TinyHtml/TinyHtmlIcon.d.mts +1 -1
- package/dist/v1/libs/TinyHtml/TinyHtmlTemplate.d.mts +1 -1
- package/dist/v1/libs/TinyHtml/TinyHtmlTextarea.d.mts +1 -1
- package/dist/v1/libs/TinyHtml/index.d.mts +1 -1
- package/dist/v1/libs/TinyHtml.cjs +72 -98
- package/dist/v1/libs/TinyHtml.d.mts +15 -32
- package/dist/v1/libs/TinyHtml.mjs +53 -77
- package/dist/v1/libs/TinyInventory.d.mts +1 -1
- package/dist/v1/libs/TinyMediaPlayer.cjs +844 -0
- package/dist/v1/libs/TinyMediaPlayer.d.mts +306 -0
- package/dist/v1/libs/TinyMediaPlayer.mjs +755 -0
- package/dist/v1/libs/TinyRadioFm.cjs +1378 -0
- package/dist/v1/libs/TinyRadioFm.d.mts +554 -0
- package/dist/v1/libs/TinyRadioFm.mjs +1137 -0
- package/dist/v1/libs/TinySmartScroller.cjs +39 -26
- package/dist/v1/libs/TinySmartScroller.d.mts +16 -62
- package/dist/v1/libs/TinySmartScroller.mjs +35 -26
- package/dist/v1/libs/UltraRandomMsgGen.d.mts +7 -7
- package/dist/v1/libs/examples/TinyClassManager.cjs +43 -41
- package/dist/v1/libs/examples/TinyClassManager.mjs +37 -37
- package/docs/v1/README.md +6 -0
- package/docs/v1/basics/mediaContent.md +131 -0
- package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +107 -0
- package/docs/v1/libs/TinyClassManager.md +69 -70
- package/docs/v1/libs/TinyDragDropDetector.md +5 -9
- package/docs/v1/libs/TinyElementObserver.md +3 -6
- package/docs/v1/libs/TinyEvents.md +1 -1
- package/docs/v1/libs/TinyHtml.md +0 -29
- package/docs/v1/libs/TinyMediaPlayer.md +100 -0
- package/docs/v1/libs/TinyRadioFm.md +141 -0
- package/docs/v1/libs/TinySmartScroller.md +3 -3
- package/package.json +40 -22
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/** @typedef {new (...args: any[]) => any} NewTinyClass */
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
|
-
* @template {
|
|
5
|
-
* @template {
|
|
6
|
+
* @template {NewTinyClass} TBase
|
|
7
|
+
* @template {NewTinyClass} TExtended
|
|
8
|
+
* @template {NewTinyClass[]} AppliedPluginClasses
|
|
6
9
|
* @typedef {Object} PluginDefinition
|
|
7
10
|
* @property {string} name - The unique identifier for the plugin.
|
|
8
11
|
* @property {string[]} [dependencies] - Array of plugin names required before applying this one.
|
|
9
|
-
* @property {function(TBase): TExtended} apply - Function that receives the base class and returns the extended class.
|
|
12
|
+
* @property {function(TBase, AppliedPluginClasses): TExtended} apply - Function that receives the base class and returns the extended class.
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* Manages the composition of a base class with multiple optional plugins (Mixins).
|
|
14
|
-
* @template {
|
|
17
|
+
* @template {NewTinyClass} T
|
|
18
|
+
* @template {T|NewTinyClass} oldT
|
|
15
19
|
*/
|
|
16
20
|
class TinyClassManager {
|
|
21
|
+
/** @typedef {[...oldT[], T]} AppliedPluginClasses */
|
|
22
|
+
|
|
17
23
|
/**
|
|
18
24
|
* @type {Set<string>}
|
|
19
25
|
* Tracks the names of successfully applied plugins to prevent duplication and check dependencies.
|
|
@@ -25,15 +31,33 @@ class TinyClassManager {
|
|
|
25
31
|
* @returns {string[]} Array of applied plugin names.
|
|
26
32
|
*/
|
|
27
33
|
get appliedPlugins() {
|
|
34
|
+
if (this.#used) throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
28
35
|
return [...this.#appliedPlugins];
|
|
29
36
|
}
|
|
30
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @type {AppliedPluginClasses}
|
|
40
|
+
* Tracks the classes of successfully applied plugins to prevent duplication and check dependencies.
|
|
41
|
+
*/
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
#appliedPluginClasses = [];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Gets the list of plugin classes currently applied to this instance.
|
|
47
|
+
* @returns {AppliedPluginClasses} Array of applied plugin classes.
|
|
48
|
+
*/
|
|
49
|
+
get appliedPluginClasses() {
|
|
50
|
+
if (this.#used) throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
51
|
+
return [...this.#appliedPluginClasses];
|
|
52
|
+
}
|
|
53
|
+
|
|
31
54
|
/**
|
|
32
55
|
* Gets the total size of the current class chain hierarchy.
|
|
33
56
|
* @returns {number} The count of applied plugins plus the core base.
|
|
34
57
|
*/
|
|
35
58
|
get size() {
|
|
36
|
-
|
|
59
|
+
if (this.#used) throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
60
|
+
return this.#appliedPluginClasses.length;
|
|
37
61
|
}
|
|
38
62
|
|
|
39
63
|
/**
|
|
@@ -46,6 +70,7 @@ class TinyClassManager {
|
|
|
46
70
|
* Holds the current state of the class chain.
|
|
47
71
|
*/
|
|
48
72
|
get currentClass() {
|
|
73
|
+
if (this.#used) throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
49
74
|
return this.#currentClass;
|
|
50
75
|
}
|
|
51
76
|
|
|
@@ -64,46 +89,120 @@ class TinyClassManager {
|
|
|
64
89
|
/**
|
|
65
90
|
* Initializes the manager with a core class.
|
|
66
91
|
* @param {T} coreClass - The foundational class to be extended.
|
|
92
|
+
* @param {oldT[]} [oldClasses=[]]
|
|
67
93
|
*/
|
|
68
|
-
constructor(
|
|
94
|
+
constructor(
|
|
95
|
+
coreClass,
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
oldClasses = [],
|
|
98
|
+
) {
|
|
69
99
|
this.#currentClass = coreClass;
|
|
100
|
+
this.#appliedPluginClasses = [...oldClasses, coreClass];
|
|
70
101
|
}
|
|
71
102
|
|
|
72
103
|
/**
|
|
73
|
-
*
|
|
74
|
-
* @template {
|
|
75
|
-
* @param {
|
|
76
|
-
* @
|
|
77
|
-
* @
|
|
104
|
+
* Internal helper to validate dependencies, check conflicts, and transition state.
|
|
105
|
+
* @template {NewTinyClass} R
|
|
106
|
+
* @param {string} name - The plugin name.
|
|
107
|
+
* @param {string[]} deps - The plugin dependencies.
|
|
108
|
+
* @param {R} ExtendedClass - The newly extended class returned by the apply function.
|
|
109
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance.
|
|
78
110
|
*/
|
|
79
|
-
|
|
111
|
+
#validateAndTransition(name, deps, ExtendedClass) {
|
|
112
|
+
// Verifies if the current manager has already been consumed to prevent branching.
|
|
80
113
|
if (this.#used) throw new Error(`[TinyClassManager] Cannot reuse a consumed manager instance.`);
|
|
81
|
-
if (this.#appliedPlugins.has(plugin.name))
|
|
82
|
-
throw new Error(`[TinyClassManager] Plugin conflict: "${plugin.name}" is already installed.`);
|
|
83
114
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
*/
|
|
88
|
-
const deps = plugin.dependencies || [];
|
|
115
|
+
// Checks if the plugin being inserted is already in the applied list.
|
|
116
|
+
if (this.#appliedPlugins.has(name))
|
|
117
|
+
throw new Error(`[TinyClassManager] Plugin conflict: "${name}" is already installed.`);
|
|
89
118
|
|
|
90
119
|
for (const dep of deps) {
|
|
91
120
|
if (!this.#appliedPlugins.has(dep)) {
|
|
92
121
|
throw new Error(
|
|
93
|
-
`[TinyClassManager] Missing Dependency: "${
|
|
122
|
+
`[TinyClassManager] Missing Dependency: "${name}" requires "${dep}" to be installed first.`,
|
|
94
123
|
);
|
|
95
124
|
}
|
|
96
125
|
}
|
|
97
126
|
|
|
98
|
-
const newClassManager = new TinyClassManager(
|
|
99
|
-
this.#appliedPlugins.forEach((
|
|
100
|
-
newClassManager.#appliedPlugins.add(
|
|
127
|
+
const newClassManager = new TinyClassManager(ExtendedClass, this.#appliedPluginClasses);
|
|
128
|
+
this.#appliedPlugins.forEach((appliedName) => newClassManager.#appliedPlugins.add(appliedName));
|
|
129
|
+
newClassManager.#appliedPlugins.add(name);
|
|
101
130
|
|
|
102
131
|
this.#used = true;
|
|
103
132
|
this.#appliedPlugins.clear();
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
this.#appliedPluginClasses = [];
|
|
135
|
+
|
|
104
136
|
return newClassManager;
|
|
105
137
|
}
|
|
106
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Applies a plugin to the class chain using a definition object.
|
|
141
|
+
* @deprecated Use {@link insert} instead.
|
|
142
|
+
* @template {NewTinyClass} R
|
|
143
|
+
* @param {PluginDefinition<T, R, AppliedPluginClasses>} plugin - The plugin module to be integrated.
|
|
144
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance holding the extended class chain.
|
|
145
|
+
* @throws {Error} Throws if instance is already consumed, plugin is duplicate, or dependencies are missing.
|
|
146
|
+
*/
|
|
147
|
+
use(plugin) {
|
|
148
|
+
/**
|
|
149
|
+
* @type {string[]}
|
|
150
|
+
* Extracted dependencies array with fallback for undefined properties.
|
|
151
|
+
*/
|
|
152
|
+
const deps = plugin.dependencies || [];
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @type {R}
|
|
156
|
+
* The new class generated by the old object-style apply wrapper.
|
|
157
|
+
*/
|
|
158
|
+
const ExtendedClass = plugin.apply(this.#currentClass, this.appliedPluginClasses);
|
|
159
|
+
|
|
160
|
+
return this.#validateAndTransition(plugin.name, deps, ExtendedClass);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Inserts a plugin directly by passing its apply function.
|
|
165
|
+
* It reads `_tinyDepName` and `_tinyDeps` statically from the returned class.
|
|
166
|
+
* @template {NewTinyClass} R
|
|
167
|
+
* @param {function(T, AppliedPluginClasses): R} applyFn - Function that receives the base class and returns the extended class.
|
|
168
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance holding the extended class chain.
|
|
169
|
+
* @throws {Error} Throws if static properties are missing, instance is consumed, or validation fails.
|
|
170
|
+
*/
|
|
171
|
+
insert(applyFn) {
|
|
172
|
+
/** * @type {R}
|
|
173
|
+
* The extended class returned directly from the provided function.
|
|
174
|
+
*/
|
|
175
|
+
const ExtendedClass = applyFn(this.#currentClass, this.appliedPluginClasses);
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @type {string}
|
|
179
|
+
* The plugin name extracted from the static property.
|
|
180
|
+
*/
|
|
181
|
+
// @ts-ignore
|
|
182
|
+
const pluginName = ExtendedClass._tinyDepName;
|
|
183
|
+
|
|
184
|
+
if (!pluginName) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
`[TinyClassManager] Plugin class must define a static '_tinyDepName' property.`,
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @type {string[]}
|
|
192
|
+
* The dependencies extracted from the static property, defaulting to an empty array.
|
|
193
|
+
*/
|
|
194
|
+
// @ts-ignore
|
|
195
|
+
const deps = ExtendedClass._tinyDeps ?? [];
|
|
196
|
+
|
|
197
|
+
if (!Array.isArray(deps) || !deps.every((name) => typeof name === 'string')) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`[TinyClassManager] Plugin class must define a static array of strings in '_tinyDepName' property.`,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return this.#validateAndTransition(pluginName, deps, ExtendedClass);
|
|
204
|
+
}
|
|
205
|
+
|
|
107
206
|
/**
|
|
108
207
|
* Finalizes the composition and returns the fully built class.
|
|
109
208
|
* @returns {T} The final class representing the last extended version in the chain.
|
|
@@ -114,6 +213,8 @@ class TinyClassManager {
|
|
|
114
213
|
throw new Error(`[TinyClassManager] Cannot build from an already finalized manager.`);
|
|
115
214
|
this.#used = true;
|
|
116
215
|
this.#appliedPlugins.clear();
|
|
216
|
+
// @ts-ignore
|
|
217
|
+
this.#appliedPluginClasses = [];
|
|
117
218
|
return this.#currentClass;
|
|
118
219
|
}
|
|
119
220
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export default TinyClassManager;
|
|
2
|
-
export type
|
|
2
|
+
export type NewTinyClass = new (...args: any[]) => any;
|
|
3
|
+
export type PluginDefinition<TBase extends NewTinyClass, TExtended extends NewTinyClass, AppliedPluginClasses extends NewTinyClass[]> = {
|
|
3
4
|
/**
|
|
4
5
|
* - The unique identifier for the plugin.
|
|
5
6
|
*/
|
|
@@ -11,31 +12,40 @@ export type PluginDefinition<TBase extends new (...args: any[]) => any, TExtende
|
|
|
11
12
|
/**
|
|
12
13
|
* - Function that receives the base class and returns the extended class.
|
|
13
14
|
*/
|
|
14
|
-
apply: (arg0: TBase) => TExtended;
|
|
15
|
+
apply: (arg0: TBase, arg1: AppliedPluginClasses) => TExtended;
|
|
15
16
|
};
|
|
17
|
+
/** @typedef {new (...args: any[]) => any} NewTinyClass */
|
|
16
18
|
/**
|
|
17
|
-
* @template {
|
|
18
|
-
* @template {
|
|
19
|
+
* @template {NewTinyClass} TBase
|
|
20
|
+
* @template {NewTinyClass} TExtended
|
|
21
|
+
* @template {NewTinyClass[]} AppliedPluginClasses
|
|
19
22
|
* @typedef {Object} PluginDefinition
|
|
20
23
|
* @property {string} name - The unique identifier for the plugin.
|
|
21
24
|
* @property {string[]} [dependencies] - Array of plugin names required before applying this one.
|
|
22
|
-
* @property {function(TBase): TExtended} apply - Function that receives the base class and returns the extended class.
|
|
25
|
+
* @property {function(TBase, AppliedPluginClasses): TExtended} apply - Function that receives the base class and returns the extended class.
|
|
23
26
|
*/
|
|
24
27
|
/**
|
|
25
28
|
* Manages the composition of a base class with multiple optional plugins (Mixins).
|
|
26
|
-
* @template {
|
|
29
|
+
* @template {NewTinyClass} T
|
|
30
|
+
* @template {T|NewTinyClass} oldT
|
|
27
31
|
*/
|
|
28
|
-
declare class TinyClassManager<T extends
|
|
32
|
+
declare class TinyClassManager<T extends NewTinyClass, oldT extends T | NewTinyClass> {
|
|
29
33
|
/**
|
|
30
34
|
* Initializes the manager with a core class.
|
|
31
35
|
* @param {T} coreClass - The foundational class to be extended.
|
|
36
|
+
* @param {oldT[]} [oldClasses=[]]
|
|
32
37
|
*/
|
|
33
|
-
constructor(coreClass: T);
|
|
38
|
+
constructor(coreClass: T, oldClasses?: oldT[]);
|
|
34
39
|
/**
|
|
35
40
|
* Gets the list of plugins currently applied to this instance.
|
|
36
41
|
* @returns {string[]} Array of applied plugin names.
|
|
37
42
|
*/
|
|
38
43
|
get appliedPlugins(): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Gets the list of plugin classes currently applied to this instance.
|
|
46
|
+
* @returns {AppliedPluginClasses} Array of applied plugin classes.
|
|
47
|
+
*/
|
|
48
|
+
get appliedPluginClasses(): [...oldT[], T];
|
|
39
49
|
/**
|
|
40
50
|
* Gets the total size of the current class chain hierarchy.
|
|
41
51
|
* @returns {number} The count of applied plugins plus the core base.
|
|
@@ -50,13 +60,23 @@ declare class TinyClassManager<T extends new (...args: any[]) => any> {
|
|
|
50
60
|
*/
|
|
51
61
|
get used(): boolean;
|
|
52
62
|
/**
|
|
53
|
-
* Applies a plugin to the class chain
|
|
54
|
-
* @
|
|
55
|
-
* @
|
|
56
|
-
* @
|
|
63
|
+
* Applies a plugin to the class chain using a definition object.
|
|
64
|
+
* @deprecated Use {@link insert} instead.
|
|
65
|
+
* @template {NewTinyClass} R
|
|
66
|
+
* @param {PluginDefinition<T, R, AppliedPluginClasses>} plugin - The plugin module to be integrated.
|
|
67
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance holding the extended class chain.
|
|
57
68
|
* @throws {Error} Throws if instance is already consumed, plugin is duplicate, or dependencies are missing.
|
|
58
69
|
*/
|
|
59
|
-
use<R extends
|
|
70
|
+
use<R extends NewTinyClass>(plugin: PluginDefinition<T, R, [...oldT[], T]>): TinyClassManager<R, T | oldT>;
|
|
71
|
+
/**
|
|
72
|
+
* Inserts a plugin directly by passing its apply function.
|
|
73
|
+
* It reads `_tinyDepName` and `_tinyDeps` statically from the returned class.
|
|
74
|
+
* @template {NewTinyClass} R
|
|
75
|
+
* @param {function(T, AppliedPluginClasses): R} applyFn - Function that receives the base class and returns the extended class.
|
|
76
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance holding the extended class chain.
|
|
77
|
+
* @throws {Error} Throws if static properties are missing, instance is consumed, or validation fails.
|
|
78
|
+
*/
|
|
79
|
+
insert<R extends NewTinyClass>(applyFn: (arg0: T, arg1: [...oldT[], T]) => R): TinyClassManager<R, T | oldT>;
|
|
60
80
|
/**
|
|
61
81
|
* Finalizes the composition and returns the fully built class.
|
|
62
82
|
* @returns {T} The final class representing the last extended version in the chain.
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
/** @typedef {new (...args: any[]) => any} NewTinyClass */
|
|
1
2
|
/**
|
|
2
|
-
* @template {
|
|
3
|
-
* @template {
|
|
3
|
+
* @template {NewTinyClass} TBase
|
|
4
|
+
* @template {NewTinyClass} TExtended
|
|
5
|
+
* @template {NewTinyClass[]} AppliedPluginClasses
|
|
4
6
|
* @typedef {Object} PluginDefinition
|
|
5
7
|
* @property {string} name - The unique identifier for the plugin.
|
|
6
8
|
* @property {string[]} [dependencies] - Array of plugin names required before applying this one.
|
|
7
|
-
* @property {function(TBase): TExtended} apply - Function that receives the base class and returns the extended class.
|
|
9
|
+
* @property {function(TBase, AppliedPluginClasses): TExtended} apply - Function that receives the base class and returns the extended class.
|
|
8
10
|
*/
|
|
9
11
|
/**
|
|
10
12
|
* Manages the composition of a base class with multiple optional plugins (Mixins).
|
|
11
|
-
* @template {
|
|
13
|
+
* @template {NewTinyClass} T
|
|
14
|
+
* @template {T|NewTinyClass} oldT
|
|
12
15
|
*/
|
|
13
16
|
class TinyClassManager {
|
|
17
|
+
/** @typedef {[...oldT[], T]} AppliedPluginClasses */
|
|
14
18
|
/**
|
|
15
19
|
* @type {Set<string>}
|
|
16
20
|
* Tracks the names of successfully applied plugins to prevent duplication and check dependencies.
|
|
@@ -21,14 +25,33 @@ class TinyClassManager {
|
|
|
21
25
|
* @returns {string[]} Array of applied plugin names.
|
|
22
26
|
*/
|
|
23
27
|
get appliedPlugins() {
|
|
28
|
+
if (this.#used)
|
|
29
|
+
throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
24
30
|
return [...this.#appliedPlugins];
|
|
25
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* @type {AppliedPluginClasses}
|
|
34
|
+
* Tracks the classes of successfully applied plugins to prevent duplication and check dependencies.
|
|
35
|
+
*/
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
#appliedPluginClasses = [];
|
|
38
|
+
/**
|
|
39
|
+
* Gets the list of plugin classes currently applied to this instance.
|
|
40
|
+
* @returns {AppliedPluginClasses} Array of applied plugin classes.
|
|
41
|
+
*/
|
|
42
|
+
get appliedPluginClasses() {
|
|
43
|
+
if (this.#used)
|
|
44
|
+
throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
45
|
+
return [...this.#appliedPluginClasses];
|
|
46
|
+
}
|
|
26
47
|
/**
|
|
27
48
|
* Gets the total size of the current class chain hierarchy.
|
|
28
49
|
* @returns {number} The count of applied plugins plus the core base.
|
|
29
50
|
*/
|
|
30
51
|
get size() {
|
|
31
|
-
|
|
52
|
+
if (this.#used)
|
|
53
|
+
throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
54
|
+
return this.#appliedPluginClasses.length;
|
|
32
55
|
}
|
|
33
56
|
/**
|
|
34
57
|
* @type {T}
|
|
@@ -39,6 +62,8 @@ class TinyClassManager {
|
|
|
39
62
|
* Holds the current state of the class chain.
|
|
40
63
|
*/
|
|
41
64
|
get currentClass() {
|
|
65
|
+
if (this.#used)
|
|
66
|
+
throw new Error(`[TinyClassManager] Cannot get a consumed manager instance.`);
|
|
42
67
|
return this.#currentClass;
|
|
43
68
|
}
|
|
44
69
|
/**
|
|
@@ -54,39 +79,97 @@ class TinyClassManager {
|
|
|
54
79
|
/**
|
|
55
80
|
* Initializes the manager with a core class.
|
|
56
81
|
* @param {T} coreClass - The foundational class to be extended.
|
|
82
|
+
* @param {oldT[]} [oldClasses=[]]
|
|
57
83
|
*/
|
|
58
|
-
constructor(coreClass
|
|
84
|
+
constructor(coreClass,
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
oldClasses = []) {
|
|
59
87
|
this.#currentClass = coreClass;
|
|
88
|
+
this.#appliedPluginClasses = [...oldClasses, coreClass];
|
|
60
89
|
}
|
|
61
90
|
/**
|
|
62
|
-
*
|
|
63
|
-
* @template {
|
|
64
|
-
* @param {
|
|
65
|
-
* @
|
|
66
|
-
* @
|
|
91
|
+
* Internal helper to validate dependencies, check conflicts, and transition state.
|
|
92
|
+
* @template {NewTinyClass} R
|
|
93
|
+
* @param {string} name - The plugin name.
|
|
94
|
+
* @param {string[]} deps - The plugin dependencies.
|
|
95
|
+
* @param {R} ExtendedClass - The newly extended class returned by the apply function.
|
|
96
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance.
|
|
67
97
|
*/
|
|
68
|
-
|
|
98
|
+
#validateAndTransition(name, deps, ExtendedClass) {
|
|
99
|
+
// Verifies if the current manager has already been consumed to prevent branching.
|
|
69
100
|
if (this.#used)
|
|
70
101
|
throw new Error(`[TinyClassManager] Cannot reuse a consumed manager instance.`);
|
|
71
|
-
if
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
* @type {string[]}
|
|
75
|
-
* Extracted dependencies array with fallback for undefined properties.
|
|
76
|
-
*/
|
|
77
|
-
const deps = plugin.dependencies || [];
|
|
102
|
+
// Checks if the plugin being inserted is already in the applied list.
|
|
103
|
+
if (this.#appliedPlugins.has(name))
|
|
104
|
+
throw new Error(`[TinyClassManager] Plugin conflict: "${name}" is already installed.`);
|
|
78
105
|
for (const dep of deps) {
|
|
79
106
|
if (!this.#appliedPlugins.has(dep)) {
|
|
80
|
-
throw new Error(`[TinyClassManager] Missing Dependency: "${
|
|
107
|
+
throw new Error(`[TinyClassManager] Missing Dependency: "${name}" requires "${dep}" to be installed first.`);
|
|
81
108
|
}
|
|
82
109
|
}
|
|
83
|
-
const newClassManager = new TinyClassManager(
|
|
84
|
-
this.#appliedPlugins.forEach((
|
|
85
|
-
newClassManager.#appliedPlugins.add(
|
|
110
|
+
const newClassManager = new TinyClassManager(ExtendedClass, this.#appliedPluginClasses);
|
|
111
|
+
this.#appliedPlugins.forEach((appliedName) => newClassManager.#appliedPlugins.add(appliedName));
|
|
112
|
+
newClassManager.#appliedPlugins.add(name);
|
|
86
113
|
this.#used = true;
|
|
87
114
|
this.#appliedPlugins.clear();
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
this.#appliedPluginClasses = [];
|
|
88
117
|
return newClassManager;
|
|
89
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Applies a plugin to the class chain using a definition object.
|
|
121
|
+
* @deprecated Use {@link insert} instead.
|
|
122
|
+
* @template {NewTinyClass} R
|
|
123
|
+
* @param {PluginDefinition<T, R, AppliedPluginClasses>} plugin - The plugin module to be integrated.
|
|
124
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance holding the extended class chain.
|
|
125
|
+
* @throws {Error} Throws if instance is already consumed, plugin is duplicate, or dependencies are missing.
|
|
126
|
+
*/
|
|
127
|
+
use(plugin) {
|
|
128
|
+
/**
|
|
129
|
+
* @type {string[]}
|
|
130
|
+
* Extracted dependencies array with fallback for undefined properties.
|
|
131
|
+
*/
|
|
132
|
+
const deps = plugin.dependencies || [];
|
|
133
|
+
/**
|
|
134
|
+
* @type {R}
|
|
135
|
+
* The new class generated by the old object-style apply wrapper.
|
|
136
|
+
*/
|
|
137
|
+
const ExtendedClass = plugin.apply(this.#currentClass, this.appliedPluginClasses);
|
|
138
|
+
return this.#validateAndTransition(plugin.name, deps, ExtendedClass);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Inserts a plugin directly by passing its apply function.
|
|
142
|
+
* It reads `_tinyDepName` and `_tinyDeps` statically from the returned class.
|
|
143
|
+
* @template {NewTinyClass} R
|
|
144
|
+
* @param {function(T, AppliedPluginClasses): R} applyFn - Function that receives the base class and returns the extended class.
|
|
145
|
+
* @returns {TinyClassManager<R, T | oldT>} A new manager instance holding the extended class chain.
|
|
146
|
+
* @throws {Error} Throws if static properties are missing, instance is consumed, or validation fails.
|
|
147
|
+
*/
|
|
148
|
+
insert(applyFn) {
|
|
149
|
+
/** * @type {R}
|
|
150
|
+
* The extended class returned directly from the provided function.
|
|
151
|
+
*/
|
|
152
|
+
const ExtendedClass = applyFn(this.#currentClass, this.appliedPluginClasses);
|
|
153
|
+
/**
|
|
154
|
+
* @type {string}
|
|
155
|
+
* The plugin name extracted from the static property.
|
|
156
|
+
*/
|
|
157
|
+
// @ts-ignore
|
|
158
|
+
const pluginName = ExtendedClass._tinyDepName;
|
|
159
|
+
if (!pluginName) {
|
|
160
|
+
throw new Error(`[TinyClassManager] Plugin class must define a static '_tinyDepName' property.`);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* @type {string[]}
|
|
164
|
+
* The dependencies extracted from the static property, defaulting to an empty array.
|
|
165
|
+
*/
|
|
166
|
+
// @ts-ignore
|
|
167
|
+
const deps = ExtendedClass._tinyDeps ?? [];
|
|
168
|
+
if (!Array.isArray(deps) || !deps.every((name) => typeof name === 'string')) {
|
|
169
|
+
throw new Error(`[TinyClassManager] Plugin class must define a static array of strings in '_tinyDepName' property.`);
|
|
170
|
+
}
|
|
171
|
+
return this.#validateAndTransition(pluginName, deps, ExtendedClass);
|
|
172
|
+
}
|
|
90
173
|
/**
|
|
91
174
|
* Finalizes the composition and returns the fully built class.
|
|
92
175
|
* @returns {T} The final class representing the last extended version in the chain.
|
|
@@ -97,6 +180,8 @@ class TinyClassManager {
|
|
|
97
180
|
throw new Error(`[TinyClassManager] Cannot build from an already finalized manager.`);
|
|
98
181
|
this.#used = true;
|
|
99
182
|
this.#appliedPlugins.clear();
|
|
183
|
+
// @ts-ignore
|
|
184
|
+
this.#appliedPluginClasses = [];
|
|
100
185
|
return this.#currentClass;
|
|
101
186
|
}
|
|
102
187
|
}
|
|
@@ -80,22 +80,22 @@ export type ColorTypes = "hex" | "hexa" | "rgb" | "rgba" | "hsl" | "hsla" | "hwb
|
|
|
80
80
|
* @template {string} TinyColorValidatorT
|
|
81
81
|
*/
|
|
82
82
|
declare class TinyColorValidator<TinyColorValidatorT extends string> {
|
|
83
|
-
static
|
|
84
|
-
static
|
|
85
|
-
static
|
|
86
|
-
static
|
|
87
|
-
static
|
|
88
|
-
static
|
|
89
|
-
static
|
|
90
|
-
static
|
|
91
|
-
static
|
|
92
|
-
static
|
|
93
|
-
static
|
|
94
|
-
static
|
|
95
|
-
static
|
|
96
|
-
static
|
|
97
|
-
static
|
|
98
|
-
static
|
|
83
|
+
static #HEX_REGEX: RegExp;
|
|
84
|
+
static #HEXA_REGEX: RegExp;
|
|
85
|
+
static #ALPHA: string;
|
|
86
|
+
static #NUM_0_255: string;
|
|
87
|
+
static #NUM_0_360: string;
|
|
88
|
+
static #NUM_0_100: string;
|
|
89
|
+
static #RGB_REGEX: RegExp;
|
|
90
|
+
static #RGBA_REGEX: RegExp;
|
|
91
|
+
static #HSL_REGEX: RegExp;
|
|
92
|
+
static #HSLA_REGEX: RegExp;
|
|
93
|
+
static #HWB_REGEX: RegExp;
|
|
94
|
+
static #LAB_AB: string;
|
|
95
|
+
static #LAB_REGEX: RegExp;
|
|
96
|
+
static #LCH_REGEX: RegExp;
|
|
97
|
+
static #HTML_COLOR_NAMES: Set<string>;
|
|
98
|
+
static #SPECIAL_COLOR_NAMES: Set<string>;
|
|
99
99
|
/**
|
|
100
100
|
* Returns all HTML color names as an array.
|
|
101
101
|
* @returns {string[]}
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {Object} DragAndDropOptions
|
|
5
|
-
* @property {HTMLElement} [target=document.body] - The DOM element where drag listeners will be attached. Defaults to `document.body` if `fullscreen` is true or no target is provided.
|
|
6
|
-
* @property {boolean} [fullscreen=true] - If true, listeners are attached to the entire page (`document.body`). If false, the `target` must be specified.
|
|
7
5
|
* @property {string} [hoverClass="dnd-hover"] - CSS class applied to the target element while files are being dragged over it.
|
|
8
6
|
* @property {(files: FileList, event: DragEvent) => void} [onDrop] - Callback function executed when files are dropped onto the target.
|
|
9
7
|
* @property {(event: DragEvent) => void} [onEnter] - Optional callback triggered when dragging enters the target area.
|
|
@@ -17,14 +15,12 @@
|
|
|
17
15
|
* It handles the drag lifecycle (enter, over, leave, drop) and provides hooks for developers to handle file uploads or UI changes.
|
|
18
16
|
*
|
|
19
17
|
* @class
|
|
18
|
+
* @template {HTMLElement} HTMLTarget
|
|
20
19
|
*/
|
|
21
20
|
class TinyDragDropDetector {
|
|
22
|
-
/** @type {
|
|
21
|
+
/** @type {HTMLTarget} */
|
|
23
22
|
#target;
|
|
24
23
|
|
|
25
|
-
/** @type {boolean} */
|
|
26
|
-
#fullscreen;
|
|
27
|
-
|
|
28
24
|
/** @type {string} */
|
|
29
25
|
#hoverClass;
|
|
30
26
|
|
|
@@ -46,31 +42,19 @@ class TinyDragDropDetector {
|
|
|
46
42
|
/**
|
|
47
43
|
* Creates a new instance of TinyDragDropDetector to handle drag-and-drop file detection.
|
|
48
44
|
*
|
|
49
|
-
* @param {
|
|
45
|
+
* @param {HTMLTarget} target - The DOM element where drag listeners will be attached.
|
|
46
|
+
* @param {DragAndDropOptions} options - Configuration options for the detector.
|
|
50
47
|
* @throws {TypeError} If `target` is not an HTMLElement.
|
|
51
|
-
* @throws {TypeError} If `fullscreen` is not a boolean.
|
|
52
48
|
* @throws {TypeError} If `hoverClass` is not a string.
|
|
53
49
|
* @throws {TypeError} If `onDrop` is defined but not a function.
|
|
54
50
|
* @throws {TypeError} If `onEnter` is defined but not a function.
|
|
55
51
|
* @throws {TypeError} If `onLeave` is defined but not a function.
|
|
56
52
|
*/
|
|
57
|
-
constructor(options
|
|
58
|
-
const {
|
|
59
|
-
target,
|
|
60
|
-
fullscreen = true,
|
|
61
|
-
hoverClass = 'dnd-hover',
|
|
62
|
-
onDrop,
|
|
63
|
-
onEnter,
|
|
64
|
-
onLeave,
|
|
65
|
-
} = options;
|
|
66
|
-
|
|
67
|
-
// Validate fullscreen
|
|
68
|
-
if (typeof fullscreen !== 'boolean')
|
|
69
|
-
throw new TypeError('The "fullscreen" option must be a boolean.');
|
|
53
|
+
constructor(target, options) {
|
|
54
|
+
const { hoverClass = 'dnd-hover', onDrop, onEnter, onLeave } = options;
|
|
70
55
|
|
|
71
56
|
// Validate target
|
|
72
|
-
|
|
73
|
-
if (!(resolvedTarget instanceof HTMLElement))
|
|
57
|
+
if (!(target instanceof HTMLElement))
|
|
74
58
|
throw new TypeError('The "target" option must be an instance of HTMLElement.');
|
|
75
59
|
|
|
76
60
|
// Validate hoverClass
|
|
@@ -90,8 +74,7 @@ class TinyDragDropDetector {
|
|
|
90
74
|
throw new TypeError('The "onLeave" option must be a function.');
|
|
91
75
|
|
|
92
76
|
// Store properties
|
|
93
|
-
this.#target =
|
|
94
|
-
this.#fullscreen = fullscreen;
|
|
77
|
+
this.#target = target;
|
|
95
78
|
this.#hoverClass = hoverClass;
|
|
96
79
|
|
|
97
80
|
this.#onDropCallback = onDrop || (() => {});
|
|
@@ -112,7 +95,7 @@ class TinyDragDropDetector {
|
|
|
112
95
|
|
|
113
96
|
/**
|
|
114
97
|
* Returns the current target DOM element where the listeners are attached.
|
|
115
|
-
* @returns {
|
|
98
|
+
* @returns {HTMLTarget}
|
|
116
99
|
*/
|
|
117
100
|
getTarget() {
|
|
118
101
|
return this.#target;
|
|
@@ -126,14 +109,6 @@ class TinyDragDropDetector {
|
|
|
126
109
|
return this.#hoverClass;
|
|
127
110
|
}
|
|
128
111
|
|
|
129
|
-
/**
|
|
130
|
-
* Indicates whether the detector is operating in fullscreen mode.
|
|
131
|
-
* @returns {boolean}
|
|
132
|
-
*/
|
|
133
|
-
isFullScreen() {
|
|
134
|
-
return this.#fullscreen;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
112
|
/**
|
|
138
113
|
* Returns whether a drag operation is currently active over the target.
|
|
139
114
|
* @returns {boolean}
|