tiny-essentials 1.20.2 → 1.21.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.
Files changed (123) hide show
  1. package/README.md +13 -11
  2. package/dist/_/numbers.cjs +136 -0
  3. package/dist/_/numbers.d.mts +24 -0
  4. package/dist/_/numbers.mjs +102 -0
  5. package/dist/v1/TinyAdvancedRaffle.min.js +1 -0
  6. package/dist/v1/TinyArrayPaginator.min.js +1 -0
  7. package/dist/v1/TinyBasicsEs.min.js +1 -1
  8. package/dist/v1/TinyCookieConsent.min.js +1 -0
  9. package/dist/v1/TinyDayNightCycle.min.js +1 -0
  10. package/dist/v1/TinyEssentials.min.js +1 -1
  11. package/dist/v1/TinyGamepad.min.js +1 -0
  12. package/dist/v1/TinyI18.min.js +1 -0
  13. package/dist/v1/TinyInventory.min.js +1 -0
  14. package/dist/v1/TinyInventoryTrader.min.js +1 -0
  15. package/dist/v1/TinyLocalStorage.min.js +1 -1
  16. package/dist/v1/TinyRateLimiter.min.js +1 -1
  17. package/dist/v1/TinySmartScroller.min.js +1 -1
  18. package/dist/v1/TinyTextarea.min.js +1 -0
  19. package/dist/v1/TinyToastNotify.min.js +1 -1
  20. package/dist/v1/TinyUploadClicker.min.js +1 -1
  21. package/dist/v1/basics/array.cjs +21 -0
  22. package/dist/v1/basics/array.d.mts +8 -0
  23. package/dist/v1/basics/array.mjs +18 -0
  24. package/dist/v1/basics/index.cjs +2 -8
  25. package/dist/v1/basics/index.d.mts +3 -8
  26. package/dist/v1/basics/index.mjs +2 -3
  27. package/dist/v1/basics/simpleMath.cjs +46 -0
  28. package/dist/v1/basics/simpleMath.d.mts +27 -0
  29. package/dist/v1/basics/simpleMath.mjs +42 -0
  30. package/dist/v1/build/TinyAdvancedRaffle.cjs +7 -0
  31. package/dist/v1/build/TinyAdvancedRaffle.d.mts +3 -0
  32. package/dist/v1/build/TinyAdvancedRaffle.mjs +2 -0
  33. package/dist/v1/build/TinyArrayPaginator.cjs +7 -0
  34. package/dist/v1/build/TinyArrayPaginator.d.mts +3 -0
  35. package/dist/v1/build/TinyArrayPaginator.mjs +2 -0
  36. package/dist/v1/build/TinyCookieConsent.cjs +7 -0
  37. package/dist/v1/build/TinyCookieConsent.d.mts +3 -0
  38. package/dist/v1/build/TinyCookieConsent.mjs +2 -0
  39. package/dist/v1/build/TinyDayNightCycle.cjs +7 -0
  40. package/dist/v1/build/TinyDayNightCycle.d.mts +3 -0
  41. package/dist/v1/build/TinyDayNightCycle.mjs +2 -0
  42. package/dist/v1/build/TinyGamepad.cjs +7 -0
  43. package/dist/v1/build/TinyGamepad.d.mts +3 -0
  44. package/dist/v1/build/TinyGamepad.mjs +2 -0
  45. package/dist/v1/build/TinyI18.cjs +7 -0
  46. package/dist/v1/build/TinyI18.d.mts +3 -0
  47. package/dist/v1/build/TinyI18.mjs +2 -0
  48. package/dist/v1/build/TinyInventory.cjs +7 -0
  49. package/dist/v1/build/TinyInventory.d.mts +3 -0
  50. package/dist/v1/build/TinyInventory.mjs +2 -0
  51. package/dist/v1/build/TinyInventoryTrader.cjs +7 -0
  52. package/dist/v1/build/TinyInventoryTrader.d.mts +3 -0
  53. package/dist/v1/build/TinyInventoryTrader.mjs +2 -0
  54. package/dist/v1/build/TinyTextarea.cjs +7 -0
  55. package/dist/v1/build/TinyTextarea.d.mts +3 -0
  56. package/dist/v1/build/TinyTextarea.mjs +2 -0
  57. package/dist/v1/css/TinyCookieConsent.min.css +1 -0
  58. package/dist/v1/index.cjs +20 -8
  59. package/dist/v1/index.d.mts +12 -8
  60. package/dist/v1/index.mjs +11 -3
  61. package/dist/v1/libs/TinyAdvancedRaffle.cjs +1654 -0
  62. package/dist/v1/libs/TinyAdvancedRaffle.d.mts +851 -0
  63. package/dist/v1/libs/TinyAdvancedRaffle.mjs +1477 -0
  64. package/dist/v1/libs/TinyArrayPaginator.cjs +132 -0
  65. package/dist/v1/libs/TinyArrayPaginator.d.mts +78 -0
  66. package/dist/v1/libs/TinyArrayPaginator.mjs +119 -0
  67. package/dist/v1/libs/TinyCookieConsent.cjs +278 -0
  68. package/dist/v1/libs/TinyCookieConsent.d.mts +142 -0
  69. package/dist/v1/libs/TinyCookieConsent.mjs +248 -0
  70. package/dist/v1/libs/TinyDayNightCycle.cjs +1389 -0
  71. package/dist/v1/libs/TinyDayNightCycle.d.mts +673 -0
  72. package/dist/v1/libs/TinyDayNightCycle.mjs +1232 -0
  73. package/dist/v1/libs/TinyGamepad.cjs +2690 -0
  74. package/dist/v1/libs/TinyGamepad.d.mts +1286 -0
  75. package/dist/v1/libs/TinyGamepad.mjs +2386 -0
  76. package/dist/v1/libs/TinyHtml.d.mts +2 -2
  77. package/dist/v1/libs/TinyI18.cjs +946 -0
  78. package/dist/v1/libs/TinyI18.d.mts +418 -0
  79. package/dist/v1/libs/TinyI18.mjs +873 -0
  80. package/dist/v1/libs/TinyInventory.cjs +1788 -0
  81. package/dist/v1/libs/TinyInventory.d.mts +871 -0
  82. package/dist/v1/libs/TinyInventory.mjs +1650 -0
  83. package/dist/v1/libs/TinyInventoryTrader.cjs +242 -0
  84. package/dist/v1/libs/TinyInventoryTrader.d.mts +95 -0
  85. package/dist/v1/libs/TinyInventoryTrader.mjs +212 -0
  86. package/dist/v1/libs/TinyLocalStorage.cjs +14 -1
  87. package/dist/v1/libs/TinyLocalStorage.mjs +8 -1
  88. package/dist/v1/libs/TinyRateLimiter.cjs +0 -13
  89. package/dist/v1/libs/TinyRateLimiter.d.mts +0 -8
  90. package/dist/v1/libs/TinyRateLimiter.mjs +0 -12
  91. package/dist/v1/libs/TinySmartScroller.cjs +51 -15
  92. package/dist/v1/libs/TinySmartScroller.d.mts +28 -12
  93. package/dist/v1/libs/TinySmartScroller.mjs +44 -14
  94. package/dist/v1/libs/TinyTextarea.cjs +230 -0
  95. package/dist/v1/libs/TinyTextarea.d.mts +128 -0
  96. package/dist/v1/libs/TinyTextarea.mjs +198 -0
  97. package/dist/v1/libs/TinyToastNotify.cjs +2 -2
  98. package/dist/v1/libs/TinyToastNotify.mjs +2 -2
  99. package/dist/v1/libs/TinyUploadClicker.cjs +1 -1
  100. package/docs/v1/Ai-Tips.md +51 -0
  101. package/docs/v1/Personal-Ai-Prompts(portuguese).md +134 -0
  102. package/docs/v1/Personal-Ai-Prompts.md +113 -0
  103. package/docs/v1/README.md +24 -0
  104. package/docs/v1/basics/array.md +17 -0
  105. package/docs/v1/basics/simpleMath.md +73 -0
  106. package/docs/v1/libs/TinyAdvancedRaffle.md +674 -0
  107. package/docs/v1/libs/TinyArrayPaginator.md +150 -0
  108. package/docs/v1/libs/TinyCookieConsent.md +152 -0
  109. package/docs/v1/libs/TinyDayNightCycle.md +711 -0
  110. package/docs/v1/libs/TinyGamepad.md +980 -0
  111. package/docs/v1/libs/TinyI18.md +515 -0
  112. package/docs/v1/libs/TinyInventory.md +777 -0
  113. package/docs/v1/libs/TinyInventoryTrader.md +114 -0
  114. package/docs/v1/libs/TinySmartScroller.md +4 -4
  115. package/docs/v1/libs/TinyTextarea.md +156 -0
  116. package/package.json +7 -5
  117. package/dist/v1/basics/html_deprecated.cjs +0 -124
  118. package/dist/v1/basics/html_deprecated.d.mts +0 -40
  119. package/dist/v1/basics/html_deprecated.mjs +0 -97
  120. package/dist/v1/css/TinyDraggerExample.css +0 -21
  121. package/dist/v1/css/TinyNotify.css +0 -350
  122. package/dist/v1/css/aiMarker.css +0 -4
  123. package/docs/v1/basics/html_deprecated.md +0 -127
