mutts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +150 -0
  2. package/dist/chunks/decorator-BXsign4Z.js +176 -0
  3. package/dist/chunks/decorator-BXsign4Z.js.map +1 -0
  4. package/dist/chunks/decorator-CPbZNnsX.esm.js +168 -0
  5. package/dist/chunks/decorator-CPbZNnsX.esm.js.map +1 -0
  6. package/dist/decorator.d.ts +50 -0
  7. package/dist/decorator.esm.js +2 -0
  8. package/dist/decorator.esm.js.map +1 -0
  9. package/dist/decorator.js +11 -0
  10. package/dist/decorator.js.map +1 -0
  11. package/dist/destroyable.d.ts +48 -0
  12. package/dist/destroyable.esm.js +91 -0
  13. package/dist/destroyable.esm.js.map +1 -0
  14. package/dist/destroyable.js +98 -0
  15. package/dist/destroyable.js.map +1 -0
  16. package/dist/eventful.d.ts +11 -0
  17. package/dist/eventful.esm.js +88 -0
  18. package/dist/eventful.esm.js.map +1 -0
  19. package/dist/eventful.js +90 -0
  20. package/dist/eventful.js.map +1 -0
  21. package/dist/index.d.ts +15 -0
  22. package/dist/index.esm.js +7 -0
  23. package/dist/index.esm.js.map +1 -0
  24. package/dist/index.js +52 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/indexable.d.ts +31 -0
  27. package/dist/indexable.esm.js +85 -0
  28. package/dist/indexable.esm.js.map +1 -0
  29. package/dist/indexable.js +89 -0
  30. package/dist/indexable.js.map +1 -0
  31. package/dist/mutts.umd.js +2 -0
  32. package/dist/mutts.umd.js.map +1 -0
  33. package/dist/mutts.umd.min.js +2 -0
  34. package/dist/mutts.umd.min.js.map +1 -0
  35. package/dist/promiseChain.d.ts +11 -0
  36. package/dist/promiseChain.esm.js +72 -0
  37. package/dist/promiseChain.esm.js.map +1 -0
  38. package/dist/promiseChain.js +74 -0
  39. package/dist/promiseChain.js.map +1 -0
  40. package/dist/reactive.d.ts +114 -0
  41. package/dist/reactive.esm.js +1455 -0
  42. package/dist/reactive.esm.js.map +1 -0
  43. package/dist/reactive.js +1472 -0
  44. package/dist/reactive.js.map +1 -0
  45. package/dist/std-decorators.d.ts +17 -0
  46. package/dist/std-decorators.esm.js +161 -0
  47. package/dist/std-decorators.esm.js.map +1 -0
  48. package/dist/std-decorators.js +169 -0
  49. package/dist/std-decorators.js.map +1 -0
  50. package/docs/decorator.md +300 -0
  51. package/docs/destroyable.md +294 -0
  52. package/docs/events.md +225 -0
  53. package/docs/indexable.md +561 -0
  54. package/docs/promiseChain.md +218 -0
  55. package/docs/reactive.md +2072 -0
  56. package/docs/std-decorators.md +558 -0
  57. package/package.json +132 -0
  58. package/src/decorator.test.ts +495 -0
  59. package/src/decorator.ts +205 -0
  60. package/src/destroyable.test.ts +155 -0
  61. package/src/destroyable.ts +158 -0
  62. package/src/eventful.test.ts +380 -0
  63. package/src/eventful.ts +69 -0
  64. package/src/index.ts +7 -0
  65. package/src/indexable.test.ts +388 -0
  66. package/src/indexable.ts +124 -0
  67. package/src/promiseChain.test.ts +201 -0
  68. package/src/promiseChain.ts +99 -0
  69. package/src/reactive/array.test.ts +923 -0
  70. package/src/reactive/array.ts +352 -0
  71. package/src/reactive/core.test.ts +1663 -0
  72. package/src/reactive/core.ts +866 -0
  73. package/src/reactive/index.ts +28 -0
  74. package/src/reactive/interface.test.ts +1477 -0
  75. package/src/reactive/interface.ts +231 -0
  76. package/src/reactive/map.test.ts +866 -0
  77. package/src/reactive/map.ts +162 -0
  78. package/src/reactive/set.test.ts +289 -0
  79. package/src/reactive/set.ts +142 -0
  80. package/src/std-decorators.test.ts +679 -0
  81. package/src/std-decorators.ts +182 -0
  82. package/src/utils.ts +52 -0
