functype 0.8.83 → 0.8.85

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 (38) hide show
  1. package/dist/{Either-CncND8cm.d.ts → Either-BlY4VB1r.d.ts} +3 -3
  2. package/dist/{chunk-JMCOLAJY.mjs → chunk-JAPOUVPL.mjs} +2 -2
  3. package/dist/chunk-JAPOUVPL.mjs.map +1 -0
  4. package/dist/either/index.d.ts +1 -1
  5. package/dist/either/index.mjs +1 -1
  6. package/dist/fpromise/index.d.ts +1 -1
  7. package/dist/fpromise/index.mjs +1 -1
  8. package/dist/index.d.ts +3 -28
  9. package/dist/index.mjs +1 -1
  10. package/dist/list/index.d.ts +1 -1
  11. package/dist/list/index.mjs +1 -1
  12. package/dist/map/index.d.ts +1 -1
  13. package/dist/map/index.mjs +1 -1
  14. package/dist/option/index.d.ts +1 -1
  15. package/dist/option/index.mjs +1 -1
  16. package/dist/set/index.d.ts +1 -1
  17. package/dist/set/index.mjs +1 -1
  18. package/dist/try/index.d.ts +1 -1
  19. package/dist/try/index.mjs +1 -1
  20. package/package.json +1 -1
  21. package/dist/chunk-JMCOLAJY.mjs.map +0 -1
  22. package/readme/BUNDLE_OPTIMIZATION.md +0 -74
  23. package/readme/FPromise-Assessment.md +0 -43
  24. package/readme/HKT.md +0 -110
  25. package/readme/ROADMAP.md +0 -113
  26. package/readme/TASK-IMPLEMENTATION.md +0 -290
  27. package/readme/TASK-TODO.md +0 -40
  28. package/readme/TASK-UPDATES.md +0 -64
  29. package/readme/TUPLE-EXAMPLES.md +0 -76
  30. package/readme/TaskMigration.md +0 -129
  31. package/readme/ai-guide.md +0 -406
  32. package/readme/examples.md +0 -2093
  33. package/readme/quick-reference.md +0 -514
  34. package/readme/task-cancellation-progress.md +0 -258
  35. package/readme/task-error-handling.md +0 -127
  36. package/readme/task-quick-reference.md +0 -157
  37. package/readme/tasks.md +0 -205
  38. package/readme/type-index.md +0 -238
