tiny-essentials 1.26.2 → 1.26.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.
@@ -6,9 +6,10 @@ Welcome to **TinyClassManager**! This is a lightweight, linear mixin manager des
6
6
 
7
7
  ## 🚀 Key Features
8
8
 
9
- * **🔒 Immutable Chain State:** Each `.use()` call consumes the previous manager, preventing unwanted side effects or weird mutations.
9
+ * **🔒 Immutable Chain State:** Each `.insert()` call consumes the previous manager, preventing unwanted side effects or weird mutations.
10
10
  * **🧩 Dependency Verification:** Automatically ensures that a required plugin is loaded before the dependent plugin is applied.
11
11
  * **🛑 Conflict Protection:** Prevents you from installing the exact same plugin twice on the same class chain.
12
+ * **⚡ Clean Architecture:** Uses static class properties to manage metadata, keeping your plugin functions pure and direct.
12
13
 
13
14
  ---
14
15
 
@@ -25,8 +26,9 @@ Welcome to **TinyClassManager**! This is a lightweight, linear mixin manager des
25
26
 
26
27
  #### Methods
27
28
 
28
- * **`constructor(coreClass)`**: Initialises the manager with your foundational core class.
29
- * **`use(plugin)`**: Applies a new plugin to the chain. Returns a *new* `TinyClassManager` instance containing the extended class.
29
+ * **`constructor(coreClass)`**: Initializes the manager with your foundational core class.
30
+ * **`insert(applyFn)`**: Applies a new plugin to the chain by passing a function that returns the extended class. The returned class **must** define a `static _tinyDepName` string, and can optionally define a `static _tinyDeps` array of strings. Returns a *new* `TinyClassManager` instance.
31
+ * **`use(plugin)`**: *[Deprecated]* Legacy method for applying plugins using a definition object. Use `insert` instead.
30
32
  * **`build()`**: Finalizes the composition chain, marks the instance as consumed, and returns the fully compiled class ready for instantiation.
31
33
 
32
34
  ---