@@ -0,0 +1,218 @@
1
+ # PromiseChain
2
+
3
+ A TypeScript utility that transforms promises into chainable objects, allowing you to call methods directly on promise results without awaiting them first.
4
+
5
+ ## Overview
6
+
7
+ The `promiseChain` module provides a way to work with promises in a more fluent, chainable manner. Instead of using `await` at every step, you can call methods directly on promise results and let the system handle the promise resolution automatically.
8
+
9
+ ## API Reference
10
+
11
+ ### `chainPromise<T>(given: Promise<T> | T): PromiseChain<T>`
12
+
13
+ Transforms a promise or value into a chainable object that automatically handles promise resolution and method forwarding.
14
+
15
+ **Parameters:**
16
+ - `given`: A promise or any value to make chainable
17
+
18
+ **Returns:** A chainable object that maintains the original promise methods (`then`, `catch`, `finally`) while allowing direct method access
19
+
20
+ **Example:**
21
+ ```typescript
22
+ import { chainPromise } from './promiseChain'
23
+
24
+ // Basic usage
25
+ const result = await chainPromise(Promise.resolve({ name: 'John', age: 30 })).getName()
26
+ console.log(result) // 'John'
27
+
28
+ // Chaining multiple methods
29
+ const info = await chainPromise(fetchUserData())
30
+ .getProfile()
31
+ .getSettings()
32
+ .getPreferences()
33
+ ```
34
+
35
+ ## Type Definitions
36
+
37
+ ### `PromiseChain<T>`
38
+
39
+ A type that represents a chainable promise with the following characteristics:
40
+
41
+ - **For Functions**: Returns a chainable function that can be called and returns a `PromiseChain`
42
+ - **For Objects**: Returns a chainable object where all properties return `PromiseChain` instances
43
+ - **For Primitives**: Returns a promise that resolves to the primitive value
44
+ - **Promise Methods**: Maintains original `then`, `catch`, and `finally` methods
45
+
46
+ ### `Resolved<T>`
47
+
48
+ A utility type that recursively resolves promise types:
49
+
50
+ ```typescript
51
+ type Resolved<T> = T extends Promise<infer U>
52
+ ? Resolved<U>
53
+ : T extends (...args: infer Args) => infer R
54
+ ? (...args: Args) => Resolved<R>
55
+ : T extends object
56
+ ? { [k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : Resolved<T[k]> }
57
+ : T
58
+ ```
59
+
60
+ ## Usage Examples
61
+
62
+ ### Basic Method Chaining
63
+
64
+ ```typescript
65
+ import { chainPromise } from './promiseChain'
66
+
67
+ // Define an API object
68
+ const api = {
69
+ getUser: (id: string) => Promise.resolve({
70
+ id,
71
+ name: 'John Doe',
72
+ email: 'john@example.com',
73
+ getProfile: () => Promise.resolve({
74
+ bio: 'Software developer',
75
+ avatar: 'avatar.jpg',
76
+ getSettings: () => Promise.resolve({
77
+ theme: 'dark',
78
+ notifications: true
79
+ })
80
+ })
81
+ })
82
+ }
83
+
84
+ // Chain method calls without await
85
+ const settings = await chainPromise(api.getUser('123'))
86
+ .getProfile()
87
+ .getSettings()
88
+
89
+ console.log(settings) // { theme: 'dark', notifications: true }
90
+ ```
91
+
92
+ ### Function Chaining
93
+
94
+ ```typescript
95
+ const mathOperations = {
96
+ add: (a: number) => (b: number) => Promise.resolve(a + b),
97
+ multiply: (a: number) => (b: number) => Promise.resolve(a * b),
98
+ square: (a: number) => Promise.resolve(a * a)
99
+ }
100
+
101
+ // Chain function calls
102
+ const result = await chainPromise(mathOperations.add(5)(10))
103
+ .multiply(2)
104
+ .square()
105
+
106
+ console.log(result) // 900 (15 * 2 = 30, 30^2 = 900)
107
+ ```
108
+
109
+ ### API Data Processing
110
+
111
+ ```typescript
112
+ const dataService = {
113
+ fetchUsers: () => Promise.resolve([
114
+ { id: 1, name: 'Alice', active: true },
115
+ { id: 2, name: 'Bob', active: false },
116
+ { id: 3, name: 'Charlie', active: true }
117
+ ]),
118
+ filterActive: (users: any[]) => users.filter(user => user.active),
119
+ mapNames: (users: any[]) => users.map(user => user.name),
120
+ sort: (names: string[]) => names.sort()
121
+ }
122
+
123
+ // Process data through a chain
124
+ const activeUserNames = await chainPromise(dataService.fetchUsers())
125
+ .filterActive()
126
+ .mapNames()
127
+ .sort()
128
+
129
+ console.log(activeUserNames) // ['Alice', 'Charlie']
130
+ ```
131
+
132
+ ### Error Handling
133
+
134
+ ```typescript
135
+ const riskyOperation = () => Promise.resolve({
136
+ mightFail: () => Promise.reject(new Error('Something went wrong')),
137
+ safeOperation: () => Promise.resolve('Success')
138
+ })
139
+
140
+ // Handle errors in the chain
141
+ try {
142
+ const result = await chainPromise(riskyOperation())
143
+ .mightFail()
144
+ .safeOperation()
145
+ } catch (error) {
146
+ console.error('Chain failed:', error.message)
147
+ }
148
+
149
+ // Or use promise methods
150
+ const result = await chainPromise(riskyOperation())
151
+ .mightFail()
152
+ .catch(() => ({ safeOperation: () => Promise.resolve('Fallback') }))
153
+ .safeOperation()
154
+ ```
155
+
156
+ ### Mixed Promise and Non-Promise Operations
157
+
158
+ ```typescript
159
+ const mixedOperations = {
160
+ getData: () => Promise.resolve({ value: 42 }),
161
+ process: (data: any) => data.value * 2, // Synchronous
162
+ validate: (value: number) => Promise.resolve(value > 0),
163
+ format: (isValid: boolean) => isValid ? 'Valid' : 'Invalid'
164
+ }
165
+
166
+ // Chain synchronous and asynchronous operations
167
+ const result = await chainPromise(mixedOperations.getData())
168
+ .process() // Synchronous
169
+ .validate() // Asynchronous
170
+ .format() // Asynchronous
171
+
172
+ console.log(result) // 'Valid'
173
+ ```
174
+
175
+ ### Working with Arrays
176
+
177
+ ```typescript
178
+ const arrayOperations = {
179
+ getNumbers: () => Promise.resolve([1, 2, 3, 4, 5]),
180
+ filter: (arr: number[]) => arr.filter(n => n % 2 === 0),
181
+ map: (arr: number[]) => arr.map(n => n * 2),
182
+ reduce: (arr: number[]) => arr.reduce((sum, n) => sum + n, 0)
183
+ }
184
+
185
+ // Chain array operations
186
+ const sum = await chainPromise(arrayOperations.getNumbers())
187
+ .filter() // [2, 4]
188
+ .map() // [4, 8]
189
+ .reduce() // 12
190
+
191
+ console.log(sum) // 12
192
+ ```
193
+
194
+ ## Key Features
195
+
196
+ - **Automatic Promise Resolution**: No need to use `await` at every step
197
+ - **Method Forwarding**: Direct access to methods on promise results
198
+ - **Type Safety**: Full TypeScript support with proper type inference
199
+ - **Promise Method Preservation**: Maintains `then`, `catch`, and `finally` methods
200
+ - **Caching**: WeakMap-based caching prevents duplicate wrapping
201
+ - **Flexible**: Works with functions, objects, and primitive values
202
+ - **Error Propagation**: Errors in the chain are properly propagated
203
+
204
+ ## Use Cases
205
+
206
+ - **API Chaining**: Chain multiple API calls without intermediate awaits
207
+ - **Data Processing Pipelines**: Process data through multiple transformation steps
208
+ - **Functional Programming**: Create fluent interfaces for promise-based operations
209
+ - **Reducing Boilerplate**: Eliminate repetitive `await` statements
210
+ - **Complex Async Workflows**: Simplify complex asynchronous operation chains
211
+ - **Promise Composition**: Compose multiple promise-based operations elegantly
212
+
213
+ ## Performance Considerations
214
+
215
+ - **Caching**: The system uses WeakMaps to cache wrapped objects, preventing duplicate wrapping
216
+ - **Lazy Evaluation**: Methods are only called when the chain is awaited
217
+ - **Memory Management**: WeakMaps ensure proper garbage collection of cached objects
218
+ - **Proxy Overhead**: Each chainable object is wrapped in a Proxy, which has minimal performance impact for most use cases