functype 0.9.0 → 0.9.1

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 (43) hide show
  1. package/dist/{Either-C-PDWX2U.d.ts → Either-BHep7I0d.d.ts} +7 -2
  2. package/dist/{Serializable-D9GKEo30.d.ts → Serializable-BbKuhDDL.d.ts} +14 -3
  3. package/dist/branded/index.d.ts +4 -6
  4. package/dist/branded/index.mjs +1 -1
  5. package/dist/chunk-GHBOC52G.mjs +43 -0
  6. package/dist/chunk-GHBOC52G.mjs.map +1 -0
  7. package/dist/chunk-R2TQJN3P.mjs +2 -0
  8. package/dist/chunk-R2TQJN3P.mjs.map +1 -0
  9. package/dist/either/index.d.ts +2 -2
  10. package/dist/either/index.mjs +1 -1
  11. package/dist/fpromise/index.d.ts +2 -2
  12. package/dist/fpromise/index.mjs +1 -1
  13. package/dist/index.d.ts +28 -20
  14. package/dist/index.mjs +1 -1
  15. package/dist/list/index.d.ts +2 -2
  16. package/dist/list/index.mjs +1 -1
  17. package/dist/map/index.d.ts +2 -2
  18. package/dist/map/index.mjs +1 -1
  19. package/dist/option/index.d.ts +2 -2
  20. package/dist/option/index.mjs +1 -1
  21. package/dist/set/index.d.ts +2 -2
  22. package/dist/set/index.mjs +1 -1
  23. package/dist/try/index.d.ts +2 -2
  24. package/dist/try/index.mjs +1 -1
  25. package/dist/tuple/index.d.ts +1 -1
  26. package/package.json +3 -3
  27. package/readme/BUNDLE_OPTIMIZATION.md +74 -0
  28. package/readme/FPromise-Assessment.md +43 -0
  29. package/readme/HKT.md +110 -0
  30. package/readme/ROADMAP.md +113 -0
  31. package/readme/TASK-TODO.md +33 -0
  32. package/readme/TUPLE-EXAMPLES.md +76 -0
  33. package/readme/TaskMigration.md +129 -0
  34. package/readme/ai-guide.md +406 -0
  35. package/readme/examples.md +2093 -0
  36. package/readme/quick-reference.md +514 -0
  37. package/readme/task-error-handling.md +283 -0
  38. package/readme/tasks.md +203 -0
  39. package/readme/type-index.md +238 -0
  40. package/dist/chunk-4EYCKDDF.mjs +0 -43
  41. package/dist/chunk-4EYCKDDF.mjs.map +0 -1
  42. package/dist/chunk-V6LFV5LW.mjs +0 -2
  43. package/dist/chunk-V6LFV5LW.mjs.map +0 -1