@@ -57,84 +59,81 @@ class EntityCore {
57
59
 
58
60
  ### Step 2: Create an Independent Module 🏷️
59
61
 
60
- Now, let's create our first module. A plugin is just a plain object with three specific keys: `name`, `dependencies`, and `apply`. This module doesn't depend on anything else, so its dependencies array is empty.
62
+ Now, let's create our first module. A plugin is a function that receives the base class and returns an extended version of it. We use static properties (`_tinyDepName` and `_tinyDeps`) to tell the manager what this plugin is and what it needs. This module doesn't depend on anything else, so its dependencies array is empty.
61
63
 
62
64
  ```javascript
63
- const Health = {
64
- name: 'Health',
65
- dependencies: [], // Works fine straight out of the box with the Core
66
-
67
- /**
68
- * @param {typeof EntityCore} Base - The incoming base class to extend.
69
- */
70
- apply: (Base) =>
71
- class HealthModule extends Base {
72
- /**
73
- * @param {string} id
74
- */
75
- constructor(id) {
76
- super(id); // Always remember to pass arguments down!
77
-
78
- /** @type {number} */
79
- this.hp = 100;
80
- }
81
-
82
- /**
83
- * Deducts health from the entity.
84
- * @param {number} amount - The amount of raw damage to deal.
85
- */
86
- takeDamage(amount) {
87
- this.hp -= amount;
88
- console.log(`Took ${amount} damage. HP left: ${this.hp}`);
89
- }
90
- },
91
- };
65
+ /**
66
+ * @param {typeof EntityCore} Base - The incoming base class to extend.
67
+ */
68
+ const applyHealth = (Base) =>
69
+ class HealthModule extends Base {
70
+ static _tinyDepName = 'Health';
71
+ /** @type {string[]} */
72
+ static _tinyDeps = []; // Works fine straight out of the box with the Core
73
+
74
+ /**
75
+ * @param {string} id
76
+ */
77
+ constructor(id) {
78
+ super(id); // Always remember to pass arguments down!
79
+
80
+ /** @type {number} */
81
+ this.hp = 100;
82
+ }
83
+
84
+ /**
85
+ * Deducts health from the entity.
86
+ * @param {number} amount - The amount of raw damage to deal.
87
+ */
88
+ takeDamage(amount) {
89
+ this.hp -= amount;
90
+ console.log(`Took ${amount} damage. HP left: ${this.hp}`);
91
+ }
92
+ };
92
93
 
93
94
  ```
94
95
 
95
96
  ### Step 3: Create a Dependent Module 🛡️
96
97
 
97
- Here is where the magic happens! The `Armor` module strictly requires the `Health` module to be loaded first because it relies on overriding the `takeDamage` logic. We enforce this relationship inside the `dependencies` array.
98
+ Here is where the magic happens! The `Armor` module strictly requires the `Health` module to be loaded first because it relies on overriding the `takeDamage` logic. We enforce this relationship inside the `static _tinyDeps` array.
98
99
 
99
100
  ```javascript
100
- const Armor = {
101
- name: 'Armor',
102
- dependencies: ['Health'], // Strictly requires the "Health" module!
103
-
104
- /**
105
- * @param {ReturnType<typeof Health.apply>} Base - The class containing Health features.
106
- */
107
- apply: (Base) =>
108
- class ArmorModule extends Base {
109
- /**
110
- * @param {string} id
111
- */
112
- constructor(id) {
113
- super(id);
114
-
115
- /** @type {number} */
116
- this.armor = 50;
117
- }
118
-
119
- /**
120
- * Deducts health, factoring in damage mitigation provided by armor.
121
- * @param {number} amount - The initial damage before armor reduction.
122
- */
123
- takeDamage(amount) {
124
- // Mitigates damage using the armor stat
125
- const reducedDamage = Math.max(0, amount - this.armor * 0.1);
126
-
127
- // Pass the mitigated damage up to the Health layer
128
- super.takeDamage(reducedDamage);
129
- }
130
- },
131
- };
101
+ /**
102
+ * @param {ReturnType<typeof applyHealth>} Base - The class containing Health features.
103
+ */
104
+ const applyArmor = (Base) =>
105
+ class ArmorModule extends Base {
106
+ static _tinyDepName = 'Armor';
107
+ static _tinyDeps = ['Health']; // Strictly requires the "Health" module!
108
+
109
+ /**
110
+ * @param {string} id
111
+ */
112
+ constructor(id) {
113
+ super(id);
114
+
115
+ /** @type {number} */
116
+ this.armor = 50;
117
+ }
118
+
119
+ /**
120
+ * Deducts health, factoring in damage mitigation provided by armor.
121
+ * @param {number} amount - The initial damage before armor reduction.
122
+ */
123
+ takeDamage(amount) {
124
+ // Mitigates damage using the armor stat
125
+ const reducedDamage = Math.max(0, amount - this.armor * 0.1);
126
+
127
+ // Pass the mitigated damage up to the Health layer
128
+ super.takeDamage(reducedDamage);
129
+ }
130
+ };
132
131
 
133
132
  ```
134
133
 
135
134
  ### Step 4: Chain and Build Your Custom Class 🏗️
136
135
 
137
- Finally, use the manager to safely piece your modules together. Remember that `TinyClassManager` uses an explosive state pattern: once you run `.use()` or `.build()`, that specific instance is closed, forcing you to use the new returned chain instance.
136
+ Finally, use the manager to safely piece your modules together. Remember that `TinyClassManager` uses an explosive state pattern: once you run `.insert()` or `.build()`, that specific instance is closed, forcing you to use the new returned chain instance.
138
137
 
139
138
  ```javascript
140
139
  try {
@@ -142,8 +141,8 @@ try {
142
141
  const CoreTest = new TinyClassManager(EntityCore);
143
142
 
144
143
  // 2. Chain your modules and compile!
145
- // If you try to swap the order (.use(Armor).use(Health)), it will throw an explicit dependency error.
146
- const FullyArmoredEntity = CoreTest.use(Health).use(Armor).build();
144
+ // If you try to swap the order (.insert(applyArmor).insert(applyHealth)), it will throw an explicit dependency error.
145
+ const FullyArmoredEntity = CoreTest.insert(applyHealth).insert(applyArmor).build();
147
146
 
148
147
  // 3. Create your custom instance!
149
148
  const myEntity = new FullyArmoredEntity('Player_1');
@@ -170,5 +169,5 @@ try {
170
169
  When you want to build a new set of mechanics for your game or application using this architecture, always remember to follow this loop:
171
170
 
172
171
  1. **Define your Base State**: Keep it clean and focused on global data configurations.
173
- 2. **Declare Plugins as Pure Objects**: Always structure them with `name`, `dependencies` (an array of strings matching other plugin names), and an `apply` method.
172
+ 2. **Declare Plugins as Functions**: Create a function that accepts a `Base` class and returns an extended class. Equip it with `static _tinyDepName` (string) and `static _tinyDeps` (array of strings).
174
173
  3. **Use `super` Inheritances**: Inside your plugin classes, always call `super(...)` in constructors and use `super.methodName(...)` if you are overriding an existing skill or function to allow all mixed behaviors to fire smoothly down the pipeline!
@@ -111,7 +111,7 @@ Removes a specific listener from an event.
111
111
 
112
112
  Removes all listeners for one or more events.
113
113
 
114
- #### `offAllTypes(): void`
114
+ #### `offAllTypes(): void` and `removeAllListeners(): void`
115
115
 
116
116
  Removes **all listeners** for **all events**.
117
117
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-essentials",
3
- "version": "1.26.2",
3
+ "version": "1.26.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
  "bin": {
6
6
  "tiny-essentials-fork": "./TinyFork.mjs"