errore 0.3.0 → 0.4.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 (2) hide show
  1. package/README.md +69 -2
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -125,6 +125,71 @@ const posts = andThen(user, u => fetchPosts(u.id))
125
125
  const logged = tap(user, u => console.log('Got user:', u.name))
126
126
  ```
127
127
 
128
+ ### Composing Operations
129
+
130
+ Chain multiple operations together:
131
+
132
+ ```ts
133
+ import { map, andThen, mapError, isError } from 'errore'
134
+
135
+ // Define operations that can fail
136
+ function parseNumber(s: string): ValidationError | number { ... }
137
+ function validatePositive(n: number): ValidationError | number { ... }
138
+ function divide(a: number, b: number): DivisionError | number { ... }
139
+
140
+ // Compose with nested calls
141
+ const result = andThen(
142
+ andThen(parseNumber(input), validatePositive),
143
+ n => divide(100, n)
144
+ )
145
+
146
+ // Or step by step (often clearer)
147
+ function calculate(input: string): ValidationError | DivisionError | number {
148
+ const parsed = parseNumber(input)
149
+ if (isError(parsed)) return parsed
150
+
151
+ const validated = validatePositive(parsed)
152
+ if (isError(validated)) return validated
153
+
154
+ return divide(100, validated)
155
+ }
156
+
157
+ // Transform errors at the end
158
+ const appResult = mapError(
159
+ calculate(userInput),
160
+ e => new AppError({ source: e._tag, message: e.message })
161
+ )
162
+ ```
163
+
164
+ Real-world async composition:
165
+
166
+ ```ts
167
+ async function processOrder(orderId: string): Promise<OrderError | Receipt> {
168
+ const order = await fetchOrder(orderId)
169
+ if (isError(order)) return order
170
+
171
+ const validated = validateOrder(order)
172
+ if (isError(validated)) return validated
173
+
174
+ const payment = await processPayment(validated)
175
+ if (isError(payment)) return payment
176
+
177
+ return generateReceipt(payment)
178
+ }
179
+
180
+ // Caller gets union of all possible errors
181
+ const receipt = await processOrder('123')
182
+ if (isError(receipt)) {
183
+ const message = matchError(receipt, {
184
+ NotFoundError: e => `Order ${e.id} not found`,
185
+ ValidationError: e => `Invalid: ${e.field}`,
186
+ PaymentError: e => `Payment failed: ${e.reason}`,
187
+ })
188
+ console.log(message)
189
+ return
190
+ }
191
+ ```
192
+
128
193
  ### Extraction
129
194
 
130
195
  ```ts
@@ -166,15 +231,17 @@ class NetworkError extends TaggedError('NetworkError')<{
166
231
  type AppError = ValidationError | NetworkError
167
232
 
168
233
  // Exhaustive matching (TypeScript ensures all cases handled)
169
- matchError(error, {
234
+ const message = matchError(error, {
170
235
  ValidationError: e => `Invalid ${e.field}`,
171
236
  NetworkError: e => `Failed to fetch ${e.url}`
172
237
  })
238
+ console.log(message)
173
239
 
174
240
  // Partial matching with fallback
175
- matchErrorPartial(error, {
241
+ const fallbackMsg = matchErrorPartial(error, {
176
242
  ValidationError: e => `Invalid ${e.field}`
177
243
  }, e => `Unknown error: ${e.message}`)
244
+ console.log(fallbackMsg)
178
245
 
179
246
  // Type guards
180
247
  ValidationError.is(value) // specific class
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errore",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Type-safe errors as values for TypeScript. Like Go, but with full type inference.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",