tiny-essentials 1.26.0 → 1.26.2

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/README.md CHANGED
@@ -94,7 +94,7 @@ Feel free to fork, contribute, and create pull requests for improvements! Whethe
94
94
 
95
95
  ## 📝 License
96
96
 
97
- This project is licensed under the GPL-3.0 License - see the [LICENSE](LICENSE) file for details.
97
+ This project is licensed under the LGPL-3.0 License - see the [LICENSE](LICENSE) file for details.
98
98
 
99
99
  ### 💡 Credits
100
100
 
package/TinyFork.mjs CHANGED
@@ -46,17 +46,45 @@ const PATHS = {
46
46
  * @property {string[]} functionsToExtract - The specific functions to pull via Babel.
47
47
  */
48
48
  function parseTarget(rawTarget) {
49
+ /**
50
+ * Extracted version from the target string.
51
+ * @type {number|null}
52
+ */
49
53
  let targetVersion = null;
54
+
55
+ /**
56
+ * The target string without the version prefix.
57
+ * @type {string}
58
+ */
50
59
  let cleanTarget = rawTarget;
51
60
 
61
+ /**
62
+ * Regex match result for versioning.
63
+ * @type {RegExpMatchArray|null}
64
+ */
52
65
  const versionMatch = rawTarget.match(/^v(\d+)\//);
66
+
53
67
  if (versionMatch) {
54
68
  targetVersion = parseInt(versionMatch[1], 10);
55
69
  cleanTarget = rawTarget.replace(versionMatch[0], '');
56
70
  }
57
71
 
72
+ /**
73
+ * Indicates if specific functions are requested.
74
+ * @type {boolean}
75
+ */
58
76
  const hasFunctions = cleanTarget.includes(',');
77
+
78
+ /**
79
+ * List of specific function names to extract.
80
+ * @type {string[]}
81
+ */
59
82
  let functionsToExtract = [];
83
+
84
+ /**
85
+ * The base file path to search for.
86
+ * @type {string}
87
+ */
60
88
  let basePath = cleanTarget;
61
89
 
62
90
  if (hasFunctions) {
@@ -83,8 +111,22 @@ async function resolveSourceFile(targetVersion, basePath) {
83
111
  throw new Error('Forbidden extraction: Cannot export files from the build directory.');
84
112
  }
85
113
 
114
+ /**
115
+ * Supported file extensions.
116
+ * @type {string[]}
117
+ */
86
118
  const extensions = ['.mjs', '.js'];
119
+
120
+ /**
121
+ * The starting version for the resolution search.
122
+ * @type {number}
123
+ */
87
124
  const startVersion = targetVersion || LATEST_VERSION;
125
+
126
+ /**
127
+ * The ending version for the resolution search limit.
128
+ * @type {number}
129
+ */
88
130
  const endVersion = targetVersion ? targetVersion : 1;
89
131
 
90
132
  for (let v = startVersion; v >= endVersion; v--) {
@@ -115,6 +157,37 @@ async function resolveSourceFile(targetVersion, basePath) {
115
157
  throw new Error(`Module not found: ${basePath}`);
116
158
  }
117
159
 
160
+ /**
161
+ * Copies the LICENSE file from the project root to the destination vendor directory.
162
+ *
163
+ * @param {string} destDir - The final vendor output directory.
164
+ * @returns {Promise<void>} Resolves when the file is copied (or skipped if missing).
165
+ */
166
+ async function copyLicense(destDir) {
167
+ /**
168
+ * Absolute path to the original LICENSE file.
169
+ * @type {string}
170
+ */
171
+ const licenseSrc = path.join(PATHS.cliRoot, 'LICENSE');
172
+
173
+ /**
174
+ * Absolute path to the destination LICENSE file.
175
+ * @type {string}
176
+ */
177
+ const licenseDest = path.join(destDir, 'LICENSE');
178
+
179
+ try {
180
+ if (existsSync(licenseSrc)) {
181
+ await fs.copyFile(licenseSrc, licenseDest);
182
+ console.log('> Copied: LICENSE');
183
+ } else {
184
+ console.warn('> Warning: LICENSE file not found in the root directory.');
185
+ }
186
+ } catch (error) {
187
+ console.error(`> Error copying LICENSE: ${error.message}`);
188
+ }
189
+ }
190
+
118
191
  /**
119
192
  * Advanced Multi-File Dependency Extractor.
120
193
  * Parses files, traces dependencies, and extracts everything mirroring the original structure.
@@ -569,14 +642,25 @@ class MultiFileExtractor {
569
642
  async function runCLI() {
570
643
  const args = process.argv.slice(2);
571
644
 
645
+ /**
646
+ * The explicit output directory argument if passed.
647
+ * @type {string|undefined}
648
+ */
572
649
  const outDirArg = args.find((a) => a.startsWith('--out-dir='));
650
+
651
+ /**
652
+ * The formatted custom output directory.
653
+ * @type {string|null}
654
+ */
573
655
  const customOutDir = outDirArg ? outDirArg.split('=')[1] : null;
574
656
 
575
657
  // Filter out flags to get the raw target strings
576
658
  const rawTargets = args.filter((a) => !a.startsWith('--'));
577
659
 
578
660
  if (rawTargets.length === 0) {
579
- console.error('Usage: npx tiny-essentials-fork [--out-dir=custom/path] <target1> [target2] ...');
661
+ console.error(
662
+ 'Usage: npx tiny-essentials-fork [--out-dir=custom/path] <target1> [target2] ...',
663
+ );
580
664
  console.error('Example: npx tiny-essentials-fork v1/basics/example/func1 v1/lib/TinyHtml');
581
665
  process.exit(1);
582
666
  }
@@ -598,6 +682,9 @@ async function runCLI() {
598
682
 
599
683
  console.log(`Starting extraction to: ${finalVendorDir}\n`);
600
684
  await extractor.processQueue();
685
+
686
+ // Copy the license file explicitly at the very end of processing
687
+ await copyLicense(finalVendorDir);
601
688
  } catch (error) {
602
689
  console.error('\nError extracting modules:');
603
690
  console.error(error.message);
@@ -0,0 +1,10 @@
1
+ ## ✨ New Features & Additions
2
+
3
+ ### ⚙️ **TinyClassManager** (`libs/TinyClassManager.mjs`)
4
+
5
+ A lightweight, immutable manager designed to linearly compose a base class with multiple modular plugins (mixins). It acts as a safe pipeline for class extension.
6
+
7
+ * **🔒 Immutable Chain State:** Each `.use()` call consumes the previous manager instance and returns a new one. This ensures predictable state transitions and prevents unwanted side effects or accidental reuses of an old chain.
8
+ * **🧩 Smart Dependency Verification:** Plugins can define a `dependencies` array. The manager automatically verifies that all required modules are installed *before* applying the new plugin. If a dependency is missing, it throws a clear, descriptive error.
9
+ * **🛑 Duplicate Conflict Protection:** Accidentally applying the same plugin twice? The manager actively prevents this by tracking applied plugins and throwing an error if a conflict is detected.
10
+ * **🛠️ Clean Build Pipeline:** The `.build()` method finalizes the composition, locking the manager and returning the fully compiled class, ready to be instantiated.
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e={d:(s,n)=>{for(var a in n)e.o(n,a)&&!e.o(s,a)&&Object.defineProperty(s,a,{enumerable:!0,get:n[a]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)},s={};e.d(s,{TinyClassManager:()=>a});class n{#e=new Set;get appliedPlugins(){return[...this.#e]}get size(){return this.#e.size+1}#s;get currentClass(){return this.#s}#n=!1;get used(){return this.#n}constructor(e){this.#s=e}use(e){if(this.#n)throw new Error("[TinyClassManager] Cannot reuse a consumed manager instance.");if(this.#e.has(e.name))throw new Error(`[TinyClassManager] Plugin conflict: "${e.name}" is already installed.`);const s=e.dependencies||[];for(const n of s)if(!this.#e.has(n))throw new Error(`[TinyClassManager] Missing Dependency: "${e.name}" requires "${n}" to be installed first.`);const a=new n(e.apply(this.#s));return this.#e.forEach(e=>a.#e.add(e)),a.#e.add(e.name),this.#n=!0,this.#e.clear(),a}build(){if(this.#n)throw new Error("[TinyClassManager] Cannot build from an already finalized manager.");return this.#n=!0,this.#e.clear(),this.#s}}const a=n;window.TinyClassManager=s.TinyClassManager})();