@@ -0,0 +1,242 @@
1
+ 'use strict';
2
+
3
+ var TinyInventory = require('./TinyInventory.cjs');
4
+
5
+ /** @typedef {import('./TinyInventory.mjs').InventoryMetadata} InventoryMetadata */
6
+ /** @typedef {import('./TinyInventory.mjs').AddItemResult} AddItemResult */
7
+
8
+ /**
9
+ * @typedef {Object} TransferItemCfg - Transfer configuration.
10
+ * @property {number} [slotIndex] - Sender slot index.
11
+ * @property {number} [receiverSlotIndex] - Receiver slot index (optional).
12
+ * @property {string} [specialSlot] - Sender special slot ID.
13
+ * @property {number} [quantity=1] - Quantity to transfer.
14
+ * @property {boolean} [forceSpace=false] - Whether to force addition even if space is limited.
15
+ @property {boolean} [strict=false] - If true, transfer will throw if not all items can fit.
16
+ */
17
+
18
+ /**
19
+ * Class responsible for managing item transfers between two TinyInventory instances.
20
+ */
21
+ class TinyInventoryTrader {
22
+ /** @type {TinyInventory|null} */
23
+ #sender = null;
24
+
25
+ /** @type {TinyInventory|null} */
26
+ #receiver = null;
27
+
28
+ ///////////////////////////////////////////////
29
+
30
+ /** @returns {TinyInventory|null} The currently connected sender inventory. */
31
+ get sender() {
32
+ return this.#sender;
33
+ }
34
+
35
+ /** @returns {TinyInventory|null} The currently connected receiver inventory. */
36
+ get receiver() {
37
+ return this.#receiver;
38
+ }
39
+
40
+ /** @param {TinyInventory} value Sets the sender inventory. */
41
+ set sender(value) {
42
+ if (!(value instanceof TinyInventory) || !(this.receiver instanceof TinyInventory))
43
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
44
+ this.#sender = value;
45
+ }
46
+
47
+ /** @param {TinyInventory} value Sets the receiver inventory. */
48
+ set receiver(value) {
49
+ if (!(this.sender instanceof TinyInventory) || !(value instanceof TinyInventory))
50
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
51
+ this.#receiver = value;
52
+ }
53
+
54
+ ///////////////////////////////////////////////
55
+
56
+ /**
57
+ * Manages item transfers between two TinyInventory instances.
58
+ * @param {TinyInventory} [sender] - Inventory to remove items from.
59
+ * @param {TinyInventory} [receiver] - Inventory to add items to.
60
+ */
61
+ constructor(sender, receiver) {
62
+ if (sender || receiver) {
63
+ if (!(sender instanceof TinyInventory) || !(receiver instanceof TinyInventory))
64
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
65
+ this.connect(sender, receiver);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Connects the sender and receiver inventories for trading.
71
+ * @param {TinyInventory} sender - Inventory to remove items from.
72
+ * @param {TinyInventory} receiver - Inventory to add items to.
73
+ */
74
+ connect(sender, receiver) {
75
+ if (!(sender instanceof TinyInventory) || !(receiver instanceof TinyInventory))
76
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
77
+ this.#sender = sender;
78
+ this.#receiver = receiver;
79
+ }
80
+
81
+ /**
82
+ * Disconnects the sender and receiver inventories, preventing further transfers.
83
+ */
84
+ disconnect() {
85
+ this.#sender = null;
86
+ this.#receiver = null;
87
+ }
88
+
89
+ /**
90
+ * Inverts the sender and receiver roles.
91
+ * Useful when performing bidirectional transfers.
92
+ */
93
+ invert() {
94
+ const sender = this.#sender;
95
+ const receiver = this.#receiver;
96
+ this.#sender = receiver;
97
+ this.#receiver = sender;
98
+ }
99
+
100
+ /**
101
+ * Transfers an item from sender to receiver.
102
+ *
103
+ * @param {TransferItemCfg} options - Transfer configuration.
104
+ * @returns {Partial<AddItemResult>} Remaining quantity that could NOT be transferred.
105
+ * @throws {Error} If sender or receiver is not connected, item does not exist in sender,
106
+ * or if strict mode is enabled and receiver has no space for full transfer.
107
+ */
108
+ transferItem({
109
+ slotIndex,
110
+ specialSlot,
111
+ quantity = 1,
112
+ receiverSlotIndex,
113
+ forceSpace = false,
114
+ strict = false,
115
+ }) {
116
+ if (!this.#sender || !this.#receiver)
117
+ throw new Error('Sender and receiver inventories must be connected.');
118
+
119
+ // Get the item from sender
120
+ let item;
121
+ if (specialSlot) {
122
+ item = this.#sender.getSpecialItem(specialSlot);
123
+ if (!item) throw new Error(`No item found in sender special slot '${specialSlot}'.`);
124
+ } else if (typeof slotIndex === 'number') {
125
+ item = this.#sender.getItemFrom(slotIndex);
126
+ if (!item) throw new Error(`No item found in sender slot ${slotIndex}.`);
127
+ } else throw new Error('Must provide either slotIndex or specialSlot.');
128
+
129
+ // Match quantity
130
+ if (item.quantity < quantity)
131
+ throw new Error(`Sender does not have enough quantity of '${item.id}' to transfer.`);
132
+
133
+ // Clone item for transfer
134
+ const transferItem = {
135
+ id: item.id,
136
+ quantity,
137
+ metadata: item.metadata,
138
+ };
139
+
140
+ let result;
141
+
142
+ // ---------- STRICT MODE PRE-CHECK ----------
143
+ if (strict) {
144
+ if (typeof receiverSlotIndex === 'number') {
145
+ const existing = this.#receiver.existsItemAt(receiverSlotIndex)
146
+ ? this.#receiver.getItemFrom(receiverSlotIndex)
147
+ : null;
148
+ if (existing) {
149
+ if (existing.id !== transferItem.id)
150
+ throw new Error(`Receiver slot ${receiverSlotIndex} contains a different item.`);
151
+ const def = TinyInventory.getItem(existing.id);
152
+
153
+ const spaceLeft = def.maxStack - existing.quantity;
154
+ if (transferItem.quantity > spaceLeft)
155
+ throw new Error(`Strict mode: not enough space in receiver slot ${receiverSlotIndex}.`);
156
+ }
157
+ } else {
158
+ // Simulate addItem result
159
+ const simulated = this.#receiver.clone().addItem({
160
+ itemId: transferItem.id,
161
+ quantity: transferItem.quantity,
162
+ metadata: transferItem.metadata,
163
+ forceSpace,
164
+ });
165
+ if (simulated.remaining > 0)
166
+ throw new Error(`Strict mode: not enough space in receiver inventory.`);
167
+ }
168
+ }
169
+ // ---------- END STRICT CHECK ----------
170
+
171
+ // If receiverSlotIndex is informed → use setItem on receiver
172
+ if (typeof receiverSlotIndex === 'number') {
173
+ const existing = this.#receiver.existsItemAt(receiverSlotIndex)
174
+ ? this.#receiver.getItemFrom(receiverSlotIndex)
175
+ : null;
176
+ let movedQty = transferItem.quantity;
177
+
178
+ // If there is already item in this slot
179
+ if (existing) {
180
+ if (existing.id !== transferItem.id)
181
+ throw new Error(`Receiver slot ${receiverSlotIndex} contains a different item.`);
182
+ const def = TinyInventory.getItem(existing.id);
183
+
184
+ const spaceLeft = def.maxStack - existing.quantity;
185
+ movedQty = Math.min(spaceLeft, transferItem.quantity);
186
+
187
+ if (movedQty > 0) {
188
+ this.#receiver.setItem({
189
+ slotIndex: receiverSlotIndex,
190
+ item: { ...existing, quantity: existing.quantity + movedQty },
191
+ forceSpace,
192
+ });
193
+ }
194
+ } else {
195
+ // Empty Slot → just seal the whole item
196
+ this.#receiver.setItem({
197
+ slotIndex: receiverSlotIndex,
198
+ item: transferItem,
199
+ forceSpace,
200
+ });
201
+ }
202
+
203
+ // Now we calculate what's left
204
+ result = { remaining: transferItem.quantity - movedQty };
205
+ } else {
206
+ result = this.#receiver.addItem({
207
+ itemId: transferItem.id,
208
+ quantity: transferItem.quantity,
209
+ metadata: transferItem.metadata,
210
+ forceSpace,
211
+ });
212
+ }
213
+
214
+ // Remove successfully transferred quantity from sender
215
+ const removedQty = transferItem.quantity - result.remaining;
216
+ if (removedQty > 0) {
217
+ if (specialSlot) {
218
+ this.#sender.unequipItem({ slotId: specialSlot, quantity: removedQty, forceSpace });
219
+ } else if (typeof slotIndex === 'number') {
220
+ const remainingQty = item.quantity - removedQty;
221
+ this.#sender.setItem({
222
+ slotIndex,
223
+ item: remainingQty > 0 ? { ...item, quantity: remainingQty } : null,
224
+ forceSpace,
225
+ });
226
+ }
227
+ }
228
+
229
+ return result;
230
+ }
231
+
232
+ /**
233
+ * Transfers multiple items at once.
234
+ * @param {TransferItemCfg[]} items - Array of transfer configs (see transferItem options).
235
+ * @returns {Partial<AddItemResult>[]} Array of remaining quantities for each item.
236
+ */
237
+ transferMultiple(items) {
238
+ return items.map((cfg) => this.transferItem(cfg));
239
+ }
240
+ }
241
+
242
+ module.exports = TinyInventoryTrader;
@@ -0,0 +1,95 @@
1
+ export default TinyInventoryTrader;
2
+ export type InventoryMetadata = import("./TinyInventory.mjs").InventoryMetadata;
3
+ export type AddItemResult = import("./TinyInventory.mjs").AddItemResult;
4
+ /**
5
+ * - Transfer configuration.
6
+ */
7
+ export type TransferItemCfg = {
8
+ /**
9
+ * - Sender slot index.
10
+ */
11
+ slotIndex?: number | undefined;
12
+ /**
13
+ * - Receiver slot index (optional).
14
+ */
15
+ receiverSlotIndex?: number | undefined;
16
+ /**
17
+ * - Sender special slot ID.
18
+ */
19
+ specialSlot?: string | undefined;
20
+ /**
21
+ * - Quantity to transfer.
22
+ */
23
+ quantity?: number | undefined;
24
+ /**
25
+ * - Whether to force addition even if space is limited.
26
+ */
27
+ forceSpace?: boolean | undefined;
28
+ /**
29
+ * - If true, transfer will throw if not all items can fit.
30
+ */
31
+ strict?: boolean | undefined;
32
+ };
33
+ /** @typedef {import('./TinyInventory.mjs').InventoryMetadata} InventoryMetadata */
34
+ /** @typedef {import('./TinyInventory.mjs').AddItemResult} AddItemResult */
35
+ /**
36
+ * @typedef {Object} TransferItemCfg - Transfer configuration.
37
+ * @property {number} [slotIndex] - Sender slot index.
38
+ * @property {number} [receiverSlotIndex] - Receiver slot index (optional).
39
+ * @property {string} [specialSlot] - Sender special slot ID.
40
+ * @property {number} [quantity=1] - Quantity to transfer.
41
+ * @property {boolean} [forceSpace=false] - Whether to force addition even if space is limited.
42
+ @property {boolean} [strict=false] - If true, transfer will throw if not all items can fit.
43
+ */
44
+ /**
45
+ * Class responsible for managing item transfers between two TinyInventory instances.
46
+ */
47
+ declare class TinyInventoryTrader {
48
+ /**
49
+ * Manages item transfers between two TinyInventory instances.
50
+ * @param {TinyInventory} [sender] - Inventory to remove items from.
51
+ * @param {TinyInventory} [receiver] - Inventory to add items to.
52
+ */
53
+ constructor(sender?: TinyInventory, receiver?: TinyInventory);
54
+ /** @param {TinyInventory} value Sets the sender inventory. */
55
+ set sender(value: TinyInventory);
56
+ /** @returns {TinyInventory|null} The currently connected sender inventory. */
57
+ get sender(): TinyInventory | null;
58
+ /** @param {TinyInventory} value Sets the receiver inventory. */
59
+ set receiver(value: TinyInventory);
60
+ /** @returns {TinyInventory|null} The currently connected receiver inventory. */
61
+ get receiver(): TinyInventory | null;
62
+ /**
63
+ * Connects the sender and receiver inventories for trading.
64
+ * @param {TinyInventory} sender - Inventory to remove items from.
65
+ * @param {TinyInventory} receiver - Inventory to add items to.
66
+ */
67
+ connect(sender: TinyInventory, receiver: TinyInventory): void;
68
+ /**
69
+ * Disconnects the sender and receiver inventories, preventing further transfers.
70
+ */
71
+ disconnect(): void;
72
+ /**
73
+ * Inverts the sender and receiver roles.
74
+ * Useful when performing bidirectional transfers.
75
+ */
76
+ invert(): void;
77
+ /**
78
+ * Transfers an item from sender to receiver.
79
+ *
80
+ * @param {TransferItemCfg} options - Transfer configuration.
81
+ * @returns {Partial<AddItemResult>} Remaining quantity that could NOT be transferred.
82
+ * @throws {Error} If sender or receiver is not connected, item does not exist in sender,
83
+ * or if strict mode is enabled and receiver has no space for full transfer.
84
+ */
85
+ transferItem({ slotIndex, specialSlot, quantity, receiverSlotIndex, forceSpace, strict, }: TransferItemCfg): Partial<AddItemResult>;
86
+ /**
87
+ * Transfers multiple items at once.
88
+ * @param {TransferItemCfg[]} items - Array of transfer configs (see transferItem options).
89
+ * @returns {Partial<AddItemResult>[]} Array of remaining quantities for each item.
90
+ */
91
+ transferMultiple(items: TransferItemCfg[]): Partial<AddItemResult>[];
92
+ #private;
93
+ }
94
+ import TinyInventory from './TinyInventory.mjs';
95
+ //# sourceMappingURL=TinyInventoryTrader.d.mts.map
@@ -0,0 +1,212 @@
1
+ import TinyInventory from './TinyInventory.mjs';
2
+ /** @typedef {import('./TinyInventory.mjs').InventoryMetadata} InventoryMetadata */
3
+ /** @typedef {import('./TinyInventory.mjs').AddItemResult} AddItemResult */
4
+ /**
5
+ * @typedef {Object} TransferItemCfg - Transfer configuration.
6
+ * @property {number} [slotIndex] - Sender slot index.
7
+ * @property {number} [receiverSlotIndex] - Receiver slot index (optional).
8
+ * @property {string} [specialSlot] - Sender special slot ID.
9
+ * @property {number} [quantity=1] - Quantity to transfer.
10
+ * @property {boolean} [forceSpace=false] - Whether to force addition even if space is limited.
11
+ @property {boolean} [strict=false] - If true, transfer will throw if not all items can fit.
12
+ */
13
+ /**
14
+ * Class responsible for managing item transfers between two TinyInventory instances.
15
+ */
16
+ class TinyInventoryTrader {
17
+ /** @type {TinyInventory|null} */
18
+ #sender = null;
19
+ /** @type {TinyInventory|null} */
20
+ #receiver = null;
21
+ ///////////////////////////////////////////////
22
+ /** @returns {TinyInventory|null} The currently connected sender inventory. */
23
+ get sender() {
24
+ return this.#sender;
25
+ }
26
+ /** @returns {TinyInventory|null} The currently connected receiver inventory. */
27
+ get receiver() {
28
+ return this.#receiver;
29
+ }
30
+ /** @param {TinyInventory} value Sets the sender inventory. */
31
+ set sender(value) {
32
+ if (!(value instanceof TinyInventory) || !(this.receiver instanceof TinyInventory))
33
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
34
+ this.#sender = value;
35
+ }
36
+ /** @param {TinyInventory} value Sets the receiver inventory. */
37
+ set receiver(value) {
38
+ if (!(this.sender instanceof TinyInventory) || !(value instanceof TinyInventory))
39
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
40
+ this.#receiver = value;
41
+ }
42
+ ///////////////////////////////////////////////
43
+ /**
44
+ * Manages item transfers between two TinyInventory instances.
45
+ * @param {TinyInventory} [sender] - Inventory to remove items from.
46
+ * @param {TinyInventory} [receiver] - Inventory to add items to.
47
+ */
48
+ constructor(sender, receiver) {
49
+ if (sender || receiver) {
50
+ if (!(sender instanceof TinyInventory) || !(receiver instanceof TinyInventory))
51
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
52
+ this.connect(sender, receiver);
53
+ }
54
+ }
55
+ /**
56
+ * Connects the sender and receiver inventories for trading.
57
+ * @param {TinyInventory} sender - Inventory to remove items from.
58
+ * @param {TinyInventory} receiver - Inventory to add items to.
59
+ */
60
+ connect(sender, receiver) {
61
+ if (!(sender instanceof TinyInventory) || !(receiver instanceof TinyInventory))
62
+ throw new Error('Both sender and receiver must be TinyInventory instances.');
63
+ this.#sender = sender;
64
+ this.#receiver = receiver;
65
+ }
66
+ /**
67
+ * Disconnects the sender and receiver inventories, preventing further transfers.
68
+ */
69
+ disconnect() {
70
+ this.#sender = null;
71
+ this.#receiver = null;
72
+ }
73
+ /**
74
+ * Inverts the sender and receiver roles.
75
+ * Useful when performing bidirectional transfers.
76
+ */
77
+ invert() {
78
+ const sender = this.#sender;
79
+ const receiver = this.#receiver;
80
+ this.#sender = receiver;
81
+ this.#receiver = sender;
82
+ }
83
+ /**
84
+ * Transfers an item from sender to receiver.
85
+ *
86
+ * @param {TransferItemCfg} options - Transfer configuration.
87
+ * @returns {Partial<AddItemResult>} Remaining quantity that could NOT be transferred.
88
+ * @throws {Error} If sender or receiver is not connected, item does not exist in sender,
89
+ * or if strict mode is enabled and receiver has no space for full transfer.
90
+ */
91
+ transferItem({ slotIndex, specialSlot, quantity = 1, receiverSlotIndex, forceSpace = false, strict = false, }) {
92
+ if (!this.#sender || !this.#receiver)
93
+ throw new Error('Sender and receiver inventories must be connected.');
94
+ // Get the item from sender
95
+ let item;
96
+ if (specialSlot) {
97
+ item = this.#sender.getSpecialItem(specialSlot);
98
+ if (!item)
99
+ throw new Error(`No item found in sender special slot '${specialSlot}'.`);
100
+ }
101
+ else if (typeof slotIndex === 'number') {
102
+ item = this.#sender.getItemFrom(slotIndex);
103
+ if (!item)
104
+ throw new Error(`No item found in sender slot ${slotIndex}.`);
105
+ }
106
+ else
107
+ throw new Error('Must provide either slotIndex or specialSlot.');
108
+ // Match quantity
109
+ if (item.quantity < quantity)
110
+ throw new Error(`Sender does not have enough quantity of '${item.id}' to transfer.`);
111
+ // Clone item for transfer
112
+ const transferItem = {
113
+ id: item.id,
114
+ quantity,
115
+ metadata: item.metadata,
116
+ };
117
+ let result;
118
+ // ---------- STRICT MODE PRE-CHECK ----------
119
+ if (strict) {
120
+ if (typeof receiverSlotIndex === 'number') {
121
+ const existing = this.#receiver.existsItemAt(receiverSlotIndex)
122
+ ? this.#receiver.getItemFrom(receiverSlotIndex)
123
+ : null;
124
+ if (existing) {
125
+ if (existing.id !== transferItem.id)
126
+ throw new Error(`Receiver slot ${receiverSlotIndex} contains a different item.`);
127
+ const def = TinyInventory.getItem(existing.id);
128
+ const spaceLeft = def.maxStack - existing.quantity;
129
+ if (transferItem.quantity > spaceLeft)
130
+ throw new Error(`Strict mode: not enough space in receiver slot ${receiverSlotIndex}.`);
131
+ }
132
+ }
133
+ else {
134
+ // Simulate addItem result
135
+ const simulated = this.#receiver.clone().addItem({
136
+ itemId: transferItem.id,
137
+ quantity: transferItem.quantity,
138
+ metadata: transferItem.metadata,
139
+ forceSpace,
140
+ });
141
+ if (simulated.remaining > 0)
142
+ throw new Error(`Strict mode: not enough space in receiver inventory.`);
143
+ }
144
+ }
145
+ // ---------- END STRICT CHECK ----------
146
+ // If receiverSlotIndex is informed → use setItem on receiver
147
+ if (typeof receiverSlotIndex === 'number') {
148
+ const existing = this.#receiver.existsItemAt(receiverSlotIndex)
149
+ ? this.#receiver.getItemFrom(receiverSlotIndex)
150
+ : null;
151
+ let movedQty = transferItem.quantity;
152
+ // If there is already item in this slot
153
+ if (existing) {
154
+ if (existing.id !== transferItem.id)
155
+ throw new Error(`Receiver slot ${receiverSlotIndex} contains a different item.`);
156
+ const def = TinyInventory.getItem(existing.id);
157
+ const spaceLeft = def.maxStack - existing.quantity;
158
+ movedQty = Math.min(spaceLeft, transferItem.quantity);
159
+ if (movedQty > 0) {
160
+ this.#receiver.setItem({
161
+ slotIndex: receiverSlotIndex,
162
+ item: { ...existing, quantity: existing.quantity + movedQty },
163
+ forceSpace,
164
+ });
165
+ }
166
+ }
167
+ else {
168
+ // Empty Slot → just seal the whole item
169
+ this.#receiver.setItem({
170
+ slotIndex: receiverSlotIndex,
171
+ item: transferItem,
172
+ forceSpace,
173
+ });
174
+ }
175
+ // Now we calculate what's left
176
+ result = { remaining: transferItem.quantity - movedQty };
177
+ }
178
+ else {
179
+ result = this.#receiver.addItem({
180
+ itemId: transferItem.id,
181
+ quantity: transferItem.quantity,
182
+ metadata: transferItem.metadata,
183
+ forceSpace,
184
+ });
185
+ }
186
+ // Remove successfully transferred quantity from sender
187
+ const removedQty = transferItem.quantity - result.remaining;
188
+ if (removedQty > 0) {
189
+ if (specialSlot) {
190
+ this.#sender.unequipItem({ slotId: specialSlot, quantity: removedQty, forceSpace });
191
+ }
192
+ else if (typeof slotIndex === 'number') {
193
+ const remainingQty = item.quantity - removedQty;
194
+ this.#sender.setItem({
195
+ slotIndex,
196
+ item: remainingQty > 0 ? { ...item, quantity: remainingQty } : null,
197
+ forceSpace,
198
+ });
199
+ }
200
+ }
201
+ return result;
202
+ }
203
+ /**
204
+ * Transfers multiple items at once.
205
+ * @param {TransferItemCfg[]} items - Array of transfer configs (see transferItem options).
206
+ * @returns {Partial<AddItemResult>[]} Array of remaining quantities for each item.
207
+ */
208
+ transferMultiple(items) {
209
+ return items.map((cfg) => this.transferItem(cfg));
210
+ }
211
+ }
212
+ export default TinyInventoryTrader;
@@ -13,7 +13,6 @@ const customDecoders = new Map();
13
13
  const customTypesFreezed = new Set([
14
14
  'string',
15
15
  'boolean',
16
- 'number',
17
16
  'object',
18
17
  'array',
19
18
  String,
@@ -961,6 +960,20 @@ TinyLocalStorage.registerJsonType(
961
960
  true,
962
961
  );
963
962
 
963
+ // Number
964
+ TinyLocalStorage.registerJsonType(
965
+ 'number',
966
+ (value) => ({
967
+ __number__: true,
968
+ value: value.toString(),
969
+ }),
970
+ {
971
+ check: (value) => value.__number__,
972
+ decode: (value) => Number(value.value),
973
+ },
974
+ true,
975
+ );
976
+
964
977
  // Big Int
965
978
  TinyLocalStorage.registerJsonType(
966
979
  'bigint',
@@ -8,7 +8,6 @@ const customDecoders = new Map();
8
8
  const customTypesFreezed = new Set([
9
9
  'string',
10
10
  'boolean',
11
- 'number',
12
11
  'object',
13
12
  'array',
14
13
  String,
@@ -848,6 +847,14 @@ TinyLocalStorage.registerJsonType(RegExp, (value) => ({
848
847
  check: (value) => value.__regexp__,
849
848
  decode: (value) => new RegExp(value.source, value.flags),
850
849
  }, true);
850
+ // Number
851
+ TinyLocalStorage.registerJsonType('number', (value) => ({
852
+ __number__: true,
853
+ value: value.toString(),
854
+ }), {
855
+ check: (value) => value.__number__,
856
+ decode: (value) => Number(value.value),
857
+ }, true);
851
858
  // Big Int
852
859
  TinyLocalStorage.registerJsonType('bigint', (value) => ({
853
860
  __bigint__: true,
@@ -327,19 +327,6 @@ class TinyRateLimiter {
327
327
  this.groupTTL.delete(groupId);
328
328
  }
329
329
 
330
- /**
331
- * Manually reset user data.
332
- *
333
- * @deprecated Use `resetUserGroup(userId)` instead. This method will be removed in future versions.
334
- * @param {string} userId
335
- * @returns {void}
336
- */
337
- reset(userId) {
338
- if (process?.env?.NODE_ENV !== 'production')
339
- console.warn(`[TinyRateLimiter] 'reset()' is deprecated. Use 'resetUserGroup()' instead.`);
340
- return this.resetUserGroup(userId);
341
- }
342
-
343
330
  /**
344
331
  * Manually reset a user mapping
345
332
  * @param {string} userId
@@ -119,14 +119,6 @@ declare class TinyRateLimiter {
119
119
  * @param {string} groupId
120
120
  */
121
121
  resetGroup(groupId: string): void;
122
- /**
123
- * Manually reset user data.
124
- *
125
- * @deprecated Use `resetUserGroup(userId)` instead. This method will be removed in future versions.
126
- * @param {string} userId
127
- * @returns {void}
128
- */
129
- reset(userId: string): void;
130
122
  /**
131
123
  * Manually reset a user mapping
132
124
  * @param {string} userId
@@ -293,18 +293,6 @@ class TinyRateLimiter {
293
293
  this.lastSeen.delete(groupId);
294
294
  this.groupTTL.delete(groupId);
295
295
  }
296
- /**
297
- * Manually reset user data.
298
- *
299
- * @deprecated Use `resetUserGroup(userId)` instead. This method will be removed in future versions.
300
- * @param {string} userId
301
- * @returns {void}
302
- */
303
- reset(userId) {
304
- if (process?.env?.NODE_ENV !== 'production')
305
- console.warn(`[TinyRateLimiter] 'reset()' is deprecated. Use 'resetUserGroup()' instead.`);
306
- return this.resetUserGroup(userId);
307
- }
308
296
  /**
309
297
  * Manually reset a user mapping
310
298
  * @param {string} userId