@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.
@@ -0,0 +1,1749 @@
1
+ export { Collection as CollectJsCollection } from 'collect.js';
2
+ import { Newable, ModuleContainer, ServiceIdentifier } from '@abdokouta/react-di';
3
+ export { ModuleContainer, Newable, ServiceIdentifier } from '@abdokouta/react-di';
4
+
5
+ /**
6
+ * Laravel-style string manipulation class
7
+ * Provides static methods for common string operations
8
+ */
9
+ declare class Str {
10
+ /**
11
+ * Return the remainder of a string after the first occurrence of a given value
12
+ */
13
+ static after(subject: string, search: string): string;
14
+ /**
15
+ * Return the remainder of a string after the last occurrence of a given value
16
+ */
17
+ static afterLast(subject: string, search: string): string;
18
+ /**
19
+ * Convert a string to title case following APA guidelines
20
+ */
21
+ static apa(value: string): string;
22
+ /**
23
+ * Transliterate a UTF-8 value to ASCII
24
+ */
25
+ static ascii(value: string): string;
26
+ /**
27
+ * Get the portion of a string before the first occurrence of a given value
28
+ */
29
+ static before(subject: string, search: string): string;
30
+ /**
31
+ * Get the portion of a string before the last occurrence of a given value
32
+ */
33
+ static beforeLast(subject: string, search: string): string;
34
+ /**
35
+ * Get the portion of a string between two values
36
+ */
37
+ static between(subject: string, from: string, to: string): string;
38
+ /**
39
+ * Get the smallest possible portion of a string between two values
40
+ */
41
+ static betweenFirst(subject: string, from: string, to: string): string;
42
+ /**
43
+ * Convert a string to camelCase
44
+ */
45
+ static camel(value: string): string;
46
+ /**
47
+ * Get the character at the specified index
48
+ */
49
+ static charAt(subject: string, index: number): string | false;
50
+ /**
51
+ * Remove the first occurrence of the given value from the start of the string
52
+ */
53
+ static chopStart(subject: string, search: string | string[]): string;
54
+ /**
55
+ * Remove the last occurrence of the given value from the end of the string
56
+ */
57
+ static chopEnd(subject: string, search: string | string[]): string;
58
+ /**
59
+ * Determine if a given string contains a given substring
60
+ */
61
+ static contains(haystack: string, needles: string | string[], ignoreCase?: boolean): boolean;
62
+ /**
63
+ * Determine if a given string contains all array values
64
+ */
65
+ static containsAll(haystack: string, needles: string[], ignoreCase?: boolean): boolean;
66
+ /**
67
+ * Determine if a given string doesn't contain a given substring
68
+ */
69
+ static doesntContain(haystack: string, needles: string | string[], ignoreCase?: boolean): boolean;
70
+ /**
71
+ * Replace consecutive instances of a character with a single instance
72
+ */
73
+ static deduplicate(value: string, character?: string): string;
74
+ /**
75
+ * Determine if a given string ends with a given substring
76
+ */
77
+ static endsWith(haystack: string, needles: string | string[]): boolean;
78
+ /**
79
+ * Extract an excerpt from text that matches the first instance of a phrase
80
+ */
81
+ static excerpt(text: string, phrase: string, options?: {
82
+ radius?: number;
83
+ omission?: string;
84
+ }): string;
85
+ /**
86
+ * Cap a string with a single instance of a given value
87
+ */
88
+ static finish(value: string, cap: string): string;
89
+ /**
90
+ * Convert a string to headline case
91
+ */
92
+ static headline(value: string): string;
93
+ /**
94
+ * Determine if a given string matches a given pattern
95
+ */
96
+ static is(pattern: string, value: string, ignoreCase?: boolean): boolean;
97
+ /**
98
+ * Determine if a given string is 7-bit ASCII
99
+ */
100
+ static isAscii(value: string): boolean;
101
+ /**
102
+ * Determine if a given string is valid JSON
103
+ */
104
+ static isJson(value: string): boolean;
105
+ /**
106
+ * Determine if a given string is a valid URL
107
+ */
108
+ static isUrl(value: string, protocols?: string[]): boolean;
109
+ /**
110
+ * Determine if a given string is a valid ULID
111
+ */
112
+ static isUlid(value: string): boolean;
113
+ /**
114
+ * Determine if a given string is a valid UUID
115
+ */
116
+ static isUuid(value: string): boolean;
117
+ /**
118
+ * Convert a string to kebab-case
119
+ */
120
+ static kebab(value: string): string;
121
+ /**
122
+ * Return the given string with the first character lowercased
123
+ */
124
+ static lcfirst(value: string): string;
125
+ /**
126
+ * Return the length of the given string
127
+ */
128
+ static len(value: string): number;
129
+ /**
130
+ * Limit the number of characters in a string
131
+ */
132
+ static limit(value: string, limit?: number, end?: string, preserveWords?: boolean): string;
133
+ /**
134
+ * Convert the given string to lowercase
135
+ */
136
+ static lower(value: string): string;
137
+ /**
138
+ * Masks a portion of a string with a repeated character
139
+ */
140
+ static mask(value: string, character: string, index: number, length?: number): string;
141
+ /**
142
+ * Pad both sides of a string with another
143
+ */
144
+ static padBoth(value: string, length: number, pad?: string): string;
145
+ /**
146
+ * Pad the left side of a string with another
147
+ */
148
+ static padLeft(value: string, length: number, pad?: string): string;
149
+ /**
150
+ * Pad the right side of a string with another
151
+ */
152
+ static padRight(value: string, length: number, pad?: string): string;
153
+ /**
154
+ * Get the plural form of an English word
155
+ */
156
+ static plural(value: string, count?: number): string;
157
+ /**
158
+ * Pluralize the last word of an English, studly caps case string
159
+ */
160
+ static pluralStudly(value: string, count?: number): string;
161
+ /**
162
+ * Find the position of the first occurrence of a substring
163
+ */
164
+ static position(haystack: string, needle: string): number | false;
165
+ /**
166
+ * Generate a random string
167
+ */
168
+ static random(length?: number): string;
169
+ /**
170
+ * Remove the given value from the string
171
+ */
172
+ static remove(search: string | string[], subject: string, caseSensitive?: boolean): string;
173
+ /**
174
+ * Repeat the given string
175
+ */
176
+ static repeat(value: string, times: number): string;
177
+ /**
178
+ * Replace the given value in the given string
179
+ */
180
+ static replace(search: string, replace: string, subject: string, caseSensitive?: boolean): string;
181
+ /**
182
+ * Replace a given value in the string sequentially with an array
183
+ */
184
+ static replaceArray(search: string, replacements: string[], subject: string): string;
185
+ /**
186
+ * Replace the first occurrence of a given value in the string
187
+ */
188
+ static replaceFirst(search: string, replace: string, subject: string): string;
189
+ /**
190
+ * Replace the last occurrence of a given value in the string
191
+ */
192
+ static replaceLast(search: string, replace: string, subject: string): string;
193
+ /**
194
+ * Replace the first occurrence only if it appears at the start
195
+ */
196
+ static replaceStart(search: string, replace: string, subject: string): string;
197
+ /**
198
+ * Replace the last occurrence only if it appears at the end
199
+ */
200
+ static replaceEnd(search: string, replace: string, subject: string): string;
201
+ /**
202
+ * Reverse the given string
203
+ */
204
+ static reverse(value: string): string;
205
+ /**
206
+ * Get the singular form of an English word
207
+ */
208
+ static singular(value: string): string;
209
+ /**
210
+ * Generate a URL friendly slug
211
+ */
212
+ static slug(value: string, separator?: string): string;
213
+ /**
214
+ * Convert a string to snake_case
215
+ */
216
+ static snake(value: string, delimiter?: string): string;
217
+ /**
218
+ * Remove all extraneous whitespace
219
+ */
220
+ static squish(value: string): string;
221
+ /**
222
+ * Begin a string with a single instance of a given value
223
+ */
224
+ static start(value: string, prefix: string): string;
225
+ /**
226
+ * Determine if a given string starts with a given substring
227
+ */
228
+ static startsWith(haystack: string, needles: string | string[]): boolean;
229
+ /**
230
+ * Convert a value to studly caps case
231
+ */
232
+ static studly(value: string): string;
233
+ /**
234
+ * Returns the portion of string specified by the start and length parameters
235
+ */
236
+ static substr(value: string, start: number, length?: number): string;
237
+ /**
238
+ * Returns the number of substring occurrences
239
+ */
240
+ static substrCount(haystack: string, needle: string): number;
241
+ /**
242
+ * Replace text within a portion of a string
243
+ */
244
+ static substrReplace(value: string, replace: string, start: number, length?: number): string;
245
+ /**
246
+ * Swap multiple keywords in a string with other keywords
247
+ */
248
+ static swap(map: Record<string, string>, subject: string): string;
249
+ /**
250
+ * Take the first or last {limit} characters
251
+ */
252
+ static take(value: string, limit: number): string;
253
+ /**
254
+ * Convert the given string to title case
255
+ */
256
+ static title(value: string): string;
257
+ /**
258
+ * Convert the given string to Base64
259
+ */
260
+ static toBase64(value: string): string;
261
+ /**
262
+ * Transliterate a string to its closest ASCII representation
263
+ */
264
+ static transliterate(value: string): string;
265
+ /**
266
+ * Trim whitespace from both ends of the string
267
+ */
268
+ static trim(value: string, characters?: string): string;
269
+ /**
270
+ * Trim whitespace from the beginning of the string
271
+ */
272
+ static ltrim(value: string, characters?: string): string;
273
+ /**
274
+ * Trim whitespace from the end of the string
275
+ */
276
+ static rtrim(value: string, characters?: string): string;
277
+ /**
278
+ * Make a string's first character uppercase
279
+ */
280
+ static ucfirst(value: string): string;
281
+ /**
282
+ * Split a string by uppercase characters
283
+ */
284
+ static ucsplit(value: string): string[];
285
+ /**
286
+ * Convert the given string to uppercase
287
+ */
288
+ static upper(value: string): string;
289
+ /**
290
+ * Remove the specified strings from the beginning and end
291
+ */
292
+ static unwrap(value: string, before: string, after?: string): string;
293
+ /**
294
+ * Get the number of words a string contains
295
+ */
296
+ static wordCount(value: string): number;
297
+ /**
298
+ * Wrap a string to a given number of characters
299
+ */
300
+ static wordWrap(value: string, characters?: number, breakStr?: string): string;
301
+ /**
302
+ * Limit the number of words in a string
303
+ */
304
+ static words(value: string, words?: number, end?: string): string;
305
+ /**
306
+ * Wrap the string with the given strings
307
+ */
308
+ static wrap(value: string, before: string, after?: string): string;
309
+ }
310
+
311
+ declare class Collection$1<T = any> {
312
+ private collection;
313
+ constructor(items?: T[]);
314
+ /**
315
+ * Create a new collection instance
316
+ */
317
+ static make<T>(items?: T[]): Collection$1<T>;
318
+ /**
319
+ * Get all items in the collection
320
+ */
321
+ all(): T[];
322
+ /**
323
+ * Get the average value of a given key
324
+ */
325
+ avg(key?: keyof T | ((item: T) => number)): number;
326
+ /**
327
+ * Chunk the collection into chunks of the given size
328
+ */
329
+ chunk(size: number): Collection$1<T[]>;
330
+ /**
331
+ * Collapse a collection of arrays into a single, flat collection
332
+ */
333
+ collapse(): Collection$1<any>;
334
+ /**
335
+ * Determine if an item exists in the collection
336
+ */
337
+ contains(key: keyof T | ((item: T) => boolean), value?: any): boolean;
338
+ /**
339
+ * Get the total number of items in the collection
340
+ */
341
+ count(): number;
342
+ /**
343
+ * Get the items in the collection that are not present in the given items
344
+ */
345
+ diff(items: T[]): Collection$1<T>;
346
+ /**
347
+ * Execute a callback over each item
348
+ */
349
+ each(callback: (item: T, key: number) => void | false): this;
350
+ /**
351
+ * Determine if all items pass the given test
352
+ */
353
+ every(callback: (item: T, key: number) => boolean): boolean;
354
+ /**
355
+ * Get all items except for those with the specified keys
356
+ */
357
+ except(keys: (keyof T)[]): Collection$1<T>;
358
+ /**
359
+ * Run a filter over each of the items
360
+ */
361
+ filter(callback?: (item: T, key: number) => boolean): Collection$1<T>;
362
+ /**
363
+ * Get the first item from the collection
364
+ */
365
+ first(callback?: (item: T, key: number) => boolean): T | undefined;
366
+ /**
367
+ * Get a flattened array of the items in the collection
368
+ */
369
+ flatten(depth?: number): Collection$1<any>;
370
+ /**
371
+ * Flip the items in the collection
372
+ */
373
+ flip(): Collection$1<any>;
374
+ /**
375
+ * Remove an item from the collection by key
376
+ */
377
+ forget(key: number): this;
378
+ /**
379
+ * Get an item from the collection by key
380
+ */
381
+ get(key: number, defaultValue?: T): T | undefined;
382
+ /**
383
+ * Group the collection's items by a given key
384
+ */
385
+ groupBy(key: keyof T | ((item: T) => any)): Collection$1<Collection$1<T>>;
386
+ /**
387
+ * Determine if a given key exists in the collection
388
+ */
389
+ has(key: number): boolean;
390
+ /**
391
+ * Concatenate values of a given key as a string
392
+ */
393
+ implode(key: keyof T | string, glue?: string): string;
394
+ /**
395
+ * Intersect the collection with the given items
396
+ */
397
+ intersect(items: T[]): Collection$1<T>;
398
+ /**
399
+ * Determine if the collection is empty
400
+ */
401
+ isEmpty(): boolean;
402
+ /**
403
+ * Determine if the collection is not empty
404
+ */
405
+ isNotEmpty(): boolean;
406
+ /**
407
+ * Join all items from the collection using a string
408
+ */
409
+ join(glue: string, finalGlue?: string): string;
410
+ /**
411
+ * Key the collection by the given key
412
+ */
413
+ keyBy(key: keyof T | ((item: T) => any)): Collection$1<T>;
414
+ /**
415
+ * Get the keys of the collection items
416
+ */
417
+ keys(): Collection$1<string | number>;
418
+ /**
419
+ * Get the last item from the collection
420
+ */
421
+ last(callback?: (item: T, key: number) => boolean): T | undefined;
422
+ /**
423
+ * Run a map over each of the items
424
+ */
425
+ map<U>(callback: (item: T, key: number) => U): Collection$1<U>;
426
+ /**
427
+ * Get the max value of a given key
428
+ */
429
+ max(key?: keyof T): number;
430
+ /**
431
+ * Merge the collection with the given items
432
+ */
433
+ merge(items: T[]): Collection$1<T>;
434
+ /**
435
+ * Get the min value of a given key
436
+ */
437
+ min(key?: keyof T): number;
438
+ /**
439
+ * Get the items with the specified keys
440
+ */
441
+ only(keys: (keyof T)[]): Collection$1<T>;
442
+ /**
443
+ * Get and remove the last item from the collection
444
+ */
445
+ pop(): T | undefined;
446
+ /**
447
+ * Push an item onto the beginning of the collection
448
+ */
449
+ prepend(value: T): this;
450
+ /**
451
+ * Get and remove an item from the collection
452
+ */
453
+ pull(key: number): T | undefined;
454
+ /**
455
+ * Push an item onto the end of the collection
456
+ */
457
+ push(value: T): this;
458
+ /**
459
+ * Put an item in the collection by key
460
+ */
461
+ put(key: number, value: T): this;
462
+ /**
463
+ * Get one or a specified number of items randomly from the collection
464
+ */
465
+ random(count?: number): T | Collection$1<T>;
466
+ /**
467
+ * Reduce the collection to a single value
468
+ */
469
+ reduce<U>(callback: (carry: U, item: T) => U, initial: U): U;
470
+ /**
471
+ * Filter items by the given key value pair
472
+ */
473
+ reject(callback: (item: T, key: number) => boolean): Collection$1<T>;
474
+ /**
475
+ * Reverse items order
476
+ */
477
+ reverse(): Collection$1<T>;
478
+ /**
479
+ * Search the collection for a given value
480
+ */
481
+ search(value: T | ((item: T) => boolean)): number | false;
482
+ /**
483
+ * Get and remove the first item from the collection
484
+ */
485
+ shift(): T | undefined;
486
+ /**
487
+ * Shuffle the items in the collection
488
+ */
489
+ shuffle(): Collection$1<T>;
490
+ /**
491
+ * Slice the underlying collection array
492
+ */
493
+ slice(start: number, length?: number): Collection$1<T>;
494
+ /**
495
+ * Sort through each item with a callback
496
+ */
497
+ sort(callback?: (a: T, b: T) => number): Collection$1<T>;
498
+ /**
499
+ * Sort the collection by the given key
500
+ */
501
+ sortBy(key: keyof T | ((item: T) => any)): Collection$1<T>;
502
+ /**
503
+ * Sort the collection in descending order by the given key
504
+ */
505
+ sortByDesc(key: keyof T | ((item: T) => any)): Collection$1<T>;
506
+ /**
507
+ * Splice a portion of the underlying collection array
508
+ */
509
+ splice(start: number, length?: number, ...items: T[]): Collection$1<T>;
510
+ /**
511
+ * Get the sum of the given values
512
+ */
513
+ sum(key?: keyof T | ((item: T) => number)): number;
514
+ /**
515
+ * Take the first or last {limit} items
516
+ */
517
+ take(limit: number): Collection$1<T>;
518
+ /**
519
+ * Pass the collection to the given callback and return the result
520
+ */
521
+ pipe<U>(callback: (collection: Collection$1<T>) => U): U;
522
+ /**
523
+ * Pass the collection to the given callback and then return it
524
+ */
525
+ tap(callback: (collection: Collection$1<T>) => void): this;
526
+ /**
527
+ * Transform each item in the collection using a callback
528
+ */
529
+ transform(callback: (item: T, key: number) => T): this;
530
+ /**
531
+ * Return only unique items from the collection array
532
+ */
533
+ unique(key?: keyof T): Collection$1<T>;
534
+ /**
535
+ * Reset the keys on the underlying array
536
+ */
537
+ values(): Collection$1<T>;
538
+ /**
539
+ * Filter items by the given key value pair
540
+ */
541
+ where(key: keyof T, value: any): Collection$1<T>;
542
+ where(key: keyof T, operator: string, value: any): Collection$1<T>;
543
+ /**
544
+ * Filter items by the given key value pair using loose comparison
545
+ */
546
+ whereIn(key: keyof T, values: any[]): Collection$1<T>;
547
+ /**
548
+ * Filter items by the given key value pair using loose comparison
549
+ */
550
+ whereNotIn(key: keyof T, values: any[]): Collection$1<T>;
551
+ /**
552
+ * Zip the collection together with one or more arrays
553
+ */
554
+ zip<U>(...arrays: U[][]): Collection$1<any[]>;
555
+ /**
556
+ * Convert the collection to a plain array
557
+ */
558
+ toArray(): T[];
559
+ /**
560
+ * Convert the collection to JSON
561
+ */
562
+ toJson(): string;
563
+ /**
564
+ * Get the collection as a string
565
+ */
566
+ toString(): string;
567
+ }
568
+ /**
569
+ * Helper function to create a new collection
570
+ */
571
+ declare function collect<T>(items?: T[]): Collection$1<T>;
572
+
573
+ /**
574
+ * Laravel-style Map Collection class
575
+ * Provides collection methods for Map data structures
576
+ */
577
+ declare class MapCollection<K = any, V = any> {
578
+ private internalMap;
579
+ constructor(entries?: Iterable<[K, V]> | Record<string, V>);
580
+ /**
581
+ * Create a new map collection instance
582
+ */
583
+ static make<K, V>(entries?: Iterable<[K, V]> | Record<string, V>): MapCollection<K, V>;
584
+ /**
585
+ * Get all entries as an array of [key, value] pairs
586
+ */
587
+ all(): [K, V][];
588
+ /**
589
+ * Get the number of items in the map
590
+ */
591
+ count(): number;
592
+ /**
593
+ * Get the number of items in the map (alias for count)
594
+ */
595
+ size(): number;
596
+ /**
597
+ * Determine if the map is empty
598
+ */
599
+ isEmpty(): boolean;
600
+ /**
601
+ * Determine if the map is not empty
602
+ */
603
+ isNotEmpty(): boolean;
604
+ /**
605
+ * Determine if a key exists in the map
606
+ */
607
+ has(key: K): boolean;
608
+ /**
609
+ * Get a value from the map by key
610
+ */
611
+ get(key: K, defaultValue?: V): V | undefined;
612
+ /**
613
+ * Set a value in the map
614
+ */
615
+ set(key: K, value: V): this;
616
+ /**
617
+ * Put a value in the map (alias for set)
618
+ */
619
+ put(key: K, value: V): this;
620
+ /**
621
+ * Remove a key from the map
622
+ */
623
+ delete(key: K): boolean;
624
+ /**
625
+ * Remove a key from the map (alias for delete)
626
+ */
627
+ forget(key: K): boolean;
628
+ /**
629
+ * Remove all items from the map
630
+ */
631
+ clear(): this;
632
+ /**
633
+ * Get all keys from the map
634
+ */
635
+ keys(): K[];
636
+ /**
637
+ * Get all values from the map
638
+ */
639
+ values(): V[];
640
+ /**
641
+ * Execute a callback over each item
642
+ */
643
+ each(callback: (value: V, key: K) => void | false): this;
644
+ /**
645
+ * Run a map over each of the items
646
+ */
647
+ mapValues<U>(callback: (value: V, key: K) => U): MapCollection<K, U>;
648
+ /**
649
+ * Run a filter over each of the items
650
+ */
651
+ filter(callback: (value: V, key: K) => boolean): MapCollection<K, V>;
652
+ /**
653
+ * Determine if all items pass the given test
654
+ */
655
+ every(callback: (value: V, key: K) => boolean): boolean;
656
+ /**
657
+ * Determine if any item passes the given test
658
+ */
659
+ some(callback: (value: V, key: K) => boolean): boolean;
660
+ /**
661
+ * Get the first value that passes the given test
662
+ */
663
+ first(callback?: (value: V, key: K) => boolean): V | undefined;
664
+ /**
665
+ * Get the last value that passes the given test
666
+ */
667
+ last(callback?: (value: V, key: K) => boolean): V | undefined;
668
+ /**
669
+ * Reduce the map to a single value
670
+ */
671
+ reduce<U>(callback: (carry: U, value: V, key: K) => U, initial: U): U;
672
+ /**
673
+ * Merge another map into this one
674
+ */
675
+ merge(other: MapCollection<K, V> | Map<K, V> | Record<string, V>): this;
676
+ /**
677
+ * Get only the specified keys
678
+ */
679
+ only(keys: K[]): MapCollection<K, V>;
680
+ /**
681
+ * Get all items except the specified keys
682
+ */
683
+ except(keys: K[]): MapCollection<K, V>;
684
+ /**
685
+ * Flip the keys and values
686
+ */
687
+ flip(): MapCollection<V, K>;
688
+ /**
689
+ * Pass the map to the given callback and return the result
690
+ */
691
+ pipe<U>(callback: (map: MapCollection<K, V>) => U): U;
692
+ /**
693
+ * Pass the map to the given callback and then return it
694
+ */
695
+ tap(callback: (map: MapCollection<K, V>) => void): this;
696
+ /**
697
+ * Convert the map to a plain object
698
+ */
699
+ toObject(): Record<string, V>;
700
+ /**
701
+ * Convert the map to an array of [key, value] pairs
702
+ */
703
+ toArray(): [K, V][];
704
+ /**
705
+ * Convert the map to JSON
706
+ */
707
+ toJson(): string;
708
+ /**
709
+ * Get the map as a string
710
+ */
711
+ toString(): string;
712
+ /**
713
+ * Get the underlying Map instance
714
+ */
715
+ toMap(): Map<K, V>;
716
+ }
717
+ /**
718
+ * Helper function to create a new map collection
719
+ */
720
+ declare function collectMap<K, V>(entries?: Iterable<[K, V]> | Record<string, V>): MapCollection<K, V>;
721
+
722
+ /**
723
+ * Laravel-style Set Collection class
724
+ * Provides collection methods for Set data structures
725
+ */
726
+ declare class SetCollection<T = any> {
727
+ private set;
728
+ constructor(items?: Iterable<T>);
729
+ /**
730
+ * Create a new set collection instance
731
+ */
732
+ static make<T>(items?: Iterable<T>): SetCollection<T>;
733
+ /**
734
+ * Get all items as an array
735
+ */
736
+ all(): T[];
737
+ /**
738
+ * Get the number of items in the set
739
+ */
740
+ count(): number;
741
+ /**
742
+ * Get the number of items in the set (alias for count)
743
+ */
744
+ size(): number;
745
+ /**
746
+ * Determine if the set is empty
747
+ */
748
+ isEmpty(): boolean;
749
+ /**
750
+ * Determine if the set is not empty
751
+ */
752
+ isNotEmpty(): boolean;
753
+ /**
754
+ * Determine if an item exists in the set
755
+ */
756
+ has(item: T): boolean;
757
+ /**
758
+ * Determine if an item exists in the set (alias for has)
759
+ */
760
+ contains(item: T): boolean;
761
+ /**
762
+ * Add an item to the set
763
+ */
764
+ add(item: T): this;
765
+ /**
766
+ * Add an item to the set (alias for add)
767
+ */
768
+ push(item: T): this;
769
+ /**
770
+ * Remove an item from the set
771
+ */
772
+ delete(item: T): boolean;
773
+ /**
774
+ * Remove an item from the set (alias for delete)
775
+ */
776
+ forget(item: T): boolean;
777
+ /**
778
+ * Remove all items from the set
779
+ */
780
+ clear(): this;
781
+ /**
782
+ * Execute a callback over each item
783
+ */
784
+ each(callback: (item: T, index: number) => void | false): this;
785
+ /**
786
+ * Run a map over each of the items
787
+ */
788
+ map<U>(callback: (item: T, index: number) => U): SetCollection<U>;
789
+ /**
790
+ * Run a filter over each of the items
791
+ */
792
+ filter(callback: (item: T, index: number) => boolean): SetCollection<T>;
793
+ /**
794
+ * Determine if all items pass the given test
795
+ */
796
+ every(callback: (item: T, index: number) => boolean): boolean;
797
+ /**
798
+ * Determine if any item passes the given test
799
+ */
800
+ some(callback: (item: T, index: number) => boolean): boolean;
801
+ /**
802
+ * Get the first item that passes the given test
803
+ */
804
+ first(callback?: (item: T, index: number) => boolean): T | undefined;
805
+ /**
806
+ * Get the last item that passes the given test
807
+ */
808
+ last(callback?: (item: T, index: number) => boolean): T | undefined;
809
+ /**
810
+ * Reduce the set to a single value
811
+ */
812
+ reduce<U>(callback: (carry: U, item: T, index: number) => U, initial: U): U;
813
+ /**
814
+ * Merge another set into this one
815
+ */
816
+ merge(other: SetCollection<T> | Set<T> | T[]): this;
817
+ /**
818
+ * Get the union of this set and another
819
+ */
820
+ union(other: SetCollection<T> | Set<T> | T[]): SetCollection<T>;
821
+ /**
822
+ * Get the intersection of this set and another
823
+ */
824
+ intersect(other: SetCollection<T> | Set<T> | T[]): SetCollection<T>;
825
+ /**
826
+ * Get the difference between this set and another
827
+ */
828
+ diff(other: SetCollection<T> | Set<T> | T[]): SetCollection<T>;
829
+ /**
830
+ * Get items that are in either set but not in both
831
+ */
832
+ symmetricDiff(other: SetCollection<T> | Set<T> | T[]): SetCollection<T>;
833
+ /**
834
+ * Determine if this set is a subset of another
835
+ */
836
+ isSubsetOf(other: SetCollection<T> | Set<T> | T[]): boolean;
837
+ /**
838
+ * Determine if this set is a superset of another
839
+ */
840
+ isSupersetOf(other: SetCollection<T> | Set<T> | T[]): boolean;
841
+ /**
842
+ * Pass the set to the given callback and return the result
843
+ */
844
+ pipe<U>(callback: (set: SetCollection<T>) => U): U;
845
+ /**
846
+ * Pass the set to the given callback and then return it
847
+ */
848
+ tap(callback: (set: SetCollection<T>) => void): this;
849
+ /**
850
+ * Convert the set to an array
851
+ */
852
+ toArray(): T[];
853
+ /**
854
+ * Convert the set to JSON
855
+ */
856
+ toJson(): string;
857
+ /**
858
+ * Get the set as a string
859
+ */
860
+ toString(): string;
861
+ /**
862
+ * Get the underlying Set instance
863
+ */
864
+ toSet(): Set<T>;
865
+ }
866
+ /**
867
+ * Helper function to create a new set collection
868
+ */
869
+ declare function collectSet<T>(items?: Iterable<T>): SetCollection<T>;
870
+
871
+ /**
872
+ * @fileoverview Base registry implementation
873
+ *
874
+ * This file provides a generic base registry class that uses the Collection
875
+ * interface for storage. It provides a consistent API for all registry
876
+ * implementations across the application.
877
+ *
878
+ * Key Features:
879
+ * - Generic type support for any item type
880
+ * - Default item support (fallback when item not found)
881
+ * - Validation hooks (before add, after add)
882
+ * - Collection-based storage (efficient O(1) operations)
883
+ * - Type-safe API
884
+ * - Consistent interface across all registries
885
+ *
886
+ * Use Cases:
887
+ * - Theme registry (storing and retrieving themes)
888
+ * - Token registry (managing design tokens)
889
+ * - Plugin registry (managing plugins)
890
+ * - Configuration registry (storing configs)
891
+ * - Any key-value registry needs
892
+ *
893
+ * @module @pixielity/support
894
+ * @category Registries
895
+ */
896
+ /**
897
+ * Collection interface for registry storage
898
+ */
899
+ interface Collection<T> {
900
+ add(key: string, value: T): void;
901
+ get(key: string): T | undefined;
902
+ getAll(): T[];
903
+ getKeys(): string[];
904
+ getAsRecord(): Record<string, T>;
905
+ has(key: string): boolean;
906
+ remove(key: string): boolean;
907
+ clear(): void;
908
+ size(): number;
909
+ isEmpty(): boolean;
910
+ forEach(callback: (value: T, key: string) => void): void;
911
+ map<U>(callback: (value: T, key: string) => U): U[];
912
+ filter(predicate: (value: T, key: string) => boolean): T[];
913
+ find(predicate: (value: T, key: string) => boolean): T | undefined;
914
+ }
915
+ /**
916
+ * Validation result for registry operations
917
+ *
918
+ * Used by validation hooks to indicate whether an operation
919
+ * should proceed or be rejected.
920
+ *
921
+ * @example
922
+ * ```typescript
923
+ * const result: ValidationResult = {
924
+ * valid: false,
925
+ * error: 'Item name cannot be empty'
926
+ * };
927
+ * ```
928
+ */
929
+ interface ValidationResult {
930
+ /**
931
+ * Whether the validation passed
932
+ */
933
+ valid: boolean;
934
+ /**
935
+ * Error message if validation failed
936
+ */
937
+ error?: string;
938
+ }
939
+ /**
940
+ * Base registry options
941
+ *
942
+ * Configuration options for creating a registry instance.
943
+ * Allows customization of default item behavior and validation.
944
+ *
945
+ * @template T - The type of items stored in the registry
946
+ */
947
+ interface BaseRegistryOptions<T> {
948
+ /**
949
+ * Default item to return when requested item is not found
950
+ *
951
+ * If not provided, get() will return undefined for missing items.
952
+ * If provided, get() will return this default item instead.
953
+ */
954
+ defaultItem?: T;
955
+ /**
956
+ * Validation hook called before adding an item
957
+ *
958
+ * Allows custom validation logic before items are added to the registry.
959
+ * If validation fails, the item will not be added and an error will be thrown.
960
+ *
961
+ * @param key - Item key
962
+ * @param item - Item to validate
963
+ * @returns Validation result
964
+ */
965
+ validateBeforeAdd?: (key: string, item: T) => ValidationResult;
966
+ /**
967
+ * Hook called after an item is successfully added
968
+ *
969
+ * Useful for side effects like logging, notifications, or triggering
970
+ * dependent updates after an item is registered.
971
+ *
972
+ * @param key - Item key
973
+ * @param item - Item that was added
974
+ */
975
+ afterAdd?: (key: string, item: T) => void;
976
+ }
977
+ /**
978
+ * Base registry class
979
+ *
980
+ * A generic registry implementation that provides a consistent API for
981
+ * storing and retrieving items by key. Uses the Collection interface
982
+ * for efficient storage with O(1) operations.
983
+ *
984
+ * This class extends Collection functionality by adding:
985
+ * - Default item support
986
+ * - Validation hooks
987
+ * - Consistent registry API
988
+ *
989
+ * All Collection methods are directly accessible on the registry instance.
990
+ *
991
+ * Performance Characteristics:
992
+ * - register(): O(1) + validation time
993
+ * - get(): O(1)
994
+ * - has(): O(1)
995
+ * - remove(): O(1)
996
+ * - getAll(): O(n)
997
+ * - clear(): O(1)
998
+ *
999
+ * @template T - The type of items stored in the registry
1000
+ *
1001
+ * @example
1002
+ * ```typescript
1003
+ * // Create a theme registry
1004
+ * const themeRegistry = new BaseRegistry<Theme>({
1005
+ * defaultItem: defaultTheme,
1006
+ * validateBeforeAdd: (key, theme) => {
1007
+ * if (!theme.name) {
1008
+ * return { valid: false, error: 'Theme must have a name' };
1009
+ * }
1010
+ * return { valid: true };
1011
+ * }
1012
+ * });
1013
+ *
1014
+ * // Register themes
1015
+ * themeRegistry.register('blue', blueTheme);
1016
+ * themeRegistry.register('red', redTheme);
1017
+ *
1018
+ * // Get a theme
1019
+ * const theme = themeRegistry.get('blue');
1020
+ *
1021
+ * // Get all themes
1022
+ * const allThemes = themeRegistry.getAll();
1023
+ *
1024
+ * // Check if theme exists
1025
+ * if (themeRegistry.has('blue')) {
1026
+ * console.log('Blue theme exists');
1027
+ * }
1028
+ * ```
1029
+ *
1030
+ * @example
1031
+ * ```typescript
1032
+ * // Create a simple token registry
1033
+ * const tokenRegistry = new BaseRegistry<Token>();
1034
+ *
1035
+ * tokenRegistry.register('primary', { value: '#0000FF' });
1036
+ * tokenRegistry.register('secondary', { value: '#FF0000' });
1037
+ *
1038
+ * const allTokens = tokenRegistry.getAll();
1039
+ * console.log(allTokens.length); // 2
1040
+ * ```
1041
+ */
1042
+ declare class BaseRegistry<T> implements Collection<T> {
1043
+ /**
1044
+ * Internal collection for storing registry items
1045
+ *
1046
+ * Uses Collection interface for flexible storage implementation.
1047
+ * By default, uses MapCollection for O(1) operations.
1048
+ */
1049
+ protected collection: Collection<T>;
1050
+ /**
1051
+ * Default item to return when requested item is not found
1052
+ *
1053
+ * If set, get() will return this item instead of undefined
1054
+ * when the requested key doesn't exist in the registry.
1055
+ */
1056
+ protected defaultItem?: T;
1057
+ /**
1058
+ * Validation hook called before adding an item
1059
+ *
1060
+ * If provided, this function is called before every register()
1061
+ * operation to validate the item. If validation fails, the
1062
+ * item is not added and an error is thrown.
1063
+ */
1064
+ protected validateBeforeAdd?: (key: string, item: T) => ValidationResult;
1065
+ /**
1066
+ * Hook called after an item is successfully added
1067
+ *
1068
+ * If provided, this function is called after every successful
1069
+ * register() operation. Useful for side effects like logging
1070
+ * or triggering dependent updates.
1071
+ */
1072
+ protected afterAdd?: (key: string, item: T) => void;
1073
+ /**
1074
+ * Creates a new BaseRegistry instance
1075
+ *
1076
+ * Initializes the registry with optional configuration for default
1077
+ * item and validation hooks. By default, uses MapCollection for storage.
1078
+ *
1079
+ * @param options - Registry configuration options
1080
+ *
1081
+ * @example
1082
+ * ```typescript
1083
+ * // Simple registry without options
1084
+ * const registry = new BaseRegistry<Theme>();
1085
+ * ```
1086
+ *
1087
+ * @example
1088
+ * ```typescript
1089
+ * // Registry with default item
1090
+ * const registry = new BaseRegistry<Theme>({
1091
+ * defaultItem: defaultTheme
1092
+ * });
1093
+ * ```
1094
+ *
1095
+ * @example
1096
+ * ```typescript
1097
+ * // Registry with validation
1098
+ * const registry = new BaseRegistry<Theme>({
1099
+ * validateBeforeAdd: (key, theme) => {
1100
+ * if (!theme.name) {
1101
+ * return { valid: false, error: 'Theme must have a name' };
1102
+ * }
1103
+ * return { valid: true };
1104
+ * },
1105
+ * afterAdd: (key, theme) => {
1106
+ * console.log(`Registered theme: ${theme.name}`);
1107
+ * }
1108
+ * });
1109
+ * ```
1110
+ */
1111
+ constructor(options?: BaseRegistryOptions<T>);
1112
+ /**
1113
+ * Register an item in the registry
1114
+ *
1115
+ * Adds or updates an item in the registry with the specified key.
1116
+ * If an item with the same key already exists, it will be replaced.
1117
+ *
1118
+ * If a validation hook is configured, it will be called before adding
1119
+ * the item. If validation fails, an error is thrown and the item is
1120
+ * not added.
1121
+ *
1122
+ * If an afterAdd hook is configured, it will be called after the item
1123
+ * is successfully added.
1124
+ *
1125
+ * Time Complexity: O(1) + validation time
1126
+ *
1127
+ * @param key - Unique identifier for the item
1128
+ * @param item - Item to register
1129
+ * @throws Error if validation fails
1130
+ *
1131
+ * @example
1132
+ * ```typescript
1133
+ * const registry = new BaseRegistry<Theme>();
1134
+ *
1135
+ * // Register a theme
1136
+ * registry.register('blue', {
1137
+ * name: 'Blue',
1138
+ * colors: { accent: '#0000FF' }
1139
+ * });
1140
+ *
1141
+ * // Update existing theme
1142
+ * registry.register('blue', {
1143
+ * name: 'Blue',
1144
+ * colors: { accent: '#0066FF' }
1145
+ * });
1146
+ * ```
1147
+ */
1148
+ register(key: string, item: T): void;
1149
+ /**
1150
+ * Add an item to the collection (alias for register)
1151
+ *
1152
+ * This method is part of the Collection interface.
1153
+ * It delegates to register() to ensure validation hooks are called.
1154
+ *
1155
+ * Time Complexity: O(1) + validation time
1156
+ *
1157
+ * @param key - Unique identifier for the item
1158
+ * @param value - Item to add
1159
+ */
1160
+ add(key: string, value: T): void;
1161
+ /**
1162
+ * Get an item from the registry
1163
+ *
1164
+ * Retrieves an item by its key. If the item doesn't exist:
1165
+ * - Returns the default item if one was configured
1166
+ * - Returns undefined if no default item was configured
1167
+ *
1168
+ * Time Complexity: O(1)
1169
+ *
1170
+ * @param key - Item identifier
1171
+ * @returns Item if found, default item if configured, or undefined
1172
+ *
1173
+ * @example
1174
+ * ```typescript
1175
+ * const theme = registry.get('blue');
1176
+ * ```
1177
+ */
1178
+ get(key: string): T | undefined;
1179
+ /**
1180
+ * Get all items in the registry
1181
+ *
1182
+ * Returns an array containing all items in the registry.
1183
+ * The order of items depends on the collection implementation
1184
+ * (MapCollection maintains insertion order).
1185
+ *
1186
+ * Time Complexity: O(n) where n is the number of items
1187
+ *
1188
+ * @returns Array of all items in the registry
1189
+ *
1190
+ * @example
1191
+ * ```typescript
1192
+ * const allThemes = registry.getAll();
1193
+ * ```
1194
+ */
1195
+ getAll(): T[];
1196
+ /**
1197
+ * Get all keys in the registry
1198
+ *
1199
+ * Returns an array containing all keys in the registry.
1200
+ * Useful for iteration or checking what items are registered.
1201
+ *
1202
+ * Time Complexity: O(n) where n is the number of items
1203
+ *
1204
+ * @returns Array of all keys in the registry
1205
+ *
1206
+ * @example
1207
+ * ```typescript
1208
+ * const keys = registry.getKeys();
1209
+ * ```
1210
+ */
1211
+ getKeys(): string[];
1212
+ /**
1213
+ * Get registry as a record object
1214
+ *
1215
+ * Converts the registry to a plain JavaScript object (record)
1216
+ * with keys mapping to values. Useful for serialization.
1217
+ *
1218
+ * Time Complexity: O(n) where n is the number of items
1219
+ *
1220
+ * @returns Record object with keys mapping to values
1221
+ *
1222
+ * @example
1223
+ * ```typescript
1224
+ * const record = registry.getAsRecord();
1225
+ * ```
1226
+ */
1227
+ getAsRecord(): Record<string, T>;
1228
+ /**
1229
+ * Check if an item is registered
1230
+ *
1231
+ * Checks whether an item with the specified key exists in the registry.
1232
+ * Does not check the value, only the presence of the key.
1233
+ *
1234
+ * Time Complexity: O(1)
1235
+ *
1236
+ * @param key - Item identifier to check
1237
+ * @returns True if item is registered, false otherwise
1238
+ *
1239
+ * @example
1240
+ * ```typescript
1241
+ * if (registry.has('blue')) {
1242
+ * console.log('Blue theme exists');
1243
+ * }
1244
+ * ```
1245
+ */
1246
+ has(key: string): boolean;
1247
+ /**
1248
+ * Remove an item from the registry
1249
+ *
1250
+ * Removes an item with the specified key from the registry.
1251
+ * Returns true if the item was removed, false if it didn't exist.
1252
+ *
1253
+ * Time Complexity: O(1)
1254
+ *
1255
+ * @param key - Item identifier to remove
1256
+ * @returns True if item was removed, false if it didn't exist
1257
+ *
1258
+ * @example
1259
+ * ```typescript
1260
+ * const removed = registry.remove('blue');
1261
+ * ```
1262
+ */
1263
+ remove(key: string): boolean;
1264
+ /**
1265
+ * Clear all items from the registry
1266
+ *
1267
+ * Removes all items from the registry, leaving it empty.
1268
+ * This operation is irreversible.
1269
+ *
1270
+ * Time Complexity: O(1)
1271
+ *
1272
+ * @example
1273
+ * ```typescript
1274
+ * registry.clear();
1275
+ * ```
1276
+ */
1277
+ clear(): void;
1278
+ /**
1279
+ * Get the number of items in the registry
1280
+ *
1281
+ * Returns the total count of items currently registered.
1282
+ *
1283
+ * Time Complexity: O(1)
1284
+ *
1285
+ * @returns Number of items in the registry
1286
+ *
1287
+ * @example
1288
+ * ```typescript
1289
+ * console.log(registry.size()); // 2
1290
+ * ```
1291
+ */
1292
+ size(): number;
1293
+ /**
1294
+ * Check if the registry is empty
1295
+ *
1296
+ * Returns true if the registry contains no items, false otherwise.
1297
+ * This is a convenience method equivalent to checking if size() === 0.
1298
+ *
1299
+ * Time Complexity: O(1)
1300
+ *
1301
+ * @returns True if registry has no items, false otherwise
1302
+ *
1303
+ * @example
1304
+ * ```typescript
1305
+ * console.log(registry.isEmpty()); // true
1306
+ * ```
1307
+ */
1308
+ isEmpty(): boolean;
1309
+ /**
1310
+ * Iterate over all items in the registry
1311
+ *
1312
+ * Executes a callback function for each item in the registry.
1313
+ * Items are iterated in insertion order (for MapCollection).
1314
+ *
1315
+ * Time Complexity: O(n) where n is the number of items
1316
+ *
1317
+ * @param callback - Function to call for each item (value, key)
1318
+ *
1319
+ * @example
1320
+ * ```typescript
1321
+ * registry.forEach((theme, key) => {
1322
+ * console.log(`${key}: ${theme.name}`);
1323
+ * });
1324
+ * ```
1325
+ */
1326
+ forEach(callback: (value: T, key: string) => void): void;
1327
+ /**
1328
+ * Map over all items in the registry
1329
+ *
1330
+ * Transforms each item in the registry using a callback function
1331
+ * and returns an array of the transformed values.
1332
+ *
1333
+ * Time Complexity: O(n) where n is the number of items
1334
+ *
1335
+ * @template U - The type of the transformed items
1336
+ * @param callback - Function to transform each item (value, key) => U
1337
+ * @returns Array of transformed items
1338
+ *
1339
+ * @example
1340
+ * ```typescript
1341
+ * const names = registry.map(theme => theme.name);
1342
+ * ```
1343
+ */
1344
+ map<U>(callback: (value: T, key: string) => U): U[];
1345
+ /**
1346
+ * Filter items in the registry
1347
+ *
1348
+ * Returns an array of items that pass the test implemented by the
1349
+ * provided predicate function.
1350
+ *
1351
+ * Time Complexity: O(n) where n is the number of items
1352
+ *
1353
+ * @param predicate - Function to test each item (value, key) => boolean
1354
+ * @returns Array of items that pass the test
1355
+ *
1356
+ * @example
1357
+ * ```typescript
1358
+ * const darkThemes = registry.filter(theme => theme.isDark);
1359
+ * ```
1360
+ */
1361
+ filter(predicate: (value: T, key: string) => boolean): T[];
1362
+ /**
1363
+ * Find an item in the registry
1364
+ *
1365
+ * Returns the first item that satisfies the provided predicate function.
1366
+ * Returns undefined if no item passes the test.
1367
+ *
1368
+ * Time Complexity: O(n) worst case, O(1) best case
1369
+ *
1370
+ * @param predicate - Function to test each item (value, key) => boolean
1371
+ * @returns First item that passes the test, or undefined
1372
+ *
1373
+ * @example
1374
+ * ```typescript
1375
+ * const defaultTheme = registry.find(theme => theme.isDefault);
1376
+ * ```
1377
+ */
1378
+ find(predicate: (value: T, key: string) => boolean): T | undefined;
1379
+ }
1380
+
1381
+ /**
1382
+ * @fileoverview Facade interfaces
1383
+ *
1384
+ * Defines the interfaces for the Facade pattern implementation.
1385
+ * Facades provide a static interface to services resolved from the DI container.
1386
+ *
1387
+ * @module @abdokouta/react-support
1388
+ * @category Facades
1389
+ */
1390
+ /**
1391
+ * Application interface for facade resolution
1392
+ *
1393
+ * This interface represents the minimal contract that an application/container
1394
+ * must implement to work with facades. It mirrors the Laravel Application contract.
1395
+ */
1396
+ interface FacadeApplication {
1397
+ /**
1398
+ * Resolve a service from the container
1399
+ *
1400
+ * @param abstract - Service identifier (string, symbol, or class)
1401
+ * @returns The resolved service instance
1402
+ */
1403
+ get<T>(abstract: string | symbol | (new (...args: unknown[]) => T)): T;
1404
+ /**
1405
+ * Check if a service has been resolved
1406
+ *
1407
+ * @param abstract - Service identifier
1408
+ * @returns True if the service has been resolved
1409
+ */
1410
+ resolved?(abstract: string | symbol): boolean;
1411
+ /**
1412
+ * Register a callback to run after a service is resolved
1413
+ *
1414
+ * @param abstract - Service identifier
1415
+ * @param callback - Callback to run after resolution
1416
+ */
1417
+ afterResolving?(abstract: string | symbol, callback: (service: unknown, app: FacadeApplication) => void): void;
1418
+ /**
1419
+ * Bind an instance to the container
1420
+ *
1421
+ * @param abstract - Service identifier
1422
+ * @param instance - Instance to bind
1423
+ */
1424
+ instance?(abstract: string | symbol, instance: unknown): void;
1425
+ }
1426
+ /**
1427
+ * Fake interface for testing
1428
+ *
1429
+ * Facades can be swapped with fakes for testing purposes.
1430
+ * Any object implementing this interface is considered a fake.
1431
+ */
1432
+ interface Fake {
1433
+ /**
1434
+ * Marker to identify fake instances
1435
+ */
1436
+ readonly __isFake: true;
1437
+ }
1438
+ /**
1439
+ * Check if an object is a Fake
1440
+ *
1441
+ * @param obj - Object to check
1442
+ * @returns True if the object is a Fake
1443
+ */
1444
+ declare function isFake(obj: unknown): obj is Fake;
1445
+
1446
+ /**
1447
+ * @fileoverview Base Facade implementation
1448
+ *
1449
+ * This file provides the base Facade class that enables static access to
1450
+ * services resolved from the DI container. Inspired by Laravel's Facade pattern.
1451
+ *
1452
+ * Uses @abdokouta/react-di's getModuleContainer to resolve services,
1453
+ * enabling facades to work outside of React components.
1454
+ *
1455
+ * Key Features:
1456
+ * - Static interface to container-resolved services
1457
+ * - Instance caching for performance
1458
+ * - Hot-swapping for testing
1459
+ * - Fake detection for test assertions
1460
+ * - Works outside React components
1461
+ *
1462
+ * @module @abdokouta/react-support
1463
+ * @category Facades
1464
+ */
1465
+
1466
+ /**
1467
+ * Base Facade class
1468
+ *
1469
+ * Provides a static interface to services resolved from the DI container.
1470
+ * Subclasses must implement `getFacadeAccessor()` to specify which service
1471
+ * the facade represents.
1472
+ *
1473
+ * @example
1474
+ * ```typescript
1475
+ * import { Facade } from '@abdokouta/react-support';
1476
+ * import { LoggerService } from './logger.service';
1477
+ * import { AppModule } from './app.module';
1478
+ *
1479
+ * class Log extends Facade {
1480
+ * protected static getFacadeAccessor(): ServiceIdentifier {
1481
+ * return LoggerService;
1482
+ * }
1483
+ * }
1484
+ *
1485
+ * // Set the module once at app bootstrap
1486
+ * Facade.setFacadeModule(AppModule);
1487
+ *
1488
+ * // Use the facade statically anywhere
1489
+ * Log.info('Hello, world!');
1490
+ * Log.error('Something went wrong');
1491
+ * ```
1492
+ *
1493
+ * @example
1494
+ * ```typescript
1495
+ * // Swap with a fake for testing
1496
+ * const fakeLogs: string[] = [];
1497
+ * const fakeLogger = {
1498
+ * __isFake: true as const,
1499
+ * info: (msg: string) => fakeLogs.push(msg),
1500
+ * error: (msg: string) => fakeLogs.push(msg),
1501
+ * };
1502
+ *
1503
+ * Log.swap(fakeLogger);
1504
+ * Log.info('Test message');
1505
+ * expect(fakeLogs).toContain('Test message');
1506
+ * ```
1507
+ */
1508
+ declare abstract class Facade {
1509
+ /**
1510
+ * The root module class for resolving services
1511
+ */
1512
+ protected static moduleClass: Newable | null;
1513
+ /**
1514
+ * The module container instance (cached)
1515
+ */
1516
+ protected static container: ModuleContainer | null;
1517
+ /**
1518
+ * The resolved object instances
1519
+ *
1520
+ * Caches resolved instances by their accessor key for performance.
1521
+ */
1522
+ protected static resolvedInstance: Map<string | symbol, unknown>;
1523
+ /**
1524
+ * Indicates if the resolved instance should be cached
1525
+ *
1526
+ * Set to false in subclasses to always resolve fresh instances.
1527
+ */
1528
+ protected static cached: boolean;
1529
+ /**
1530
+ * Hotswap the underlying instance behind the facade
1531
+ *
1532
+ * Useful for testing - swap the real service with a mock or fake.
1533
+ *
1534
+ * @param instance - Instance to swap in
1535
+ *
1536
+ * @example
1537
+ * ```typescript
1538
+ * // In tests
1539
+ * const mockLogger = { info: vi.fn(), error: vi.fn() };
1540
+ * Log.swap(mockLogger);
1541
+ *
1542
+ * // Now Log.info() calls mockLogger.info()
1543
+ * Log.info('test');
1544
+ * expect(mockLogger.info).toHaveBeenCalledWith('test');
1545
+ * ```
1546
+ */
1547
+ static swap(instance: unknown): void;
1548
+ /**
1549
+ * Determines whether a "fake" has been set as the facade instance
1550
+ *
1551
+ * @returns True if the current instance is a Fake
1552
+ *
1553
+ * @example
1554
+ * ```typescript
1555
+ * if (Log.isFake()) {
1556
+ * console.log('Using fake logger');
1557
+ * }
1558
+ * ```
1559
+ */
1560
+ static isFake(): boolean;
1561
+ /**
1562
+ * Get the root object behind the facade
1563
+ *
1564
+ * Resolves and returns the actual service instance.
1565
+ *
1566
+ * @returns The resolved service instance
1567
+ */
1568
+ static getFacadeRoot<T = unknown>(): T;
1569
+ /**
1570
+ * Get the registered name of the component
1571
+ *
1572
+ * Subclasses MUST override this method to specify which service
1573
+ * the facade represents.
1574
+ *
1575
+ * @returns Service identifier (string, symbol, or class)
1576
+ * @throws Error if not implemented
1577
+ *
1578
+ * @example
1579
+ * ```typescript
1580
+ * class Log extends Facade {
1581
+ * protected static getFacadeAccessor(): ServiceIdentifier {
1582
+ * return LoggerService; // or 'logger' string token
1583
+ * }
1584
+ * }
1585
+ * ```
1586
+ */
1587
+ protected static getFacadeAccessor(): ServiceIdentifier;
1588
+ /**
1589
+ * Get a consistent key for the accessor
1590
+ */
1591
+ protected static getAccessorKey(accessor: ServiceIdentifier): string | symbol;
1592
+ /**
1593
+ * Resolve the facade root instance from the container
1594
+ *
1595
+ * @param identifier - Service identifier
1596
+ * @returns Resolved service instance
1597
+ */
1598
+ protected static resolveFacadeInstance<T>(identifier: ServiceIdentifier<T>): T;
1599
+ /**
1600
+ * Get the module container
1601
+ *
1602
+ * @returns The module container instance
1603
+ */
1604
+ protected static getContainer(): ModuleContainer | null;
1605
+ /**
1606
+ * Clear a resolved facade instance
1607
+ *
1608
+ * @param name - Service identifier to clear (defaults to this facade's accessor)
1609
+ */
1610
+ static clearResolvedInstance(name?: string | symbol): void;
1611
+ /**
1612
+ * Clear all resolved instances
1613
+ *
1614
+ * Useful for test cleanup.
1615
+ */
1616
+ static clearResolvedInstances(): void;
1617
+ /**
1618
+ * Get the module class
1619
+ *
1620
+ * @returns The module class
1621
+ */
1622
+ static getFacadeModule(): Newable | null;
1623
+ /**
1624
+ * Set the module class for facade resolution
1625
+ *
1626
+ * Must be called during application bootstrap to enable facades.
1627
+ * Call this AFTER Inversiland.run() or Container.configure().build().
1628
+ *
1629
+ * @param module - The root module class
1630
+ *
1631
+ * @example
1632
+ * ```typescript
1633
+ * // In your app bootstrap (main.tsx)
1634
+ * import { Facade } from '@abdokouta/react-support';
1635
+ * import { Container, ContainerProvider } from '@abdokouta/react-di';
1636
+ * import { AppModule } from './app.module';
1637
+ *
1638
+ * // Initialize container
1639
+ * Container.configure().withModule(AppModule).withDefaults().build();
1640
+ *
1641
+ * // Set facade module
1642
+ * Facade.setFacadeModule(AppModule);
1643
+ *
1644
+ * // Now facades work anywhere
1645
+ * ReactDOM.createRoot(document.getElementById("root")!).render(
1646
+ * <ContainerProvider module={AppModule}>
1647
+ * <App />
1648
+ * </ContainerProvider>
1649
+ * );
1650
+ * ```
1651
+ */
1652
+ static setFacadeModule(module: Newable | null): void;
1653
+ /**
1654
+ * Set the container directly (alternative to setFacadeModule)
1655
+ *
1656
+ * @param container - The module container instance
1657
+ */
1658
+ static setFacadeContainer(container: ModuleContainer | null): void;
1659
+ /**
1660
+ * @deprecated Use setFacadeModule instead
1661
+ */
1662
+ static setFacadeApplication(app: FacadeApplication | null): void;
1663
+ /**
1664
+ * @deprecated Use getFacadeModule instead
1665
+ */
1666
+ static getFacadeApplication(): FacadeApplication | null;
1667
+ }
1668
+
1669
+ /**
1670
+ * @fileoverview Facade factory with Proxy support
1671
+ *
1672
+ * Creates facades with automatic method forwarding using JavaScript Proxy.
1673
+ * This enables the Laravel-style `Facade::method()` pattern in TypeScript.
1674
+ *
1675
+ * @module @abdokouta/react-support
1676
+ * @category Facades
1677
+ */
1678
+
1679
+ /**
1680
+ * Facade class type with static methods and proxied service methods
1681
+ */
1682
+ type FacadeClass<T> = typeof Facade & {
1683
+ getFacadeRoot<R = T>(): R;
1684
+ } & {
1685
+ [K in keyof T]: T[K];
1686
+ };
1687
+ /**
1688
+ * Options for creating a facade
1689
+ */
1690
+ interface CreateFacadeOptions<T> {
1691
+ /**
1692
+ * Service identifier (string token, symbol, or class)
1693
+ */
1694
+ accessor: ServiceIdentifier<T>;
1695
+ /**
1696
+ * Whether to cache the resolved instance
1697
+ * @default true
1698
+ */
1699
+ cached?: boolean;
1700
+ }
1701
+ /**
1702
+ * Create a facade for a service
1703
+ *
1704
+ * Creates a Proxy-based facade that forwards all method calls to the
1705
+ * resolved service instance. This enables the Laravel-style pattern
1706
+ * where you can call methods directly on the facade class.
1707
+ *
1708
+ * @param options - Facade configuration
1709
+ * @returns Proxied facade class
1710
+ *
1711
+ * @example
1712
+ * ```typescript
1713
+ * // Define your service interface
1714
+ * interface ILogger {
1715
+ * info(message: string): void;
1716
+ * error(message: string): void;
1717
+ * debug(message: string): void;
1718
+ * }
1719
+ *
1720
+ * // Create the facade
1721
+ * const Log = createFacade<ILogger>({
1722
+ * accessor: 'logger', // or LoggerService class
1723
+ * });
1724
+ *
1725
+ * // Set module at bootstrap
1726
+ * Facade.setFacadeModule(AppModule);
1727
+ *
1728
+ * // Use it statically
1729
+ * Log.info('Hello!');
1730
+ * Log.error('Oops!');
1731
+ * ```
1732
+ */
1733
+ declare function createFacade<T extends object>(options: CreateFacadeOptions<T>): FacadeClass<T>;
1734
+ /**
1735
+ * Create a typed facade class (without proxy)
1736
+ *
1737
+ * @param accessor - Service identifier
1738
+ * @returns Facade class constructor
1739
+ */
1740
+ declare function createFacadeClass<T>(accessor: ServiceIdentifier<T>): typeof Facade;
1741
+ /**
1742
+ * Get container from a module class
1743
+ *
1744
+ * @param moduleClass - The module class
1745
+ * @returns ModuleContainer instance
1746
+ */
1747
+ declare function getContainerFromModule(moduleClass: Newable): ModuleContainer;
1748
+
1749
+ export { BaseRegistry, type BaseRegistryOptions, Collection$1 as Collection, type CreateFacadeOptions, Facade, type FacadeApplication, type FacadeClass, type Fake, MapCollection, SetCollection, Str, type ValidationResult, collect, collectMap, collectSet, createFacade, createFacadeClass, getContainerFromModule, isFake };