@@ -0,0 +1,283 @@
1
+ # Task Error Handling
2
+
3
+ The `Task` module in Functype provides robust error handling capabilities, including the ability to include task identifiers in error objects. This guide explains how to take advantage of these features.
4
+
5
+ ## Named Task Errors
6
+
7
+ When creating a `Task`, you can provide an optional name and description:
8
+
9
+ ```typescript
10
+ const namedTask = Task({
11
+ name: "UserRegistration",
12
+ description: "Handles user registration process",
13
+ })
14
+ ```
15
+
16
+ When an error occurs within this task, the task name will be referenced in the error:
17
+
18
+ 1. The `Throwable` object created from the error will include:
19
+ - The task name as the error's `name` property
20
+ - A `taskInfo` property containing both the name and description
21
+
22
+ 2. The `TaskException` object will include:
23
+ - The `_task` property with the name and description
24
+ - The original error wrapped with the task name and info
25
+
26
+ ## Examples
27
+
28
+ ### Sync Task Error
29
+
30
+ ```typescript
31
+ const namedTask = Task({ name: "UserRegistration" })
32
+
33
+ const result = namedTask.Sync(() => {
34
+ throw new Error("Invalid user data")
35
+ })
36
+
37
+ // The error (within the Left) will have:
38
+ // - name: "UserRegistration"
39
+ // - message: "Invalid user data"
40
+ // - taskInfo: { name: "UserRegistration", description: "..." }
41
+
42
+ console.log(result.value.name) // "UserRegistration"
43
+ console.log(result._task.name) // "UserRegistration"
44
+ ```
45
+
46
+ ### Async Task Error
47
+
48
+ ```typescript
49
+ try {
50
+ await Task({ name: "DataProcessing" }).Async(async () => {
51
+ throw new Error("Processing failed")
52
+ })
53
+ } catch (error) {
54
+ // The error will have:
55
+ // - name: "DataProcessing"
56
+ // - message: "Processing failed"
57
+ // - taskInfo: { name: "DataProcessing", description: "..." }
58
+
59
+ console.log(error.name) // "DataProcessing"
60
+ console.log(error.taskInfo) // { name: "DataProcessing", description: "..." }
61
+ }
62
+ ```
63
+
64
+ ### Using Task.fail Companion Function
65
+
66
+ ```typescript
67
+ const error = new Error("Authentication failed")
68
+ const result = Task.fail(error, { userId: 123 }, { name: "AuthService" })
69
+
70
+ // The TaskException contains:
71
+ console.log(result.value.name) // "AuthService"
72
+ console.log(result.value.message) // "Authentication failed"
73
+ console.log(result.value.data) // { userId: 123 }
74
+ console.log(result.value.taskInfo) // { name: "AuthService", description: "..." }
75
+ ```
76
+
77
+ ## Benefits
78
+
79
+ Including task names in errors provides several advantages:
80
+
81
+ 1. **Better Error Identification**: Easily identify which task produced an error
82
+ 2. **Improved Debugging**: Quickly locate the source of exceptions
83
+ 3. **Enhanced Logging**: Structured error information for logs and monitoring
84
+ 4. **Error Context**: Maintain context about what operation was being performed
85
+ 5. **Consistent Error Format**: All errors follow the same structure
86
+
87
+ ## Error Propagation
88
+
89
+ Task names and information propagate through the error handling chain:
90
+
91
+ ```typescript
92
+ const result = Task({ name: "UserService" }).Sync(
93
+ () => {
94
+ throw new Error("User not found")
95
+ },
96
+ (error) => `Could not process request: ${error.message}`,
97
+ )
98
+
99
+ // The resulting error maintains the task name even through the error handler
100
+ console.log(result.value.name) // "UserService"
101
+ console.log(result.value.message) // "Could not process request: User not found"
102
+ ```
103
+
104
+ ## With finally Blocks
105
+
106
+ Task names are preserved even when errors occur in finally blocks:
107
+
108
+ ```typescript
109
+ try {
110
+ await Task({ name: "CleanupTask" }).Async(
111
+ async () => "success",
112
+ async (error) => error,
113
+ () => {
114
+ throw new Error("Cleanup failed")
115
+ },
116
+ )
117
+ } catch (error) {
118
+ // The error from the finally block still includes the task name
119
+ console.log(error.name) // "CleanupTask"
120
+ console.log(error.message) // "Cleanup failed"
121
+ }
122
+ ```
123
+
124
+ ## Context Loss in Nested Tasks
125
+
126
+ When working with multiple nested `Task` executions, there's a significant issue with error context preservation. Inner task errors lose their context when they propagate through outer tasks. This limits error traceability and makes debugging complex task chains difficult.
127
+
128
+ ### Current Behavior
129
+
130
+ Consider this example:
131
+
132
+ ```typescript
133
+ // Inner task with specific context
134
+ const innerTask = Task({ name: "InnerTask" }).Async(async () => {
135
+ throw new Error("Inner failure")
136
+ })
137
+
138
+ // Outer task that calls the inner task
139
+ const outerTask = Task({ name: "OuterTask" }).Async(async () => await innerTask)
140
+
141
+ try {
142
+ await outerTask
143
+ } catch (error) {
144
+ // error.taskInfo.name will be "OuterTask", not "InnerTask"
145
+ // The original error context is lost
146
+ }
147
+ ```
148
+
149
+ In this scenario, the error context from the `InnerTask` is lost when it propagates through the `OuterTask`. This makes it difficult to:
150
+
151
+ 1. Identify the actual source of errors
152
+ 2. Implement proper error handling strategies
153
+ 3. Debug complex nested task chains
154
+
155
+ ### Current Workaround
156
+
157
+ Until a native solution is implemented, you can manually preserve the error context:
158
+
159
+ ```typescript
160
+ // Outer task with manual error handling
161
+ const outerTask = Task({ name: "OuterTask" }).Async(async () => {
162
+ try {
163
+ return await innerTask
164
+ } catch (innerError) {
165
+ // Manually reference the inner error
166
+ throw new Error(`OuterTask failed: ${(innerError as Error).message}`)
167
+ }
168
+ })
169
+ ```
170
+
171
+ ## Implemented Solution: Error Chaining
172
+
173
+ The `Task` implementation now supports error chaining, preserving the complete error context chain as errors propagate through nested tasks.
174
+
175
+ ### How Error Chaining Works
176
+
177
+ The `Task` implementation now detects when an error comes from another task and preserves the error chain by:
178
+
179
+ 1. Creating a new error with the outer task's context
180
+ 2. Setting the inner task's error as the `cause` property
181
+ 3. Preserving the complete error chain for debugging and error handling
182
+
183
+ ```typescript
184
+ // Inner task with specific context
185
+ const innerTask = Task({ name: "InnerTask" }).Async(async () => {
186
+ throw new Error("Inner failure")
187
+ })
188
+
189
+ // Outer task that calls the inner task
190
+ const outerTask = Task({ name: "OuterTask" }).Async(async () => await innerTask)
191
+
192
+ try {
193
+ await outerTask
194
+ } catch (error) {
195
+ // error.taskInfo.name will be "OuterTask"
196
+ // But error.cause.taskInfo.name will be "InnerTask"
197
+
198
+ // You can access the full error chain
199
+ const errorChain = Task.getErrorChain(error)
200
+
201
+ // Format the error chain for logging/debugging
202
+ const formattedError = Task.formatErrorChain(error, { includeTasks: true })
203
+ console.log(formattedError)
204
+ // Output:
205
+ // [OuterTask] OuterTask: Inner failure
206
+ // ↳ [InnerTask] Inner failure
207
+ }
208
+ ```
209
+
210
+ ### Task.getErrorChain
211
+
212
+ A new utility method allows you to extract the complete error chain from a Throwable error:
213
+
214
+ ```typescript
215
+ // Get array of errors from outer to inner
216
+ const errorChain = Task.getErrorChain(error)
217
+
218
+ // Access specific task information
219
+ console.log(errorChain[0].taskInfo.name) // "OuterTask"
220
+ console.log(errorChain[1].taskInfo.name) // "InnerTask"
221
+ ```
222
+
223
+ ### Task.formatErrorChain
224
+
225
+ Another utility method formats the error chain as a readable string for logging or debugging:
226
+
227
+ ```typescript
228
+ // Format with task names included
229
+ const formatted = Task.formatErrorChain(error, {
230
+ includeTasks: true, // Include task names in formatted output
231
+ separator: "\n", // Separator between error levels (default: "\n")
232
+ includeStackTrace: false, // Whether to include stack traces (default: false)
233
+ })
234
+
235
+ console.log(formatted)
236
+ // Output:
237
+ // [OuterTask] OuterTask: Inner failure
238
+ // ↳ [InnerTask] Inner failure
239
+ ```
240
+
241
+ ### Benefits
242
+
243
+ This implementation provides several advantages:
244
+
245
+ 1. **Full Context Preservation**: Every level of the error chain maintains its task context
246
+ 2. **Improved Debugging**: Error messages include the full path of the error
247
+ 3. **Better Error Handling**: Error handlers can make decisions based on the complete error chain
248
+ 4. **Minimal Performance Impact**: The solution adds negligible overhead
249
+ 5. **Backwards Compatibility**: Existing code will continue to work as before
250
+
251
+ An error chain is formatted like this by default:
252
+
253
+ ```
254
+ [OuterTask] Failed to process data
255
+ ↳ [MiddleTask] Database query failed
256
+ ↳ [InnerTask] Connection timeout
257
+ ```
258
+
259
+ ## Error Handler Behavior
260
+
261
+ When using `Task.Async`, error handlers are always called, regardless of the error type:
262
+
263
+ ```typescript
264
+ const task = Task({ name: "DataProcessor" }).Async(
265
+ async () => {
266
+ throw new Error("Processing failed")
267
+ },
268
+ (error) => {
269
+ // This handler is always called, even for TaggedThrowable errors
270
+ console.error(`Error processing data: ${error}`)
271
+ return "Failed to process data"
272
+ },
273
+ )
274
+ ```
275
+
276
+ For regular errors, the handler's return value is used as the rejection value. For errors that are already TaggedThrowable (from inner tasks), the handler is still called for side effects (like logging) in a non-blocking way, allowing these operations to happen without impacting performance. This ensures the original error chain is preserved while still enabling important operations like logging.
277
+
278
+ This ensures that error handlers can perform important operations like logging while preserving the error context needed for debugging nested task operations.
279
+
280
+ ## See Also
281
+
282
+ - [Task Module Examples](./examples/task-named-errors.ts)
283
+ - [Task API Documentation](./quick-reference.md#task)
@@ -0,0 +1,203 @@
1
+ # Functype Improvement Ideas
2
+
3
+ This document contains a comprehensive list of potential improvement ideas for the Functype library. These ideas represent possible directions for the library but should be evaluated against the core principles of maintaining a lightweight, focused approach as outlined in the README.md and implemented according to the official ROADMAP.md timeline.
4
+
5
+ > **Note**: Not all ideas listed here will necessarily be implemented. Each should be evaluated based on:
6
+ >
7
+ > - Alignment with the "lightweight" philosophy of the library
8
+ > - Prioritization in the official ROADMAP.md
9
+ > - Value to users vs. complexity added
10
+ > - Maintenance burden
11
+
12
+ ## Core Functionality Enhancements
13
+
14
+ ### Data Structures and Types
15
+
16
+ [ ] Implement LazyList/Stream for efficient processing of potentially infinite sequences
17
+ [ ] Create Validation data type for applicative validation with error accumulation
18
+ [ ] Implement Reader monad for dependency injection patterns
19
+ [ ] Add State monad for functional state management
20
+ [ ] Create IO monad for pure handling of side effects
21
+ [ ] Implement lens/optics abstractions for immutable updates
22
+ [x] Add Traversable implementation for all collection types
23
+ [ ] Implement Semigroup and Monoid type classes
24
+ [ ] Create NonEmptyList type with stronger guarantees than regular List
25
+ [x] Implement pipe operation for transforming data structures
26
+
27
+ ### Error Handling
28
+
29
+ [x] Create standardized error hierarchy for all modules
30
+ [x] Implement consistent error context propagation across monadic chains
31
+ [x] Add error recovery utilities for all error-producing types
32
+ [x] Create error serialization/deserialization utilities for API boundaries
33
+ [ ] Implement error aggregation for parallel operations
34
+
35
+ ## TypeScript and Type Safety Improvements
36
+
37
+ ### Type System Enhancements
38
+
39
+ [ ] Remove any usage from higher-kinded type implementations
40
+ [x] Expand branded/nominal type system for stronger type safety
41
+ [ ] Add more type-level utilities using conditional types and template literals
42
+ [ ] Leverage const type parameters for improved type inference
43
+ [x] Implement tuple manipulation utilities with type safety
44
+ [ ] Create type-safe path accessors for nested object structures
45
+ [ ] Add runtime type validation utilities that preserve type information
46
+
47
+ ### API Consistency
48
+
49
+ [x] Standardize method naming conventions across all modules
50
+ [x] Ensure consistent parameter ordering in similar functions
51
+ [x] Normalize return types for equivalent operations
52
+ [x] Implement consistent pattern for async variants of synchronous methods
53
+ [x] Standardize import patterns using @imports throughout the codebase
54
+ [x] Create consistent error handling strategy for all modules
55
+
56
+ ## Performance Optimizations
57
+
58
+ ### Data Structure Efficiency
59
+
60
+ [x] Implement structural sharing for immutable collections
61
+ [ ] Add memoization utilities for expensive function calls
62
+ [x] Optimize recursive operations for large data structures
63
+ [x] Implement lazy evaluation for chain operations where possible
64
+ [x] Create specialized implementations for common use cases
65
+
66
+ ### Bundle Size and Loading
67
+
68
+ [x] Analyze and reduce bundle size for core modules
69
+ [x] Implement code splitting strategies for large modules
70
+ [x] Create lightweight alternatives for performance-critical paths
71
+ [x] Add bundle size monitoring to CI/CD pipeline
72
+ [x] Optimize tree-shaking with more granular exports
73
+
74
+ ## Testing and Quality Assurance
75
+
76
+ ### Test Coverage
77
+
78
+ [x] Add test coverage metrics and set coverage goals
79
+ [x] Implement property-based tests for all data structures
80
+ [x] Create exhaustive edge case tests for error handling
81
+ [x] Add performance regression tests
82
+ [ ] Implement integration tests with popular frameworks and libraries
83
+
84
+ ### Code Quality
85
+
86
+ [x] Add static analysis tools to CI pipeline
87
+ [x] Implement automated code quality checks
88
+ [x] Create style guide enforcement tools
89
+ [ ] Add complexity metrics monitoring
90
+ [ ] Implement automated dependency updates with testing
91
+
92
+ ## Documentation and Examples
93
+
94
+ ### API Documentation
95
+
96
+ [x] Create comprehensive API documentation for all modules
97
+ [x] Add usage examples for all public methods
98
+ [x] Document performance characteristics and trade-offs
99
+ [ ] Create interactive documentation with runnable examples
100
+ [ ] Add diagrams for complex concepts and data flows
101
+
102
+ ### Guides and Tutorials
103
+
104
+ [ ] Create step-by-step migration guides from imperative to functional
105
+ [x] Add real-world examples showcasing practical applications
106
+ [x] Create beginner-friendly tutorials for functional programming concepts
107
+ [x] Implement cookbook-style documentation for common patterns
108
+ [ ] Add troubleshooting guides for common issues
109
+
110
+ ## Developer Experience
111
+
112
+ ### Tooling and Infrastructure
113
+
114
+ [x] Create development environment setup scripts
115
+ [x] Implement automated release process
116
+ [x] Add changelog generation from commit messages
117
+ [ ] Create interactive playground for experimenting with the library
118
+ [x] Implement benchmarking suite for performance testing
119
+
120
+ ### Community and Contribution
121
+
122
+ [x] Create detailed contribution guidelines
123
+ [x] Implement issue and PR templates
124
+ [ ] Add automated issue labeling and triage
125
+ [ ] Create community forum or discussion platform
126
+ [ ] Implement automated code review tools
127
+
128
+ ## Compatibility and Integration
129
+
130
+ ### Framework Integration
131
+
132
+ [ ] Create React hooks and utilities for Functype integration
133
+ [ ] Add Vue composition functions for Functype
134
+ [ ] Implement Angular services and utilities
135
+ [ ] Create Express/Koa middleware using functional patterns
136
+ [ ] Add Next.js integration utilities
137
+
138
+ ### Ecosystem Compatibility
139
+
140
+ [x] Ensure compatibility with Node.js LTS versions
141
+ [x] Maintain browser compatibility across major browsers
142
+ [ ] Add support for Deno runtime
143
+ [x] Test with various bundlers (webpack, esbuild, Rollup, etc.)
144
+ [ ] Create interoperability utilities for other functional libraries
145
+
146
+ ## Specific Module Improvements
147
+
148
+ ### Option Module
149
+
150
+ [x] Add Option.sequence for working with arrays of Options
151
+ [x] Implement Option.traverse for mapping and sequencing in one operation
152
+ [x] Add Option.fromPredicate for creating Options from boolean conditions
153
+ [x] Create Option utilities for working with nullable API responses
154
+ [x] Add Option.fromJSON for safely parsing JSON
155
+ [x] Implement pipe for transforming Option values
156
+
157
+ ### Either Module
158
+
159
+ [x] Implement Either.sequence for working with arrays of Eithers
160
+ [x] Add Either.traverse for mapping and sequencing in one operation
161
+ [x] Create bimap method for mapping both sides of Either
162
+ [x] Add Either.fromPredicate with custom error creation
163
+ [x] Implement Either utilities for async/await integration
164
+ [x] Add pipeEither for type-safe transformations across variants
165
+ [x] Implement standard pipe for consistent API with other modules
166
+
167
+ ### Task Module
168
+
169
+ [x] Add Task.sequence for parallel execution with error handling
170
+ [x] Implement Task.traverse for mapping and sequencing in one operation
171
+ [ ] Create Task.race for racing multiple tasks with timeout support
172
+ [x] Add Task retry utilities with exponential backoff
173
+ [ ] Implement Task.fromNodeCallback for Node.js style callbacks
174
+
175
+ ### FPromise Module
176
+
177
+ [x] Add timeout support for all FPromise operations
178
+ [ ] Implement cancellation support for FPromise chains
179
+ [x] Create FPromise.allSettled equivalent with typed results
180
+ [x] Add FPromise.any with proper typing
181
+ [ ] Implement progress tracking for long-running operations
182
+
183
+ ### Collection Modules
184
+
185
+ [x] Implement pipe for List data structure
186
+ [x] Implement pipe for Set data structure
187
+ [x] Implement pipe for Map data structure
188
+ [ ] Add comprehensive conversion utilities between collection types
189
+ [ ] Implement more specialized collection operations
190
+
191
+ ## Cross-Data Structure Features
192
+
193
+ [x] Implement pipe interface for consistent transformation pattern
194
+ [x] Create tests demonstrating cross-structure transformations
195
+ [x] Add type-safety for transformations across data structures
196
+ [x] Document common patterns for functional composition with pipe
197
+ [ ] Create additional utility functions for common transformations
198
+
199
+ ## Relationship to Official Roadmap
200
+
201
+ This document serves as a collection of ideas and potential enhancements for Functype. For the official development plan with prioritized tasks and timeline, please refer to the [ROADMAP.md](ROADMAP.md) file in the project root.
202
+
203
+ The official roadmap represents the committed development path, while this document captures a broader set of possibilities that may be considered for future development cycles based on community feedback and evolving requirements.