@abdokouta/react-support 1.1.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/dist/index.mjs ADDED
@@ -0,0 +1,2385 @@
1
+ // src/str/str.ts
2
+ var Str = class _Str {
3
+ /**
4
+ * Return the remainder of a string after the first occurrence of a given value
5
+ */
6
+ static after(subject, search) {
7
+ if (search === "") return subject;
8
+ const index = subject.indexOf(search);
9
+ return index === -1 ? subject : subject.substring(index + search.length);
10
+ }
11
+ /**
12
+ * Return the remainder of a string after the last occurrence of a given value
13
+ */
14
+ static afterLast(subject, search) {
15
+ if (search === "") return subject;
16
+ const index = subject.lastIndexOf(search);
17
+ return index === -1 ? subject : subject.substring(index + search.length);
18
+ }
19
+ /**
20
+ * Convert a string to title case following APA guidelines
21
+ */
22
+ static apa(value) {
23
+ const minorWords = ["a", "an", "and", "as", "at", "but", "by", "for", "in", "of", "on", "or", "the", "to", "up"];
24
+ const words = value.split(" ");
25
+ return words.map((word, index) => {
26
+ if (index === 0 || !minorWords.includes(word.toLowerCase())) {
27
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
28
+ }
29
+ return word.toLowerCase();
30
+ }).join(" ");
31
+ }
32
+ /**
33
+ * Transliterate a UTF-8 value to ASCII
34
+ */
35
+ static ascii(value) {
36
+ return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
37
+ }
38
+ /**
39
+ * Get the portion of a string before the first occurrence of a given value
40
+ */
41
+ static before(subject, search) {
42
+ if (search === "") return subject;
43
+ const index = subject.indexOf(search);
44
+ return index === -1 ? subject : subject.substring(0, index);
45
+ }
46
+ /**
47
+ * Get the portion of a string before the last occurrence of a given value
48
+ */
49
+ static beforeLast(subject, search) {
50
+ if (search === "") return subject;
51
+ const index = subject.lastIndexOf(search);
52
+ return index === -1 ? subject : subject.substring(0, index);
53
+ }
54
+ /**
55
+ * Get the portion of a string between two values
56
+ */
57
+ static between(subject, from, to) {
58
+ if (from === "" || to === "") return subject;
59
+ const startIndex = subject.indexOf(from);
60
+ if (startIndex === -1) return "";
61
+ const start = startIndex + from.length;
62
+ const endIndex = subject.indexOf(to, start);
63
+ return endIndex === -1 ? "" : subject.substring(start, endIndex);
64
+ }
65
+ /**
66
+ * Get the smallest possible portion of a string between two values
67
+ */
68
+ static betweenFirst(subject, from, to) {
69
+ return _Str.between(subject, from, to);
70
+ }
71
+ /**
72
+ * Convert a string to camelCase
73
+ */
74
+ static camel(value) {
75
+ return value.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^(.)/, (char) => char.toLowerCase());
76
+ }
77
+ /**
78
+ * Get the character at the specified index
79
+ */
80
+ static charAt(subject, index) {
81
+ if (index < 0 || index >= subject.length) return false;
82
+ return subject.charAt(index);
83
+ }
84
+ /**
85
+ * Remove the first occurrence of the given value from the start of the string
86
+ */
87
+ static chopStart(subject, search) {
88
+ const searches = Array.isArray(search) ? search : [search];
89
+ for (const s of searches) {
90
+ if (subject.startsWith(s)) {
91
+ return subject.substring(s.length);
92
+ }
93
+ }
94
+ return subject;
95
+ }
96
+ /**
97
+ * Remove the last occurrence of the given value from the end of the string
98
+ */
99
+ static chopEnd(subject, search) {
100
+ const searches = Array.isArray(search) ? search : [search];
101
+ for (const s of searches) {
102
+ if (subject.endsWith(s)) {
103
+ return subject.substring(0, subject.length - s.length);
104
+ }
105
+ }
106
+ return subject;
107
+ }
108
+ /**
109
+ * Determine if a given string contains a given substring
110
+ */
111
+ static contains(haystack, needles, ignoreCase = false) {
112
+ const needleArray = Array.isArray(needles) ? needles : [needles];
113
+ const subject = ignoreCase ? haystack.toLowerCase() : haystack;
114
+ return needleArray.some((needle) => {
115
+ const search = ignoreCase ? needle.toLowerCase() : needle;
116
+ return subject.includes(search);
117
+ });
118
+ }
119
+ /**
120
+ * Determine if a given string contains all array values
121
+ */
122
+ static containsAll(haystack, needles, ignoreCase = false) {
123
+ const subject = ignoreCase ? haystack.toLowerCase() : haystack;
124
+ return needles.every((needle) => {
125
+ const search = ignoreCase ? needle.toLowerCase() : needle;
126
+ return subject.includes(search);
127
+ });
128
+ }
129
+ /**
130
+ * Determine if a given string doesn't contain a given substring
131
+ */
132
+ static doesntContain(haystack, needles, ignoreCase = false) {
133
+ return !_Str.contains(haystack, needles, ignoreCase);
134
+ }
135
+ /**
136
+ * Replace consecutive instances of a character with a single instance
137
+ */
138
+ static deduplicate(value, character = " ") {
139
+ const escaped = character.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
140
+ const regex = new RegExp(`${escaped}+`, "g");
141
+ return value.replace(regex, character);
142
+ }
143
+ /**
144
+ * Determine if a given string ends with a given substring
145
+ */
146
+ static endsWith(haystack, needles) {
147
+ const needleArray = Array.isArray(needles) ? needles : [needles];
148
+ return needleArray.some((needle) => haystack.endsWith(needle));
149
+ }
150
+ /**
151
+ * Extract an excerpt from text that matches the first instance of a phrase
152
+ */
153
+ static excerpt(text, phrase, options = {}) {
154
+ const radius = options.radius ?? 100;
155
+ const omission = options.omission ?? "...";
156
+ const index = text.indexOf(phrase);
157
+ if (index === -1) return "";
158
+ const start = Math.max(0, index - radius);
159
+ const end = Math.min(text.length, index + phrase.length + radius);
160
+ let excerpt = text.substring(start, end);
161
+ if (start > 0) excerpt = omission + excerpt;
162
+ if (end < text.length) excerpt = excerpt + omission;
163
+ return excerpt;
164
+ }
165
+ /**
166
+ * Cap a string with a single instance of a given value
167
+ */
168
+ static finish(value, cap) {
169
+ return value.endsWith(cap) ? value : value + cap;
170
+ }
171
+ /**
172
+ * Convert a string to headline case
173
+ */
174
+ static headline(value) {
175
+ return value.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[-_]/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
176
+ }
177
+ /**
178
+ * Determine if a given string matches a given pattern
179
+ */
180
+ static is(pattern, value, ignoreCase = false) {
181
+ const regexPattern = pattern.replace(/\*/g, ".*");
182
+ const flags = ignoreCase ? "i" : "";
183
+ const regex = new RegExp(`^${regexPattern}$`, flags);
184
+ return regex.test(value);
185
+ }
186
+ /**
187
+ * Determine if a given string is 7-bit ASCII
188
+ */
189
+ static isAscii(value) {
190
+ return /^[\x00-\x7F]*$/.test(value);
191
+ }
192
+ /**
193
+ * Determine if a given string is valid JSON
194
+ */
195
+ static isJson(value) {
196
+ try {
197
+ JSON.parse(value);
198
+ return true;
199
+ } catch {
200
+ return false;
201
+ }
202
+ }
203
+ /**
204
+ * Determine if a given string is a valid URL
205
+ */
206
+ static isUrl(value, protocols) {
207
+ try {
208
+ if (typeof URL === "undefined") {
209
+ const urlPattern = /^https?:\/\/.+/i;
210
+ return urlPattern.test(value);
211
+ }
212
+ const urlObj = new URL(value);
213
+ if (protocols) {
214
+ return protocols.includes(urlObj.protocol.replace(":", ""));
215
+ }
216
+ return true;
217
+ } catch {
218
+ return false;
219
+ }
220
+ }
221
+ /**
222
+ * Determine if a given string is a valid ULID
223
+ */
224
+ static isUlid(value) {
225
+ return /^[0-9A-HJKMNP-TV-Z]{26}$/i.test(value);
226
+ }
227
+ /**
228
+ * Determine if a given string is a valid UUID
229
+ */
230
+ static isUuid(value) {
231
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
232
+ }
233
+ /**
234
+ * Convert a string to kebab-case
235
+ */
236
+ static kebab(value) {
237
+ return value.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
238
+ }
239
+ /**
240
+ * Return the given string with the first character lowercased
241
+ */
242
+ static lcfirst(value) {
243
+ return value.charAt(0).toLowerCase() + value.slice(1);
244
+ }
245
+ /**
246
+ * Return the length of the given string
247
+ */
248
+ static len(value) {
249
+ return value.length;
250
+ }
251
+ /**
252
+ * Limit the number of characters in a string
253
+ */
254
+ static limit(value, limit = 100, end = "...", preserveWords = false) {
255
+ if (value.length <= limit) return value;
256
+ let truncated = value.substring(0, limit);
257
+ if (preserveWords) {
258
+ const lastSpace = truncated.lastIndexOf(" ");
259
+ if (lastSpace > 0) {
260
+ truncated = truncated.substring(0, lastSpace);
261
+ }
262
+ }
263
+ return truncated + end;
264
+ }
265
+ /**
266
+ * Convert the given string to lowercase
267
+ */
268
+ static lower(value) {
269
+ return value.toLowerCase();
270
+ }
271
+ /**
272
+ * Masks a portion of a string with a repeated character
273
+ */
274
+ static mask(value, character, index, length) {
275
+ if (index < 0) {
276
+ index = value.length + index;
277
+ }
278
+ const maskLength = length ?? value.length - index;
279
+ const mask = character.repeat(Math.abs(maskLength));
280
+ return value.substring(0, index) + mask + value.substring(index + Math.abs(maskLength));
281
+ }
282
+ /**
283
+ * Pad both sides of a string with another
284
+ */
285
+ static padBoth(value, length, pad = " ") {
286
+ const totalPadding = length - value.length;
287
+ if (totalPadding <= 0) return value;
288
+ const leftPadding = Math.floor(totalPadding / 2);
289
+ const rightPadding = totalPadding - leftPadding;
290
+ return pad.repeat(leftPadding) + value + pad.repeat(rightPadding);
291
+ }
292
+ /**
293
+ * Pad the left side of a string with another
294
+ */
295
+ static padLeft(value, length, pad = " ") {
296
+ return value.padStart(length, pad);
297
+ }
298
+ /**
299
+ * Pad the right side of a string with another
300
+ */
301
+ static padRight(value, length, pad = " ") {
302
+ return value.padEnd(length, pad);
303
+ }
304
+ /**
305
+ * Get the plural form of an English word
306
+ */
307
+ static plural(value, count = 2) {
308
+ if (count === 1) return value;
309
+ if (value.endsWith("y") && !/[aeiou]y$/i.test(value)) {
310
+ return value.slice(0, -1) + "ies";
311
+ }
312
+ if (value.endsWith("s") || value.endsWith("x") || value.endsWith("z") || value.endsWith("ch") || value.endsWith("sh")) {
313
+ return value + "es";
314
+ }
315
+ return value + "s";
316
+ }
317
+ /**
318
+ * Pluralize the last word of an English, studly caps case string
319
+ */
320
+ static pluralStudly(value, count = 2) {
321
+ const parts = value.match(/[A-Z][a-z]*/g) || [value];
322
+ const lastWord = parts[parts.length - 1];
323
+ const pluralized = _Str.plural(lastWord, count);
324
+ parts[parts.length - 1] = pluralized;
325
+ return parts.join("");
326
+ }
327
+ /**
328
+ * Find the position of the first occurrence of a substring
329
+ */
330
+ static position(haystack, needle) {
331
+ const pos = haystack.indexOf(needle);
332
+ return pos === -1 ? false : pos;
333
+ }
334
+ /**
335
+ * Generate a random string
336
+ */
337
+ static random(length = 16) {
338
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
339
+ let result = "";
340
+ for (let i = 0; i < length; i++) {
341
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
342
+ }
343
+ return result;
344
+ }
345
+ /**
346
+ * Remove the given value from the string
347
+ */
348
+ static remove(search, subject, caseSensitive = true) {
349
+ const searches = Array.isArray(search) ? search : [search];
350
+ let result = subject;
351
+ searches.forEach((s) => {
352
+ const flags = caseSensitive ? "g" : "gi";
353
+ const escaped = s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
354
+ result = result.replace(new RegExp(escaped, flags), "");
355
+ });
356
+ return result;
357
+ }
358
+ /**
359
+ * Repeat the given string
360
+ */
361
+ static repeat(value, times) {
362
+ return value.repeat(times);
363
+ }
364
+ /**
365
+ * Replace the given value in the given string
366
+ */
367
+ static replace(search, replace, subject, caseSensitive = true) {
368
+ const flags = caseSensitive ? "g" : "gi";
369
+ const escaped = search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
370
+ return subject.replace(new RegExp(escaped, flags), replace);
371
+ }
372
+ /**
373
+ * Replace a given value in the string sequentially with an array
374
+ */
375
+ static replaceArray(search, replacements, subject) {
376
+ let result = subject;
377
+ let index = 0;
378
+ while (result.includes(search) && index < replacements.length) {
379
+ result = result.replace(search, replacements[index]);
380
+ index++;
381
+ }
382
+ return result;
383
+ }
384
+ /**
385
+ * Replace the first occurrence of a given value in the string
386
+ */
387
+ static replaceFirst(search, replace, subject) {
388
+ return subject.replace(search, replace);
389
+ }
390
+ /**
391
+ * Replace the last occurrence of a given value in the string
392
+ */
393
+ static replaceLast(search, replace, subject) {
394
+ const index = subject.lastIndexOf(search);
395
+ if (index === -1) return subject;
396
+ return subject.substring(0, index) + replace + subject.substring(index + search.length);
397
+ }
398
+ /**
399
+ * Replace the first occurrence only if it appears at the start
400
+ */
401
+ static replaceStart(search, replace, subject) {
402
+ return subject.startsWith(search) ? replace + subject.substring(search.length) : subject;
403
+ }
404
+ /**
405
+ * Replace the last occurrence only if it appears at the end
406
+ */
407
+ static replaceEnd(search, replace, subject) {
408
+ return subject.endsWith(search) ? subject.substring(0, subject.length - search.length) + replace : subject;
409
+ }
410
+ /**
411
+ * Reverse the given string
412
+ */
413
+ static reverse(value) {
414
+ return value.split("").reverse().join("");
415
+ }
416
+ /**
417
+ * Get the singular form of an English word
418
+ */
419
+ static singular(value) {
420
+ if (value.endsWith("ies")) {
421
+ return value.slice(0, -3) + "y";
422
+ }
423
+ if (value.endsWith("es")) {
424
+ return value.slice(0, -2);
425
+ }
426
+ if (value.endsWith("s") && !value.endsWith("ss")) {
427
+ return value.slice(0, -1);
428
+ }
429
+ return value;
430
+ }
431
+ /**
432
+ * Generate a URL friendly slug
433
+ */
434
+ static slug(value, separator = "-") {
435
+ return value.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_]+/g, separator).replace(new RegExp(`${separator}+`, "g"), separator).replace(new RegExp(`^${separator}|${separator}$`, "g"), "");
436
+ }
437
+ /**
438
+ * Convert a string to snake_case
439
+ */
440
+ static snake(value, delimiter = "_") {
441
+ return value.replace(/([a-z])([A-Z])/g, `$1${delimiter}$2`).replace(/[\s-]+/g, delimiter).toLowerCase();
442
+ }
443
+ /**
444
+ * Remove all extraneous whitespace
445
+ */
446
+ static squish(value) {
447
+ return value.trim().replace(/\s+/g, " ");
448
+ }
449
+ /**
450
+ * Begin a string with a single instance of a given value
451
+ */
452
+ static start(value, prefix) {
453
+ return value.startsWith(prefix) ? value : prefix + value;
454
+ }
455
+ /**
456
+ * Determine if a given string starts with a given substring
457
+ */
458
+ static startsWith(haystack, needles) {
459
+ const needleArray = Array.isArray(needles) ? needles : [needles];
460
+ return needleArray.some((needle) => haystack.startsWith(needle));
461
+ }
462
+ /**
463
+ * Convert a value to studly caps case
464
+ */
465
+ static studly(value) {
466
+ return value.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^(.)/, (char) => char.toUpperCase());
467
+ }
468
+ /**
469
+ * Returns the portion of string specified by the start and length parameters
470
+ */
471
+ static substr(value, start, length) {
472
+ return value.substr(start, length);
473
+ }
474
+ /**
475
+ * Returns the number of substring occurrences
476
+ */
477
+ static substrCount(haystack, needle) {
478
+ return (haystack.match(new RegExp(needle, "g")) || []).length;
479
+ }
480
+ /**
481
+ * Replace text within a portion of a string
482
+ */
483
+ static substrReplace(value, replace, start, length) {
484
+ const actualLength = length ?? value.length - start;
485
+ return value.substring(0, start) + replace + value.substring(start + actualLength);
486
+ }
487
+ /**
488
+ * Swap multiple keywords in a string with other keywords
489
+ */
490
+ static swap(map, subject) {
491
+ let result = subject;
492
+ Object.entries(map).forEach(([search, replace]) => {
493
+ result = _Str.replace(search, replace, result);
494
+ });
495
+ return result;
496
+ }
497
+ /**
498
+ * Take the first or last {limit} characters
499
+ */
500
+ static take(value, limit) {
501
+ if (limit < 0) {
502
+ return value.slice(limit);
503
+ }
504
+ return value.slice(0, limit);
505
+ }
506
+ /**
507
+ * Convert the given string to title case
508
+ */
509
+ static title(value) {
510
+ return value.toLowerCase().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
511
+ }
512
+ /**
513
+ * Convert the given string to Base64
514
+ */
515
+ static toBase64(value) {
516
+ if (typeof Buffer !== "undefined") {
517
+ return Buffer.from(value).toString("base64");
518
+ }
519
+ if (typeof btoa !== "undefined") {
520
+ return btoa(value);
521
+ }
522
+ throw new Error("Base64 encoding not supported in this environment");
523
+ }
524
+ /**
525
+ * Transliterate a string to its closest ASCII representation
526
+ */
527
+ static transliterate(value) {
528
+ return _Str.ascii(value);
529
+ }
530
+ /**
531
+ * Trim whitespace from both ends of the string
532
+ */
533
+ static trim(value, characters) {
534
+ if (!characters) return value.trim();
535
+ const escaped = characters.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
536
+ return value.replace(new RegExp(`^[${escaped}]+|[${escaped}]+$`, "g"), "");
537
+ }
538
+ /**
539
+ * Trim whitespace from the beginning of the string
540
+ */
541
+ static ltrim(value, characters) {
542
+ if (!characters) return value.trimStart();
543
+ const escaped = characters.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
544
+ return value.replace(new RegExp(`^[${escaped}]+`, "g"), "");
545
+ }
546
+ /**
547
+ * Trim whitespace from the end of the string
548
+ */
549
+ static rtrim(value, characters) {
550
+ if (!characters) return value.trimEnd();
551
+ const escaped = characters.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
552
+ return value.replace(new RegExp(`[${escaped}]+$`, "g"), "");
553
+ }
554
+ /**
555
+ * Make a string's first character uppercase
556
+ */
557
+ static ucfirst(value) {
558
+ return value.charAt(0).toUpperCase() + value.slice(1);
559
+ }
560
+ /**
561
+ * Split a string by uppercase characters
562
+ */
563
+ static ucsplit(value) {
564
+ return value.match(/[A-Z][a-z]*/g) || [value];
565
+ }
566
+ /**
567
+ * Convert the given string to uppercase
568
+ */
569
+ static upper(value) {
570
+ return value.toUpperCase();
571
+ }
572
+ /**
573
+ * Remove the specified strings from the beginning and end
574
+ */
575
+ static unwrap(value, before, after) {
576
+ const actualAfter = after ?? before;
577
+ let result = value;
578
+ if (result.startsWith(before)) {
579
+ result = result.substring(before.length);
580
+ }
581
+ if (result.endsWith(actualAfter)) {
582
+ result = result.substring(0, result.length - actualAfter.length);
583
+ }
584
+ return result;
585
+ }
586
+ /**
587
+ * Get the number of words a string contains
588
+ */
589
+ static wordCount(value) {
590
+ return value.trim().split(/\s+/).filter((word) => word.length > 0).length;
591
+ }
592
+ /**
593
+ * Wrap a string to a given number of characters
594
+ */
595
+ static wordWrap(value, characters = 75, breakStr = "\n") {
596
+ const words = value.split(" ");
597
+ let line = "";
598
+ const lines = [];
599
+ words.forEach((word) => {
600
+ if ((line + word).length > characters) {
601
+ if (line) lines.push(line.trim());
602
+ line = word + " ";
603
+ } else {
604
+ line += word + " ";
605
+ }
606
+ });
607
+ if (line) lines.push(line.trim());
608
+ return lines.join(breakStr);
609
+ }
610
+ /**
611
+ * Limit the number of words in a string
612
+ */
613
+ static words(value, words = 100, end = "...") {
614
+ const wordArray = value.split(/\s+/);
615
+ if (wordArray.length <= words) return value;
616
+ return wordArray.slice(0, words).join(" ") + end;
617
+ }
618
+ /**
619
+ * Wrap the string with the given strings
620
+ */
621
+ static wrap(value, before, after) {
622
+ const actualAfter = after ?? before;
623
+ return before + value + actualAfter;
624
+ }
625
+ };
626
+
627
+ // src/collections/collection.ts
628
+ import collectJs from "collect.js";
629
+ var Collection = class _Collection {
630
+ constructor(items = []) {
631
+ this.collection = collectJs(items);
632
+ }
633
+ /**
634
+ * Create a new collection instance
635
+ */
636
+ static make(items = []) {
637
+ return new _Collection(items);
638
+ }
639
+ /**
640
+ * Get all items in the collection
641
+ */
642
+ all() {
643
+ return this.collection.all();
644
+ }
645
+ /**
646
+ * Get the average value of a given key
647
+ */
648
+ avg(key) {
649
+ return this.collection.avg(key);
650
+ }
651
+ /**
652
+ * Chunk the collection into chunks of the given size
653
+ */
654
+ chunk(size) {
655
+ return new _Collection(this.collection.chunk(size).all());
656
+ }
657
+ /**
658
+ * Collapse a collection of arrays into a single, flat collection
659
+ */
660
+ collapse() {
661
+ return new _Collection(this.collection.collapse().all());
662
+ }
663
+ /**
664
+ * Determine if an item exists in the collection
665
+ */
666
+ contains(key, value) {
667
+ return this.collection.contains(key, value);
668
+ }
669
+ /**
670
+ * Get the total number of items in the collection
671
+ */
672
+ count() {
673
+ return this.collection.count();
674
+ }
675
+ /**
676
+ * Get the items in the collection that are not present in the given items
677
+ */
678
+ diff(items) {
679
+ return new _Collection(this.collection.diff(items).all());
680
+ }
681
+ /**
682
+ * Execute a callback over each item
683
+ */
684
+ each(callback) {
685
+ this.collection.each(callback);
686
+ return this;
687
+ }
688
+ /**
689
+ * Determine if all items pass the given test
690
+ */
691
+ every(callback) {
692
+ return this.collection.every(callback);
693
+ }
694
+ /**
695
+ * Get all items except for those with the specified keys
696
+ */
697
+ except(keys) {
698
+ return new _Collection(this.collection.except(keys).all());
699
+ }
700
+ /**
701
+ * Run a filter over each of the items
702
+ */
703
+ filter(callback) {
704
+ return new _Collection(this.collection.filter(callback).all());
705
+ }
706
+ /**
707
+ * Get the first item from the collection
708
+ */
709
+ first(callback) {
710
+ return this.collection.first(callback);
711
+ }
712
+ /**
713
+ * Get a flattened array of the items in the collection
714
+ */
715
+ flatten(depth) {
716
+ return new _Collection(this.collection.flatten(depth).all());
717
+ }
718
+ /**
719
+ * Flip the items in the collection
720
+ */
721
+ flip() {
722
+ return new _Collection(this.collection.flip().all());
723
+ }
724
+ /**
725
+ * Remove an item from the collection by key
726
+ */
727
+ forget(key) {
728
+ this.collection.forget(key);
729
+ return this;
730
+ }
731
+ /**
732
+ * Get an item from the collection by key
733
+ */
734
+ get(key, defaultValue) {
735
+ const result = this.collection.get(key, defaultValue);
736
+ return result === null ? void 0 : result;
737
+ }
738
+ /**
739
+ * Group the collection's items by a given key
740
+ */
741
+ groupBy(key) {
742
+ const grouped = this.collection.groupBy(key);
743
+ const result = {};
744
+ grouped.each((items, groupKey) => {
745
+ result[groupKey] = new _Collection(items.all());
746
+ });
747
+ return new _Collection(Object.values(result));
748
+ }
749
+ /**
750
+ * Determine if a given key exists in the collection
751
+ */
752
+ has(key) {
753
+ return this.collection.has(key);
754
+ }
755
+ /**
756
+ * Concatenate values of a given key as a string
757
+ */
758
+ implode(key, glue) {
759
+ return this.collection.implode(key, glue);
760
+ }
761
+ /**
762
+ * Intersect the collection with the given items
763
+ */
764
+ intersect(items) {
765
+ return new _Collection(this.collection.intersect(items).all());
766
+ }
767
+ /**
768
+ * Determine if the collection is empty
769
+ */
770
+ isEmpty() {
771
+ return this.collection.isEmpty();
772
+ }
773
+ /**
774
+ * Determine if the collection is not empty
775
+ */
776
+ isNotEmpty() {
777
+ return this.collection.isNotEmpty();
778
+ }
779
+ /**
780
+ * Join all items from the collection using a string
781
+ */
782
+ join(glue, finalGlue) {
783
+ return this.collection.join(glue, finalGlue);
784
+ }
785
+ /**
786
+ * Key the collection by the given key
787
+ */
788
+ keyBy(key) {
789
+ return new _Collection(this.collection.keyBy(key).all());
790
+ }
791
+ /**
792
+ * Get the keys of the collection items
793
+ */
794
+ keys() {
795
+ return new _Collection(this.collection.keys().all());
796
+ }
797
+ /**
798
+ * Get the last item from the collection
799
+ */
800
+ last(callback) {
801
+ return this.collection.last(callback);
802
+ }
803
+ /**
804
+ * Run a map over each of the items
805
+ */
806
+ map(callback) {
807
+ return new _Collection(this.collection.map(callback).all());
808
+ }
809
+ /**
810
+ * Get the max value of a given key
811
+ */
812
+ max(key) {
813
+ return this.collection.max(key);
814
+ }
815
+ /**
816
+ * Merge the collection with the given items
817
+ */
818
+ merge(items) {
819
+ return new _Collection(this.collection.merge(items).all());
820
+ }
821
+ /**
822
+ * Get the min value of a given key
823
+ */
824
+ min(key) {
825
+ return this.collection.min(key);
826
+ }
827
+ /**
828
+ * Get the items with the specified keys
829
+ */
830
+ only(keys) {
831
+ return new _Collection(this.collection.only(keys).all());
832
+ }
833
+ /**
834
+ * Get and remove the last item from the collection
835
+ */
836
+ pop() {
837
+ return this.collection.pop();
838
+ }
839
+ /**
840
+ * Push an item onto the beginning of the collection
841
+ */
842
+ prepend(value) {
843
+ this.collection.prepend(value);
844
+ return this;
845
+ }
846
+ /**
847
+ * Get and remove an item from the collection
848
+ */
849
+ pull(key) {
850
+ const result = this.collection.pull(key);
851
+ return result === null ? void 0 : result;
852
+ }
853
+ /**
854
+ * Push an item onto the end of the collection
855
+ */
856
+ push(value) {
857
+ this.collection.push(value);
858
+ return this;
859
+ }
860
+ /**
861
+ * Put an item in the collection by key
862
+ */
863
+ put(key, value) {
864
+ this.collection.put(key, value);
865
+ return this;
866
+ }
867
+ /**
868
+ * Get one or a specified number of items randomly from the collection
869
+ */
870
+ random(count) {
871
+ if (count) {
872
+ const result = this.collection.random(count);
873
+ return new _Collection(result.all());
874
+ }
875
+ return this.collection.random();
876
+ }
877
+ /**
878
+ * Reduce the collection to a single value
879
+ */
880
+ reduce(callback, initial) {
881
+ return this.collection.reduce(callback, initial);
882
+ }
883
+ /**
884
+ * Filter items by the given key value pair
885
+ */
886
+ reject(callback) {
887
+ return new _Collection(this.collection.reject(callback).all());
888
+ }
889
+ /**
890
+ * Reverse items order
891
+ */
892
+ reverse() {
893
+ return new _Collection(this.collection.reverse().all());
894
+ }
895
+ /**
896
+ * Search the collection for a given value
897
+ */
898
+ search(value) {
899
+ const result = this.collection.search(value);
900
+ return result === false ? false : result;
901
+ }
902
+ /**
903
+ * Get and remove the first item from the collection
904
+ */
905
+ shift() {
906
+ return this.collection.shift();
907
+ }
908
+ /**
909
+ * Shuffle the items in the collection
910
+ */
911
+ shuffle() {
912
+ return new _Collection(this.collection.shuffle().all());
913
+ }
914
+ /**
915
+ * Slice the underlying collection array
916
+ */
917
+ slice(start, length) {
918
+ return new _Collection(this.collection.slice(start, length).all());
919
+ }
920
+ /**
921
+ * Sort through each item with a callback
922
+ */
923
+ sort(callback) {
924
+ return new _Collection(this.collection.sort(callback).all());
925
+ }
926
+ /**
927
+ * Sort the collection by the given key
928
+ */
929
+ sortBy(key) {
930
+ return new _Collection(this.collection.sortBy(key).all());
931
+ }
932
+ /**
933
+ * Sort the collection in descending order by the given key
934
+ */
935
+ sortByDesc(key) {
936
+ return new _Collection(this.collection.sortByDesc(key).all());
937
+ }
938
+ /**
939
+ * Splice a portion of the underlying collection array
940
+ */
941
+ splice(start, length, ...items) {
942
+ const actualLength = length ?? 0;
943
+ const itemsArray = items;
944
+ return new _Collection(this.collection.splice(start, actualLength, ...itemsArray).all());
945
+ }
946
+ /**
947
+ * Get the sum of the given values
948
+ */
949
+ sum(key) {
950
+ const result = this.collection.sum(key);
951
+ return typeof result === "number" ? result : 0;
952
+ }
953
+ /**
954
+ * Take the first or last {limit} items
955
+ */
956
+ take(limit) {
957
+ return new _Collection(this.collection.take(limit).all());
958
+ }
959
+ /**
960
+ * Pass the collection to the given callback and return the result
961
+ */
962
+ pipe(callback) {
963
+ return callback(this);
964
+ }
965
+ /**
966
+ * Pass the collection to the given callback and then return it
967
+ */
968
+ tap(callback) {
969
+ callback(this);
970
+ return this;
971
+ }
972
+ /**
973
+ * Transform each item in the collection using a callback
974
+ */
975
+ transform(callback) {
976
+ this.collection = this.collection.map(callback);
977
+ return this;
978
+ }
979
+ /**
980
+ * Return only unique items from the collection array
981
+ */
982
+ unique(key) {
983
+ return new _Collection(this.collection.unique(key).all());
984
+ }
985
+ /**
986
+ * Reset the keys on the underlying array
987
+ */
988
+ values() {
989
+ return new _Collection(this.collection.values().all());
990
+ }
991
+ where(key, operatorOrValue, value) {
992
+ if (value === void 0) {
993
+ return new _Collection(this.collection.where(key, operatorOrValue).all());
994
+ }
995
+ return new _Collection(this.collection.where(key, operatorOrValue, value).all());
996
+ }
997
+ /**
998
+ * Filter items by the given key value pair using loose comparison
999
+ */
1000
+ whereIn(key, values) {
1001
+ return new _Collection(this.collection.whereIn(key, values).all());
1002
+ }
1003
+ /**
1004
+ * Filter items by the given key value pair using loose comparison
1005
+ */
1006
+ whereNotIn(key, values) {
1007
+ return new _Collection(this.collection.whereNotIn(key, values).all());
1008
+ }
1009
+ /**
1010
+ * Zip the collection together with one or more arrays
1011
+ */
1012
+ zip(...arrays) {
1013
+ const zipArgs = arrays;
1014
+ return new _Collection(this.collection.zip(...zipArgs).all());
1015
+ }
1016
+ /**
1017
+ * Convert the collection to a plain array
1018
+ */
1019
+ toArray() {
1020
+ return this.all();
1021
+ }
1022
+ /**
1023
+ * Convert the collection to JSON
1024
+ */
1025
+ toJson() {
1026
+ return JSON.stringify(this.all());
1027
+ }
1028
+ /**
1029
+ * Get the collection as a string
1030
+ */
1031
+ toString() {
1032
+ return this.toJson();
1033
+ }
1034
+ };
1035
+ function collect(items = []) {
1036
+ return new Collection(items);
1037
+ }
1038
+
1039
+ // src/collections/map.collection.ts
1040
+ var MapCollection = class _MapCollection {
1041
+ constructor(entries) {
1042
+ if (entries && typeof entries === "object" && !(Symbol.iterator in entries)) {
1043
+ this.internalMap = new Map(Object.entries(entries));
1044
+ } else {
1045
+ this.internalMap = new Map(entries);
1046
+ }
1047
+ }
1048
+ /**
1049
+ * Create a new map collection instance
1050
+ */
1051
+ static make(entries) {
1052
+ return new _MapCollection(entries);
1053
+ }
1054
+ /**
1055
+ * Get all entries as an array of [key, value] pairs
1056
+ */
1057
+ all() {
1058
+ return Array.from(this.internalMap.entries());
1059
+ }
1060
+ /**
1061
+ * Get the number of items in the map
1062
+ */
1063
+ count() {
1064
+ return this.internalMap.size;
1065
+ }
1066
+ /**
1067
+ * Get the number of items in the map (alias for count)
1068
+ */
1069
+ size() {
1070
+ return this.internalMap.size;
1071
+ }
1072
+ /**
1073
+ * Determine if the map is empty
1074
+ */
1075
+ isEmpty() {
1076
+ return this.internalMap.size === 0;
1077
+ }
1078
+ /**
1079
+ * Determine if the map is not empty
1080
+ */
1081
+ isNotEmpty() {
1082
+ return this.internalMap.size > 0;
1083
+ }
1084
+ /**
1085
+ * Determine if a key exists in the map
1086
+ */
1087
+ has(key) {
1088
+ return this.internalMap.has(key);
1089
+ }
1090
+ /**
1091
+ * Get a value from the map by key
1092
+ */
1093
+ get(key, defaultValue) {
1094
+ return this.internalMap.has(key) ? this.internalMap.get(key) : defaultValue;
1095
+ }
1096
+ /**
1097
+ * Set a value in the map
1098
+ */
1099
+ set(key, value) {
1100
+ this.internalMap.set(key, value);
1101
+ return this;
1102
+ }
1103
+ /**
1104
+ * Put a value in the map (alias for set)
1105
+ */
1106
+ put(key, value) {
1107
+ return this.set(key, value);
1108
+ }
1109
+ /**
1110
+ * Remove a key from the map
1111
+ */
1112
+ delete(key) {
1113
+ return this.internalMap.delete(key);
1114
+ }
1115
+ /**
1116
+ * Remove a key from the map (alias for delete)
1117
+ */
1118
+ forget(key) {
1119
+ return this.delete(key);
1120
+ }
1121
+ /**
1122
+ * Remove all items from the map
1123
+ */
1124
+ clear() {
1125
+ this.internalMap.clear();
1126
+ return this;
1127
+ }
1128
+ /**
1129
+ * Get all keys from the map
1130
+ */
1131
+ keys() {
1132
+ return Array.from(this.internalMap.keys());
1133
+ }
1134
+ /**
1135
+ * Get all values from the map
1136
+ */
1137
+ values() {
1138
+ return Array.from(this.internalMap.values());
1139
+ }
1140
+ /**
1141
+ * Execute a callback over each item
1142
+ */
1143
+ each(callback) {
1144
+ for (const [key, value] of this.internalMap) {
1145
+ if (callback(value, key) === false) {
1146
+ break;
1147
+ }
1148
+ }
1149
+ return this;
1150
+ }
1151
+ /**
1152
+ * Run a map over each of the items
1153
+ */
1154
+ mapValues(callback) {
1155
+ const result = /* @__PURE__ */ new Map();
1156
+ this.internalMap.forEach((value, key) => {
1157
+ result.set(key, callback(value, key));
1158
+ });
1159
+ return new _MapCollection(result);
1160
+ }
1161
+ /**
1162
+ * Run a filter over each of the items
1163
+ */
1164
+ filter(callback) {
1165
+ const result = /* @__PURE__ */ new Map();
1166
+ this.internalMap.forEach((value, key) => {
1167
+ if (callback(value, key)) {
1168
+ result.set(key, value);
1169
+ }
1170
+ });
1171
+ return new _MapCollection(result);
1172
+ }
1173
+ /**
1174
+ * Determine if all items pass the given test
1175
+ */
1176
+ every(callback) {
1177
+ for (const [key, value] of this.internalMap) {
1178
+ if (!callback(value, key)) {
1179
+ return false;
1180
+ }
1181
+ }
1182
+ return true;
1183
+ }
1184
+ /**
1185
+ * Determine if any item passes the given test
1186
+ */
1187
+ some(callback) {
1188
+ for (const [key, value] of this.internalMap) {
1189
+ if (callback(value, key)) {
1190
+ return true;
1191
+ }
1192
+ }
1193
+ return false;
1194
+ }
1195
+ /**
1196
+ * Get the first value that passes the given test
1197
+ */
1198
+ first(callback) {
1199
+ if (!callback) {
1200
+ return this.internalMap.values().next().value;
1201
+ }
1202
+ for (const [key, value] of this.internalMap) {
1203
+ if (callback(value, key)) {
1204
+ return value;
1205
+ }
1206
+ }
1207
+ return void 0;
1208
+ }
1209
+ /**
1210
+ * Get the last value that passes the given test
1211
+ */
1212
+ last(callback) {
1213
+ const entries = Array.from(this.internalMap.entries()).reverse();
1214
+ if (!callback) {
1215
+ return entries[0]?.[1];
1216
+ }
1217
+ for (const [key, value] of entries) {
1218
+ if (callback(value, key)) {
1219
+ return value;
1220
+ }
1221
+ }
1222
+ return void 0;
1223
+ }
1224
+ /**
1225
+ * Reduce the map to a single value
1226
+ */
1227
+ reduce(callback, initial) {
1228
+ let carry = initial;
1229
+ this.internalMap.forEach((value, key) => {
1230
+ carry = callback(carry, value, key);
1231
+ });
1232
+ return carry;
1233
+ }
1234
+ /**
1235
+ * Merge another map into this one
1236
+ */
1237
+ merge(other) {
1238
+ if (other instanceof _MapCollection) {
1239
+ other.each((value, key) => {
1240
+ this.set(key, value);
1241
+ return void 0;
1242
+ });
1243
+ } else if (other instanceof Map) {
1244
+ other.forEach((value, key) => this.set(key, value));
1245
+ } else {
1246
+ Object.entries(other).forEach(([key, value]) => {
1247
+ this.set(key, value);
1248
+ });
1249
+ }
1250
+ return this;
1251
+ }
1252
+ /**
1253
+ * Get only the specified keys
1254
+ */
1255
+ only(keys) {
1256
+ const result = /* @__PURE__ */ new Map();
1257
+ keys.forEach((key) => {
1258
+ if (this.internalMap.has(key)) {
1259
+ result.set(key, this.internalMap.get(key));
1260
+ }
1261
+ });
1262
+ return new _MapCollection(result);
1263
+ }
1264
+ /**
1265
+ * Get all items except the specified keys
1266
+ */
1267
+ except(keys) {
1268
+ const result = /* @__PURE__ */ new Map();
1269
+ this.internalMap.forEach((value, key) => {
1270
+ if (!keys.includes(key)) {
1271
+ result.set(key, value);
1272
+ }
1273
+ });
1274
+ return new _MapCollection(result);
1275
+ }
1276
+ /**
1277
+ * Flip the keys and values
1278
+ */
1279
+ flip() {
1280
+ const result = /* @__PURE__ */ new Map();
1281
+ this.internalMap.forEach((value, key) => {
1282
+ result.set(value, key);
1283
+ });
1284
+ return new _MapCollection(result);
1285
+ }
1286
+ /**
1287
+ * Pass the map to the given callback and return the result
1288
+ */
1289
+ pipe(callback) {
1290
+ return callback(this);
1291
+ }
1292
+ /**
1293
+ * Pass the map to the given callback and then return it
1294
+ */
1295
+ tap(callback) {
1296
+ callback(this);
1297
+ return this;
1298
+ }
1299
+ /**
1300
+ * Convert the map to a plain object
1301
+ */
1302
+ toObject() {
1303
+ const obj = {};
1304
+ this.internalMap.forEach((value, key) => {
1305
+ obj[String(key)] = value;
1306
+ });
1307
+ return obj;
1308
+ }
1309
+ /**
1310
+ * Convert the map to an array of [key, value] pairs
1311
+ */
1312
+ toArray() {
1313
+ return this.all();
1314
+ }
1315
+ /**
1316
+ * Convert the map to JSON
1317
+ */
1318
+ toJson() {
1319
+ return JSON.stringify(this.toObject());
1320
+ }
1321
+ /**
1322
+ * Get the map as a string
1323
+ */
1324
+ toString() {
1325
+ return this.toJson();
1326
+ }
1327
+ /**
1328
+ * Get the underlying Map instance
1329
+ */
1330
+ toMap() {
1331
+ return new Map(this.internalMap);
1332
+ }
1333
+ };
1334
+ function collectMap(entries) {
1335
+ return new MapCollection(entries);
1336
+ }
1337
+
1338
+ // src/collections/set.collection.ts
1339
+ var SetCollection = class _SetCollection {
1340
+ constructor(items) {
1341
+ this.set = new Set(items);
1342
+ }
1343
+ /**
1344
+ * Create a new set collection instance
1345
+ */
1346
+ static make(items) {
1347
+ return new _SetCollection(items);
1348
+ }
1349
+ /**
1350
+ * Get all items as an array
1351
+ */
1352
+ all() {
1353
+ return Array.from(this.set);
1354
+ }
1355
+ /**
1356
+ * Get the number of items in the set
1357
+ */
1358
+ count() {
1359
+ return this.set.size;
1360
+ }
1361
+ /**
1362
+ * Get the number of items in the set (alias for count)
1363
+ */
1364
+ size() {
1365
+ return this.set.size;
1366
+ }
1367
+ /**
1368
+ * Determine if the set is empty
1369
+ */
1370
+ isEmpty() {
1371
+ return this.set.size === 0;
1372
+ }
1373
+ /**
1374
+ * Determine if the set is not empty
1375
+ */
1376
+ isNotEmpty() {
1377
+ return this.set.size > 0;
1378
+ }
1379
+ /**
1380
+ * Determine if an item exists in the set
1381
+ */
1382
+ has(item) {
1383
+ return this.set.has(item);
1384
+ }
1385
+ /**
1386
+ * Determine if an item exists in the set (alias for has)
1387
+ */
1388
+ contains(item) {
1389
+ return this.has(item);
1390
+ }
1391
+ /**
1392
+ * Add an item to the set
1393
+ */
1394
+ add(item) {
1395
+ this.set.add(item);
1396
+ return this;
1397
+ }
1398
+ /**
1399
+ * Add an item to the set (alias for add)
1400
+ */
1401
+ push(item) {
1402
+ return this.add(item);
1403
+ }
1404
+ /**
1405
+ * Remove an item from the set
1406
+ */
1407
+ delete(item) {
1408
+ return this.set.delete(item);
1409
+ }
1410
+ /**
1411
+ * Remove an item from the set (alias for delete)
1412
+ */
1413
+ forget(item) {
1414
+ return this.delete(item);
1415
+ }
1416
+ /**
1417
+ * Remove all items from the set
1418
+ */
1419
+ clear() {
1420
+ this.set.clear();
1421
+ return this;
1422
+ }
1423
+ /**
1424
+ * Execute a callback over each item
1425
+ */
1426
+ each(callback) {
1427
+ let index = 0;
1428
+ for (const item of this.set) {
1429
+ if (callback(item, index++) === false) {
1430
+ break;
1431
+ }
1432
+ }
1433
+ return this;
1434
+ }
1435
+ /**
1436
+ * Run a map over each of the items
1437
+ */
1438
+ map(callback) {
1439
+ const result = /* @__PURE__ */ new Set();
1440
+ let index = 0;
1441
+ this.set.forEach((item) => {
1442
+ result.add(callback(item, index++));
1443
+ });
1444
+ return new _SetCollection(result);
1445
+ }
1446
+ /**
1447
+ * Run a filter over each of the items
1448
+ */
1449
+ filter(callback) {
1450
+ const result = /* @__PURE__ */ new Set();
1451
+ let index = 0;
1452
+ this.set.forEach((item) => {
1453
+ if (callback(item, index++)) {
1454
+ result.add(item);
1455
+ }
1456
+ });
1457
+ return new _SetCollection(result);
1458
+ }
1459
+ /**
1460
+ * Determine if all items pass the given test
1461
+ */
1462
+ every(callback) {
1463
+ let index = 0;
1464
+ for (const item of this.set) {
1465
+ if (!callback(item, index++)) {
1466
+ return false;
1467
+ }
1468
+ }
1469
+ return true;
1470
+ }
1471
+ /**
1472
+ * Determine if any item passes the given test
1473
+ */
1474
+ some(callback) {
1475
+ let index = 0;
1476
+ for (const item of this.set) {
1477
+ if (callback(item, index++)) {
1478
+ return true;
1479
+ }
1480
+ }
1481
+ return false;
1482
+ }
1483
+ /**
1484
+ * Get the first item that passes the given test
1485
+ */
1486
+ first(callback) {
1487
+ if (!callback) {
1488
+ return this.set.values().next().value;
1489
+ }
1490
+ let index = 0;
1491
+ for (const item of this.set) {
1492
+ if (callback(item, index++)) {
1493
+ return item;
1494
+ }
1495
+ }
1496
+ return void 0;
1497
+ }
1498
+ /**
1499
+ * Get the last item that passes the given test
1500
+ */
1501
+ last(callback) {
1502
+ const items = Array.from(this.set).reverse();
1503
+ if (!callback) {
1504
+ return items[0];
1505
+ }
1506
+ for (let i = 0; i < items.length; i++) {
1507
+ if (callback(items[i], i)) {
1508
+ return items[i];
1509
+ }
1510
+ }
1511
+ return void 0;
1512
+ }
1513
+ /**
1514
+ * Reduce the set to a single value
1515
+ */
1516
+ reduce(callback, initial) {
1517
+ let carry = initial;
1518
+ let index = 0;
1519
+ this.set.forEach((item) => {
1520
+ carry = callback(carry, item, index++);
1521
+ });
1522
+ return carry;
1523
+ }
1524
+ /**
1525
+ * Merge another set into this one
1526
+ */
1527
+ merge(other) {
1528
+ if (other instanceof _SetCollection) {
1529
+ other.each((item) => {
1530
+ this.add(item);
1531
+ return void 0;
1532
+ });
1533
+ } else if (other instanceof Set) {
1534
+ other.forEach((item) => this.add(item));
1535
+ } else {
1536
+ other.forEach((item) => this.add(item));
1537
+ }
1538
+ return this;
1539
+ }
1540
+ /**
1541
+ * Get the union of this set and another
1542
+ */
1543
+ union(other) {
1544
+ const result = new _SetCollection(this.set);
1545
+ return result.merge(other);
1546
+ }
1547
+ /**
1548
+ * Get the intersection of this set and another
1549
+ */
1550
+ intersect(other) {
1551
+ const otherSet = other instanceof _SetCollection ? other.toSet() : other instanceof Set ? other : new Set(other);
1552
+ const result = /* @__PURE__ */ new Set();
1553
+ this.set.forEach((item) => {
1554
+ if (otherSet.has(item)) {
1555
+ result.add(item);
1556
+ }
1557
+ });
1558
+ return new _SetCollection(result);
1559
+ }
1560
+ /**
1561
+ * Get the difference between this set and another
1562
+ */
1563
+ diff(other) {
1564
+ const otherSet = other instanceof _SetCollection ? other.toSet() : other instanceof Set ? other : new Set(other);
1565
+ const result = /* @__PURE__ */ new Set();
1566
+ this.set.forEach((item) => {
1567
+ if (!otherSet.has(item)) {
1568
+ result.add(item);
1569
+ }
1570
+ });
1571
+ return new _SetCollection(result);
1572
+ }
1573
+ /**
1574
+ * Get items that are in either set but not in both
1575
+ */
1576
+ symmetricDiff(other) {
1577
+ const otherSet = other instanceof _SetCollection ? other.toSet() : other instanceof Set ? other : new Set(other);
1578
+ const result = /* @__PURE__ */ new Set();
1579
+ this.set.forEach((item) => {
1580
+ if (!otherSet.has(item)) {
1581
+ result.add(item);
1582
+ }
1583
+ });
1584
+ otherSet.forEach((item) => {
1585
+ if (!this.set.has(item)) {
1586
+ result.add(item);
1587
+ }
1588
+ });
1589
+ return new _SetCollection(result);
1590
+ }
1591
+ /**
1592
+ * Determine if this set is a subset of another
1593
+ */
1594
+ isSubsetOf(other) {
1595
+ const otherSet = other instanceof _SetCollection ? other.toSet() : other instanceof Set ? other : new Set(other);
1596
+ for (const item of this.set) {
1597
+ if (!otherSet.has(item)) {
1598
+ return false;
1599
+ }
1600
+ }
1601
+ return true;
1602
+ }
1603
+ /**
1604
+ * Determine if this set is a superset of another
1605
+ */
1606
+ isSupersetOf(other) {
1607
+ const otherSet = other instanceof _SetCollection ? other.toSet() : other instanceof Set ? other : new Set(other);
1608
+ for (const item of otherSet) {
1609
+ if (!this.set.has(item)) {
1610
+ return false;
1611
+ }
1612
+ }
1613
+ return true;
1614
+ }
1615
+ /**
1616
+ * Pass the set to the given callback and return the result
1617
+ */
1618
+ pipe(callback) {
1619
+ return callback(this);
1620
+ }
1621
+ /**
1622
+ * Pass the set to the given callback and then return it
1623
+ */
1624
+ tap(callback) {
1625
+ callback(this);
1626
+ return this;
1627
+ }
1628
+ /**
1629
+ * Convert the set to an array
1630
+ */
1631
+ toArray() {
1632
+ return this.all();
1633
+ }
1634
+ /**
1635
+ * Convert the set to JSON
1636
+ */
1637
+ toJson() {
1638
+ return JSON.stringify(this.all());
1639
+ }
1640
+ /**
1641
+ * Get the set as a string
1642
+ */
1643
+ toString() {
1644
+ return this.toJson();
1645
+ }
1646
+ /**
1647
+ * Get the underlying Set instance
1648
+ */
1649
+ toSet() {
1650
+ return new Set(this.set);
1651
+ }
1652
+ };
1653
+ function collectSet(items) {
1654
+ return new SetCollection(items);
1655
+ }
1656
+
1657
+ // src/registry/base-registry.ts
1658
+ var RegistryCollection = class {
1659
+ constructor() {
1660
+ this._storage = new MapCollection();
1661
+ }
1662
+ add(key, value) {
1663
+ this._storage.set(key, value);
1664
+ }
1665
+ get(key) {
1666
+ return this._storage.get(key);
1667
+ }
1668
+ getAll() {
1669
+ return this._storage.values();
1670
+ }
1671
+ getKeys() {
1672
+ return this._storage.keys();
1673
+ }
1674
+ getAsRecord() {
1675
+ return this._storage.toObject();
1676
+ }
1677
+ has(key) {
1678
+ return this._storage.has(key);
1679
+ }
1680
+ remove(key) {
1681
+ return this._storage.delete(key);
1682
+ }
1683
+ clear() {
1684
+ this._storage.clear();
1685
+ }
1686
+ size() {
1687
+ return this._storage.size();
1688
+ }
1689
+ isEmpty() {
1690
+ return this._storage.isEmpty();
1691
+ }
1692
+ forEach(callback) {
1693
+ this._storage.each((value, key) => {
1694
+ callback(value, key);
1695
+ });
1696
+ }
1697
+ map(callback) {
1698
+ const result = [];
1699
+ this._storage.each((value, key) => {
1700
+ result.push(callback(value, key));
1701
+ });
1702
+ return result;
1703
+ }
1704
+ filter(predicate) {
1705
+ const result = [];
1706
+ this._storage.each((value, key) => {
1707
+ if (predicate(value, key)) {
1708
+ result.push(value);
1709
+ }
1710
+ });
1711
+ return result;
1712
+ }
1713
+ find(predicate) {
1714
+ return this._storage.first(predicate);
1715
+ }
1716
+ };
1717
+ var BaseRegistry = class {
1718
+ /**
1719
+ * Creates a new BaseRegistry instance
1720
+ *
1721
+ * Initializes the registry with optional configuration for default
1722
+ * item and validation hooks. By default, uses MapCollection for storage.
1723
+ *
1724
+ * @param options - Registry configuration options
1725
+ *
1726
+ * @example
1727
+ * ```typescript
1728
+ * // Simple registry without options
1729
+ * const registry = new BaseRegistry<Theme>();
1730
+ * ```
1731
+ *
1732
+ * @example
1733
+ * ```typescript
1734
+ * // Registry with default item
1735
+ * const registry = new BaseRegistry<Theme>({
1736
+ * defaultItem: defaultTheme
1737
+ * });
1738
+ * ```
1739
+ *
1740
+ * @example
1741
+ * ```typescript
1742
+ * // Registry with validation
1743
+ * const registry = new BaseRegistry<Theme>({
1744
+ * validateBeforeAdd: (key, theme) => {
1745
+ * if (!theme.name) {
1746
+ * return { valid: false, error: 'Theme must have a name' };
1747
+ * }
1748
+ * return { valid: true };
1749
+ * },
1750
+ * afterAdd: (key, theme) => {
1751
+ * console.log(`Registered theme: ${theme.name}`);
1752
+ * }
1753
+ * });
1754
+ * ```
1755
+ */
1756
+ constructor(options = {}) {
1757
+ this.collection = new RegistryCollection();
1758
+ this.defaultItem = options.defaultItem;
1759
+ this.validateBeforeAdd = options.validateBeforeAdd;
1760
+ this.afterAdd = options.afterAdd;
1761
+ }
1762
+ /**
1763
+ * Register an item in the registry
1764
+ *
1765
+ * Adds or updates an item in the registry with the specified key.
1766
+ * If an item with the same key already exists, it will be replaced.
1767
+ *
1768
+ * If a validation hook is configured, it will be called before adding
1769
+ * the item. If validation fails, an error is thrown and the item is
1770
+ * not added.
1771
+ *
1772
+ * If an afterAdd hook is configured, it will be called after the item
1773
+ * is successfully added.
1774
+ *
1775
+ * Time Complexity: O(1) + validation time
1776
+ *
1777
+ * @param key - Unique identifier for the item
1778
+ * @param item - Item to register
1779
+ * @throws Error if validation fails
1780
+ *
1781
+ * @example
1782
+ * ```typescript
1783
+ * const registry = new BaseRegistry<Theme>();
1784
+ *
1785
+ * // Register a theme
1786
+ * registry.register('blue', {
1787
+ * name: 'Blue',
1788
+ * colors: { accent: '#0000FF' }
1789
+ * });
1790
+ *
1791
+ * // Update existing theme
1792
+ * registry.register('blue', {
1793
+ * name: 'Blue',
1794
+ * colors: { accent: '#0066FF' }
1795
+ * });
1796
+ * ```
1797
+ */
1798
+ register(key, item) {
1799
+ if (this.validateBeforeAdd) {
1800
+ const result = this.validateBeforeAdd(key, item);
1801
+ if (!result.valid) {
1802
+ throw new Error(
1803
+ `Validation failed for key "${key}": ${result.error || "Unknown error"}`
1804
+ );
1805
+ }
1806
+ }
1807
+ this.collection.add(key, item);
1808
+ if (this.afterAdd) {
1809
+ this.afterAdd(key, item);
1810
+ }
1811
+ }
1812
+ // ============================================================================
1813
+ // Collection Interface Implementation
1814
+ // All methods below delegate directly to the internal collection
1815
+ // ============================================================================
1816
+ /**
1817
+ * Add an item to the collection (alias for register)
1818
+ *
1819
+ * This method is part of the Collection interface.
1820
+ * It delegates to register() to ensure validation hooks are called.
1821
+ *
1822
+ * Time Complexity: O(1) + validation time
1823
+ *
1824
+ * @param key - Unique identifier for the item
1825
+ * @param value - Item to add
1826
+ */
1827
+ add(key, value) {
1828
+ this.register(key, value);
1829
+ }
1830
+ /**
1831
+ * Get an item from the registry
1832
+ *
1833
+ * Retrieves an item by its key. If the item doesn't exist:
1834
+ * - Returns the default item if one was configured
1835
+ * - Returns undefined if no default item was configured
1836
+ *
1837
+ * Time Complexity: O(1)
1838
+ *
1839
+ * @param key - Item identifier
1840
+ * @returns Item if found, default item if configured, or undefined
1841
+ *
1842
+ * @example
1843
+ * ```typescript
1844
+ * const theme = registry.get('blue');
1845
+ * ```
1846
+ */
1847
+ get(key) {
1848
+ const item = this.collection.get(key);
1849
+ if (item !== void 0) {
1850
+ return item;
1851
+ }
1852
+ return this.defaultItem;
1853
+ }
1854
+ /**
1855
+ * Get all items in the registry
1856
+ *
1857
+ * Returns an array containing all items in the registry.
1858
+ * The order of items depends on the collection implementation
1859
+ * (MapCollection maintains insertion order).
1860
+ *
1861
+ * Time Complexity: O(n) where n is the number of items
1862
+ *
1863
+ * @returns Array of all items in the registry
1864
+ *
1865
+ * @example
1866
+ * ```typescript
1867
+ * const allThemes = registry.getAll();
1868
+ * ```
1869
+ */
1870
+ getAll() {
1871
+ return this.collection.getAll();
1872
+ }
1873
+ /**
1874
+ * Get all keys in the registry
1875
+ *
1876
+ * Returns an array containing all keys in the registry.
1877
+ * Useful for iteration or checking what items are registered.
1878
+ *
1879
+ * Time Complexity: O(n) where n is the number of items
1880
+ *
1881
+ * @returns Array of all keys in the registry
1882
+ *
1883
+ * @example
1884
+ * ```typescript
1885
+ * const keys = registry.getKeys();
1886
+ * ```
1887
+ */
1888
+ getKeys() {
1889
+ return this.collection.getKeys();
1890
+ }
1891
+ /**
1892
+ * Get registry as a record object
1893
+ *
1894
+ * Converts the registry to a plain JavaScript object (record)
1895
+ * with keys mapping to values. Useful for serialization.
1896
+ *
1897
+ * Time Complexity: O(n) where n is the number of items
1898
+ *
1899
+ * @returns Record object with keys mapping to values
1900
+ *
1901
+ * @example
1902
+ * ```typescript
1903
+ * const record = registry.getAsRecord();
1904
+ * ```
1905
+ */
1906
+ getAsRecord() {
1907
+ return this.collection.getAsRecord();
1908
+ }
1909
+ /**
1910
+ * Check if an item is registered
1911
+ *
1912
+ * Checks whether an item with the specified key exists in the registry.
1913
+ * Does not check the value, only the presence of the key.
1914
+ *
1915
+ * Time Complexity: O(1)
1916
+ *
1917
+ * @param key - Item identifier to check
1918
+ * @returns True if item is registered, false otherwise
1919
+ *
1920
+ * @example
1921
+ * ```typescript
1922
+ * if (registry.has('blue')) {
1923
+ * console.log('Blue theme exists');
1924
+ * }
1925
+ * ```
1926
+ */
1927
+ has(key) {
1928
+ return this.collection.has(key);
1929
+ }
1930
+ /**
1931
+ * Remove an item from the registry
1932
+ *
1933
+ * Removes an item with the specified key from the registry.
1934
+ * Returns true if the item was removed, false if it didn't exist.
1935
+ *
1936
+ * Time Complexity: O(1)
1937
+ *
1938
+ * @param key - Item identifier to remove
1939
+ * @returns True if item was removed, false if it didn't exist
1940
+ *
1941
+ * @example
1942
+ * ```typescript
1943
+ * const removed = registry.remove('blue');
1944
+ * ```
1945
+ */
1946
+ remove(key) {
1947
+ return this.collection.remove(key);
1948
+ }
1949
+ /**
1950
+ * Clear all items from the registry
1951
+ *
1952
+ * Removes all items from the registry, leaving it empty.
1953
+ * This operation is irreversible.
1954
+ *
1955
+ * Time Complexity: O(1)
1956
+ *
1957
+ * @example
1958
+ * ```typescript
1959
+ * registry.clear();
1960
+ * ```
1961
+ */
1962
+ clear() {
1963
+ this.collection.clear();
1964
+ }
1965
+ /**
1966
+ * Get the number of items in the registry
1967
+ *
1968
+ * Returns the total count of items currently registered.
1969
+ *
1970
+ * Time Complexity: O(1)
1971
+ *
1972
+ * @returns Number of items in the registry
1973
+ *
1974
+ * @example
1975
+ * ```typescript
1976
+ * console.log(registry.size()); // 2
1977
+ * ```
1978
+ */
1979
+ size() {
1980
+ return this.collection.size();
1981
+ }
1982
+ /**
1983
+ * Check if the registry is empty
1984
+ *
1985
+ * Returns true if the registry contains no items, false otherwise.
1986
+ * This is a convenience method equivalent to checking if size() === 0.
1987
+ *
1988
+ * Time Complexity: O(1)
1989
+ *
1990
+ * @returns True if registry has no items, false otherwise
1991
+ *
1992
+ * @example
1993
+ * ```typescript
1994
+ * console.log(registry.isEmpty()); // true
1995
+ * ```
1996
+ */
1997
+ isEmpty() {
1998
+ return this.collection.isEmpty();
1999
+ }
2000
+ /**
2001
+ * Iterate over all items in the registry
2002
+ *
2003
+ * Executes a callback function for each item in the registry.
2004
+ * Items are iterated in insertion order (for MapCollection).
2005
+ *
2006
+ * Time Complexity: O(n) where n is the number of items
2007
+ *
2008
+ * @param callback - Function to call for each item (value, key)
2009
+ *
2010
+ * @example
2011
+ * ```typescript
2012
+ * registry.forEach((theme, key) => {
2013
+ * console.log(`${key}: ${theme.name}`);
2014
+ * });
2015
+ * ```
2016
+ */
2017
+ forEach(callback) {
2018
+ this.collection.forEach(callback);
2019
+ }
2020
+ /**
2021
+ * Map over all items in the registry
2022
+ *
2023
+ * Transforms each item in the registry using a callback function
2024
+ * and returns an array of the transformed values.
2025
+ *
2026
+ * Time Complexity: O(n) where n is the number of items
2027
+ *
2028
+ * @template U - The type of the transformed items
2029
+ * @param callback - Function to transform each item (value, key) => U
2030
+ * @returns Array of transformed items
2031
+ *
2032
+ * @example
2033
+ * ```typescript
2034
+ * const names = registry.map(theme => theme.name);
2035
+ * ```
2036
+ */
2037
+ map(callback) {
2038
+ return this.collection.map(callback);
2039
+ }
2040
+ /**
2041
+ * Filter items in the registry
2042
+ *
2043
+ * Returns an array of items that pass the test implemented by the
2044
+ * provided predicate function.
2045
+ *
2046
+ * Time Complexity: O(n) where n is the number of items
2047
+ *
2048
+ * @param predicate - Function to test each item (value, key) => boolean
2049
+ * @returns Array of items that pass the test
2050
+ *
2051
+ * @example
2052
+ * ```typescript
2053
+ * const darkThemes = registry.filter(theme => theme.isDark);
2054
+ * ```
2055
+ */
2056
+ filter(predicate) {
2057
+ return this.collection.filter(predicate);
2058
+ }
2059
+ /**
2060
+ * Find an item in the registry
2061
+ *
2062
+ * Returns the first item that satisfies the provided predicate function.
2063
+ * Returns undefined if no item passes the test.
2064
+ *
2065
+ * Time Complexity: O(n) worst case, O(1) best case
2066
+ *
2067
+ * @param predicate - Function to test each item (value, key) => boolean
2068
+ * @returns First item that passes the test, or undefined
2069
+ *
2070
+ * @example
2071
+ * ```typescript
2072
+ * const defaultTheme = registry.find(theme => theme.isDefault);
2073
+ * ```
2074
+ */
2075
+ find(predicate) {
2076
+ return this.collection.find(predicate);
2077
+ }
2078
+ };
2079
+
2080
+ // src/facades/facade.ts
2081
+ import { getModuleContainer } from "@abdokouta/react-di";
2082
+
2083
+ // src/facades/facade.interface.ts
2084
+ function isFake(obj) {
2085
+ return typeof obj === "object" && obj !== null && "__isFake" in obj && obj.__isFake === true;
2086
+ }
2087
+
2088
+ // src/facades/facade.ts
2089
+ var Facade = class {
2090
+ /**
2091
+ * Hotswap the underlying instance behind the facade
2092
+ *
2093
+ * Useful for testing - swap the real service with a mock or fake.
2094
+ *
2095
+ * @param instance - Instance to swap in
2096
+ *
2097
+ * @example
2098
+ * ```typescript
2099
+ * // In tests
2100
+ * const mockLogger = { info: vi.fn(), error: vi.fn() };
2101
+ * Log.swap(mockLogger);
2102
+ *
2103
+ * // Now Log.info() calls mockLogger.info()
2104
+ * Log.info('test');
2105
+ * expect(mockLogger.info).toHaveBeenCalledWith('test');
2106
+ * ```
2107
+ */
2108
+ static swap(instance) {
2109
+ const accessor = this.getFacadeAccessor();
2110
+ const key = this.getAccessorKey(accessor);
2111
+ this.resolvedInstance.set(key, instance);
2112
+ }
2113
+ /**
2114
+ * Determines whether a "fake" has been set as the facade instance
2115
+ *
2116
+ * @returns True if the current instance is a Fake
2117
+ *
2118
+ * @example
2119
+ * ```typescript
2120
+ * if (Log.isFake()) {
2121
+ * console.log('Using fake logger');
2122
+ * }
2123
+ * ```
2124
+ */
2125
+ static isFake() {
2126
+ const accessor = this.getFacadeAccessor();
2127
+ const key = this.getAccessorKey(accessor);
2128
+ const instance = this.resolvedInstance.get(key);
2129
+ return instance !== void 0 && isFake(instance);
2130
+ }
2131
+ /**
2132
+ * Get the root object behind the facade
2133
+ *
2134
+ * Resolves and returns the actual service instance.
2135
+ *
2136
+ * @returns The resolved service instance
2137
+ */
2138
+ static getFacadeRoot() {
2139
+ return this.resolveFacadeInstance(this.getFacadeAccessor());
2140
+ }
2141
+ /**
2142
+ * Get the registered name of the component
2143
+ *
2144
+ * Subclasses MUST override this method to specify which service
2145
+ * the facade represents.
2146
+ *
2147
+ * @returns Service identifier (string, symbol, or class)
2148
+ * @throws Error if not implemented
2149
+ *
2150
+ * @example
2151
+ * ```typescript
2152
+ * class Log extends Facade {
2153
+ * protected static getFacadeAccessor(): ServiceIdentifier {
2154
+ * return LoggerService; // or 'logger' string token
2155
+ * }
2156
+ * }
2157
+ * ```
2158
+ */
2159
+ static getFacadeAccessor() {
2160
+ throw new Error("Facade does not implement getFacadeAccessor method.");
2161
+ }
2162
+ /**
2163
+ * Get a consistent key for the accessor
2164
+ */
2165
+ static getAccessorKey(accessor) {
2166
+ if (typeof accessor === "function") {
2167
+ return accessor.name || accessor.toString();
2168
+ }
2169
+ return accessor;
2170
+ }
2171
+ /**
2172
+ * Resolve the facade root instance from the container
2173
+ *
2174
+ * @param identifier - Service identifier
2175
+ * @returns Resolved service instance
2176
+ */
2177
+ static resolveFacadeInstance(identifier) {
2178
+ const key = this.getAccessorKey(identifier);
2179
+ if (this.resolvedInstance.has(key)) {
2180
+ return this.resolvedInstance.get(key);
2181
+ }
2182
+ const container = this.getContainer();
2183
+ if (!container) {
2184
+ throw new Error(
2185
+ `Unable to resolve facade instance. Module not set. Call Facade.setFacadeModule(YourModule) first.`
2186
+ );
2187
+ }
2188
+ const instance = container.get(identifier);
2189
+ if (this.cached) {
2190
+ this.resolvedInstance.set(key, instance);
2191
+ }
2192
+ return instance;
2193
+ }
2194
+ /**
2195
+ * Get the module container
2196
+ *
2197
+ * @returns The module container instance
2198
+ */
2199
+ static getContainer() {
2200
+ if (this.container) {
2201
+ return this.container;
2202
+ }
2203
+ if (this.moduleClass) {
2204
+ this.container = getModuleContainer(this.moduleClass);
2205
+ return this.container;
2206
+ }
2207
+ return null;
2208
+ }
2209
+ /**
2210
+ * Clear a resolved facade instance
2211
+ *
2212
+ * @param name - Service identifier to clear (defaults to this facade's accessor)
2213
+ */
2214
+ static clearResolvedInstance(name) {
2215
+ const key = name ?? this.getAccessorKey(this.getFacadeAccessor());
2216
+ this.resolvedInstance.delete(key);
2217
+ }
2218
+ /**
2219
+ * Clear all resolved instances
2220
+ *
2221
+ * Useful for test cleanup.
2222
+ */
2223
+ static clearResolvedInstances() {
2224
+ this.resolvedInstance.clear();
2225
+ }
2226
+ /**
2227
+ * Get the module class
2228
+ *
2229
+ * @returns The module class
2230
+ */
2231
+ static getFacadeModule() {
2232
+ return this.moduleClass;
2233
+ }
2234
+ /**
2235
+ * Set the module class for facade resolution
2236
+ *
2237
+ * Must be called during application bootstrap to enable facades.
2238
+ * Call this AFTER Inversiland.run() or Container.configure().build().
2239
+ *
2240
+ * @param module - The root module class
2241
+ *
2242
+ * @example
2243
+ * ```typescript
2244
+ * // In your app bootstrap (main.tsx)
2245
+ * import { Facade } from '@abdokouta/react-support';
2246
+ * import { Container, ContainerProvider } from '@abdokouta/react-di';
2247
+ * import { AppModule } from './app.module';
2248
+ *
2249
+ * // Initialize container
2250
+ * Container.configure().withModule(AppModule).withDefaults().build();
2251
+ *
2252
+ * // Set facade module
2253
+ * Facade.setFacadeModule(AppModule);
2254
+ *
2255
+ * // Now facades work anywhere
2256
+ * ReactDOM.createRoot(document.getElementById("root")!).render(
2257
+ * <ContainerProvider module={AppModule}>
2258
+ * <App />
2259
+ * </ContainerProvider>
2260
+ * );
2261
+ * ```
2262
+ */
2263
+ static setFacadeModule(module) {
2264
+ this.moduleClass = module;
2265
+ this.container = null;
2266
+ }
2267
+ /**
2268
+ * Set the container directly (alternative to setFacadeModule)
2269
+ *
2270
+ * @param container - The module container instance
2271
+ */
2272
+ static setFacadeContainer(container) {
2273
+ this.container = container;
2274
+ }
2275
+ // ============================================================================
2276
+ // Legacy API (for compatibility with FacadeApplication interface)
2277
+ // ============================================================================
2278
+ /**
2279
+ * @deprecated Use setFacadeModule instead
2280
+ */
2281
+ static setFacadeApplication(app) {
2282
+ if (app) {
2283
+ this.container = {
2284
+ get: (id) => app.get(id)
2285
+ };
2286
+ } else {
2287
+ this.container = null;
2288
+ }
2289
+ }
2290
+ /**
2291
+ * @deprecated Use getFacadeModule instead
2292
+ */
2293
+ static getFacadeApplication() {
2294
+ const container = this.getContainer();
2295
+ if (!container) return null;
2296
+ return {
2297
+ get: (abstract) => container.get(abstract)
2298
+ };
2299
+ }
2300
+ };
2301
+ /**
2302
+ * The root module class for resolving services
2303
+ */
2304
+ Facade.moduleClass = null;
2305
+ /**
2306
+ * The module container instance (cached)
2307
+ */
2308
+ Facade.container = null;
2309
+ /**
2310
+ * The resolved object instances
2311
+ *
2312
+ * Caches resolved instances by their accessor key for performance.
2313
+ */
2314
+ Facade.resolvedInstance = /* @__PURE__ */ new Map();
2315
+ /**
2316
+ * Indicates if the resolved instance should be cached
2317
+ *
2318
+ * Set to false in subclasses to always resolve fresh instances.
2319
+ */
2320
+ Facade.cached = true;
2321
+
2322
+ // src/facades/create-facade.ts
2323
+ import { getModuleContainer as getModuleContainer2 } from "@abdokouta/react-di";
2324
+ function createFacade(options) {
2325
+ const { accessor, cached = true } = options;
2326
+ class ConcreteFacade extends Facade {
2327
+ static getFacadeAccessor() {
2328
+ return accessor;
2329
+ }
2330
+ }
2331
+ ConcreteFacade.cached = cached;
2332
+ const proxy = new Proxy(ConcreteFacade, {
2333
+ get(target, prop, receiver) {
2334
+ if (prop in target) {
2335
+ const value = Reflect.get(target, prop, receiver);
2336
+ if (typeof value === "function") {
2337
+ return value.bind(target);
2338
+ }
2339
+ return value;
2340
+ }
2341
+ return (...args) => {
2342
+ const instance = target.getFacadeRoot();
2343
+ if (!instance) {
2344
+ throw new Error(
2345
+ `A facade root has not been set. Call Facade.setFacadeModule() first.`
2346
+ );
2347
+ }
2348
+ const method = instance[prop];
2349
+ if (typeof method !== "function") {
2350
+ throw new Error(
2351
+ `Method "${String(prop)}" does not exist on the facade root.`
2352
+ );
2353
+ }
2354
+ return method.apply(instance, args);
2355
+ };
2356
+ }
2357
+ });
2358
+ return proxy;
2359
+ }
2360
+ function createFacadeClass(accessor) {
2361
+ return class extends Facade {
2362
+ static getFacadeAccessor() {
2363
+ return accessor;
2364
+ }
2365
+ };
2366
+ }
2367
+ function getContainerFromModule(moduleClass) {
2368
+ return getModuleContainer2(moduleClass);
2369
+ }
2370
+ export {
2371
+ BaseRegistry,
2372
+ Collection,
2373
+ Facade,
2374
+ MapCollection,
2375
+ SetCollection,
2376
+ Str,
2377
+ collect,
2378
+ collectMap,
2379
+ collectSet,
2380
+ createFacade,
2381
+ createFacadeClass,
2382
+ getContainerFromModule,
2383
+ isFake
2384
+ };
2385
+ //# sourceMappingURL=index.mjs.map