@@ -1,258 +0,0 @@
1
- # Task Cancellation and Progress Tracking
2
-
3
- The Task module in functype now provides robust support for cancellation and progress tracking of asynchronous operations. This guide explains how to use these advanced features.
4
-
5
- ## Cancellation
6
-
7
- Task cancellation allows you to safely stop long-running operations that are no longer needed, improving resource usage and user experience.
8
-
9
- ### Creating Cancellable Tasks
10
-
11
- ```typescript
12
- import { Task } from "@/core"
13
-
14
- // Create a cancellable task
15
- const { task, cancel } = Task.cancellable(async (token) => {
16
- // The token is passed to your task function
17
-
18
- // Use token.isCancelled to check cancellation status
19
- if (token.isCancelled) {
20
- return "Cancelled before starting work"
21
- }
22
-
23
- // Perform your long-running operation, checking cancellation periodically
24
- for (const item of largeDataset) {
25
- if (token.isCancelled) {
26
- return "Cancelled during processing"
27
- }
28
-
29
- await processItem(item)
30
- }
31
-
32
- return "Completed successfully"
33
- })
34
-
35
- // Execute task
36
- task.then((result) => console.log(result)).catch((error) => console.error(error))
37
-
38
- // Later, if needed, cancel the operation
39
- cancel()
40
- ```
41
-
42
- ### Cancellation Token Features
43
-
44
- The `CancellationToken` provides three key properties:
45
-
46
- 1. **isCancelled**: Boolean flag indicating cancellation status
47
- 2. **signal**: An `AbortSignal` compatible with fetch and other DOM APIs
48
- 3. **onCancel**: Method to register callbacks that execute on cancellation
49
-
50
- ### Integration with Web APIs
51
-
52
- The cancellation token's `signal` property works with any API that accepts AbortSignal:
53
-
54
- ```typescript
55
- const { task, cancel } = Task.cancellable(async (token) => {
56
- // Pass the signal to fetch
57
- const response = await fetch("https://api.example.com/data", {
58
- signal: token.signal,
59
- })
60
-
61
- // Process response...
62
- return await response.json()
63
- })
64
-
65
- // Cancel after 5 seconds if still running
66
- setTimeout(cancel, 5000)
67
- ```
68
-
69
- ### Custom Cancellation Handlers
70
-
71
- Register cleanup code that runs when cancellation occurs:
72
-
73
- ```typescript
74
- const { task, cancel } = Task.cancellable(async (token) => {
75
- // Setup resources
76
- const resources = await allocateExpensiveResources()
77
-
78
- // Register cleanup on cancellation
79
- token.onCancel(() => {
80
- resources.dispose()
81
- console.log("Resources cleaned up")
82
- })
83
-
84
- try {
85
- // Do work with resources...
86
- return result
87
- } finally {
88
- // This still runs even with cancellation
89
- resources.dispose()
90
- }
91
- })
92
- ```
93
-
94
- ## Progress Tracking
95
-
96
- For long-running operations, reporting progress provides better feedback to users.
97
-
98
- ### Basic Progress Tracking
99
-
100
- ```typescript
101
- // Create a task with progress tracking
102
- const { task, currentProgress } = Task.withProgress(
103
- async (updateProgress) => {
104
- // Start at 0%
105
- updateProgress(0)
106
-
107
- // Process in chunks
108
- for (let i = 0; i < 10; i++) {
109
- // Do some work...
110
- await processChunk(i)
111
-
112
- // Update progress (0-100)
113
- updateProgress((i + 1) * 10)
114
- }
115
-
116
- return "Completed successfully"
117
- },
118
- // Optional callback receives progress updates
119
- (percent) => {
120
- console.log(`Progress: ${percent}%`)
121
- updateProgressBar(percent)
122
- },
123
- )
124
-
125
- // Execute the task
126
- const result = await task
127
-
128
- // Get current progress anytime
129
- console.log(`Current progress: ${currentProgress()}%`)
130
- ```
131
-
132
- ### Combining Progress with Cancellation
133
-
134
- Both features can be used together for maximum control:
135
-
136
- ```typescript
137
- const { task, cancel, currentProgress } = Task.withProgress(async (updateProgress, token) => {
138
- updateProgress(0)
139
-
140
- for (let i = 0; i < 100; i++) {
141
- // Check cancellation
142
- if (token.isCancelled) {
143
- return "Operation cancelled"
144
- }
145
-
146
- await processItem(i)
147
- updateProgress(i + 1)
148
- }
149
-
150
- return "All items processed"
151
- })
152
-
153
- // Show progress in UI
154
- const interval = setInterval(() => {
155
- updateUI(`Progress: ${currentProgress()}%`)
156
-
157
- // Once complete, clear the interval
158
- if (currentProgress() === 100) {
159
- clearInterval(interval)
160
- }
161
- }, 100)
162
-
163
- // Allow cancellation from UI
164
- cancelButton.addEventListener("click", () => {
165
- cancel()
166
- })
167
- ```
168
-
169
- ### AsyncWithProgress Method
170
-
171
- For direct method usage without the object destructuring pattern:
172
-
173
- ```typescript
174
- const task = Task().AsyncWithProgress(
175
- (updateProgress) => {
176
- // Update progress as needed
177
- updateProgress(25)
178
-
179
- // Return result
180
- return "done"
181
- },
182
- (percent) => console.log(`Progress: ${percent}%`),
183
- (error) => error, // Optional error handler
184
- () => {}, // Optional finally function
185
- token, // Optional cancellation token
186
- )
187
- ```
188
-
189
- ## Racing Tasks
190
-
191
- When multiple asynchronous operations are running in parallel, you might want to take the first to complete:
192
-
193
- ```typescript
194
- // Create multiple tasks
195
- const task1 = Task().Async(async () => /* slow operation */)
196
- const task2 = Task().Async(async () => /* medium operation */)
197
- const task3 = Task().Async(async () => /* fast operation */)
198
-
199
- // Race the tasks with a 5 second timeout
200
- const result = await Task.race(
201
- [task1, task2, task3],
202
- 5000, // Optional timeout in ms
203
- { name: "DataRace" } // Optional task params
204
- )
205
-
206
- // Result will be from the first task to complete
207
- // Or will throw an error if all tasks fail or the timeout is reached
208
- ```
209
-
210
- ## Node.js Callback Integration
211
-
212
- Convert traditional Node.js callback functions to Task:
213
-
214
- ```typescript
215
- import { readFile } from "fs"
216
- import { Task } from "@/core"
217
-
218
- // Convert Node.js callback function to Task
219
- const readFileTask = Task.fromNodeCallback<string, [string, string]>(readFile)
220
-
221
- // Use the task
222
- try {
223
- const content = await readFileTask("config.json", "utf8")
224
- console.log(content)
225
- } catch (error) {
226
- console.error("Error reading file:", error)
227
- }
228
- ```
229
-
230
- ## Best Practices
231
-
232
- 1. **Check Cancellation Regularly**: Check the token status at appropriate intervals in long-running tasks
233
- 2. **Clean Up Resources**: Use `onCancel` or `finally` blocks to ensure resources are released
234
- 3. **Progress Granularity**: Don't update progress too frequently to avoid performance overhead
235
- 4. **Timeout Handling**: Use timeouts with `Task.race` to prevent indefinitely waiting for operations
236
- 5. **Error Propagation**: Remember that cancellation generates error objects with task context
237
-
238
- ## Cancellation vs. Errors
239
-
240
- A cancelled task will reject with a cancellation error. If you need to distinguish between regular errors and cancellation:
241
-
242
- ```typescript
243
- try {
244
- await task
245
- } catch (error) {
246
- if (error.message.includes("cancelled")) {
247
- // Handle cancellation
248
- } else {
249
- // Handle regular error
250
- }
251
- }
252
- ```
253
-
254
- ## See Also
255
-
256
- - [Task Error Handling](./task-error-handling.md)
257
- - [Task Implementation Details](./TASK-IMPLEMENTATION.md)
258
- - [Task Migration Guide](./TaskMigration.md)
@@ -1,127 +0,0 @@
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
- ## See Also
125
-
126
- - [Task Module Examples](./examples/task-named-errors.ts)
127
- - [Task API Documentation](./quick-reference.md#task)
@@ -1,157 +0,0 @@
1
- # Task Quick Reference
2
-
3
- ## Basic Usage
4
-
5
- ```typescript
6
- import { Task } from "@/core"
7
-
8
- // Synchronous task with explicit error handling
9
- const syncResult = Task().Sync(
10
- () => "success", // Main operation
11
- (error) => error, // Error handler (optional)
12
- () => {}, // Finally (optional)
13
- )
14
-
15
- // syncResult is Either<Throwable, string>
16
- if (syncResult.isRight()) {
17
- console.log("Success:", syncResult.value) // "success"
18
- } else {
19
- console.log("Error:", syncResult.value) // Throwable
20
- }
21
-
22
- // Asynchronous task (Promise-based)
23
- const asyncResult = await Task().Async(
24
- async () => "async success", // Main operation (async)
25
- async (error) => error, // Error handler (optional, async)
26
- async () => {}, // Finally (optional, async)
27
- )
28
-
29
- // asyncResult is the unwrapped value: "async success"
30
- // If error occurs, the promise rejects with Throwable
31
- ```
32
-
33
- ## Task Naming and Error Context
34
-
35
- ```typescript
36
- // Named task provides context for errors
37
- const userTask = Task({
38
- name: "UserService",
39
- description: "Handles user operations",
40
- })
41
-
42
- // Error will include task name and description
43
- try {
44
- await userTask.Async(async () => {
45
- throw new Error("Not found")
46
- })
47
- } catch (error) {
48
- console.log(error.name) // "UserService"
49
- console.log(error.message) // "Not found"
50
- console.log(error.taskInfo) // { name: "UserService", description: "..." }
51
- }
52
- ```
53
-
54
- ## Companion Functions
55
-
56
- ```typescript
57
- // Create success/failure results
58
- const success = Task.success("data", { name: "SuccessTask" })
59
- const failure = Task.fail(new Error("Failed"), { context: true }, { name: "FailTask" })
60
-
61
- // Convert promise function to task
62
- const fetchTask = Task.fromPromise(fetch, { name: "FetchTask" })
63
- const response = await fetchTask("https://api.example.com/data")
64
-
65
- // Convert task result to promise
66
- const promise = Task.toPromise(success) // Promise<string>
67
-
68
- // Convert Node.js callback to task
69
- const readFileTask = Task.fromNodeCallback(fs.readFile)
70
- const content = await readFileTask("config.json", "utf8")
71
- ```
72
-
73
- ## Cancellation
74
-
75
- ```typescript
76
- // Create cancellable task
77
- const { task, cancel } = Task.cancellable(async (token) => {
78
- // Check cancellation
79
- if (token.isCancelled) return "Already cancelled"
80
-
81
- // Use with fetch
82
- const response = await fetch(url, { signal: token.signal })
83
-
84
- // Register cleanup on cancellation
85
- token.onCancel(() => {
86
- console.log("Task cancelled")
87
- })
88
-
89
- return await response.json()
90
- })
91
-
92
- // Later: cancel the task
93
- cancel()
94
- ```
95
-
96
- ## Progress Tracking
97
-
98
- ```typescript
99
- // Create task with progress updates
100
- const { task, currentProgress, cancel } = Task.withProgress(
101
- async (updateProgress, token) => {
102
- updateProgress(0) // Initial progress
103
-
104
- // Do work in chunks
105
- for (let i = 0; i < 10; i++) {
106
- if (token.isCancelled) break
107
- await processChunk(i)
108
- updateProgress((i + 1) * 10) // Update progress (0-100)
109
- }
110
-
111
- return "Complete"
112
- },
113
- (percent) => {
114
- console.log(`Progress: ${percent}%`)
115
- },
116
- )
117
-
118
- // Get current progress anytime
119
- console.log(`Status: ${currentProgress()}%`)
120
- ```
121
-
122
- ## Task Racing
123
-
124
- ```typescript
125
- // Race multiple tasks
126
- const result = await Task.race(
127
- [task1, task2, task3], // Array of tasks to race
128
- 5000, // Optional timeout in milliseconds
129
- { name: "RaceTask" }, // Optional task params
130
- )
131
-
132
- // Result is from the first task to complete
133
- // Throws if all tasks fail or timeout is reached
134
- ```
135
-
136
- ## Task Composition
137
-
138
- ```typescript
139
- // Sequential composition
140
- const result = await Task().Async(async () => {
141
- const first = await Task().Async(async () => "first")
142
- const second = await Task().Async(async () => first + " second")
143
- return second // "first second"
144
- })
145
-
146
- // Error handling composition
147
- try {
148
- await Task({ name: "Outer" }).Async(async () => {
149
- await Task({ name: "Inner" }).Async(async () => {
150
- throw new Error("Inner error")
151
- })
152
- })
153
- } catch (error) {
154
- // Error message is from inner task: "Inner error"
155
- // But task context is from outer task: { name: "Outer" }
156
- }
157
- ```