errore 0.10.0 → 0.12.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.
- package/README.md +59 -0
- package/SKILL.md +1105 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +19 -0
- package/dist/disposable.d.ts +120 -0
- package/dist/disposable.d.ts.map +1 -0
- package/dist/disposable.js +239 -0
- package/dist/disposable.test.d.ts +2 -0
- package/dist/disposable.test.d.ts.map +1 -0
- package/dist/disposable.test.js +602 -0
- package/dist/error.d.ts +2 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +12 -1
- package/dist/factory.d.ts +4 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +10 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.test.js +135 -0
- package/package.json +14 -3
- package/src/cli.ts +24 -0
- package/src/disposable.test.ts +507 -0
- package/src/disposable.ts +253 -0
- package/src/error.ts +15 -1
- package/src/factory.ts +16 -2
- package/src/index.test.ts +176 -1
- package/src/index.ts +3 -0
package/README.md
CHANGED
|
@@ -225,6 +225,8 @@ if (result instanceof Error) {
|
|
|
225
225
|
The error definitions:
|
|
226
226
|
|
|
227
227
|
```ts
|
|
228
|
+
import * as errore from 'errore'
|
|
229
|
+
|
|
228
230
|
class NotFoundError extends errore.createTaggedError({
|
|
229
231
|
name: 'NotFoundError',
|
|
230
232
|
message: 'User $id not found'
|
|
@@ -299,6 +301,8 @@ Returns `undefined` if no matching ancestor is found. Safe against circular `.ca
|
|
|
299
301
|
Use `extends` to inherit from a custom base class. The error will pass `instanceof` for both the base class and the specific error class:
|
|
300
302
|
|
|
301
303
|
```ts
|
|
304
|
+
import * as errore from 'errore'
|
|
305
|
+
|
|
302
306
|
class AppError extends Error {
|
|
303
307
|
statusCode = 500
|
|
304
308
|
toResponse() { return { error: this.message, code: this.statusCode } }
|
|
@@ -361,6 +365,11 @@ const response = await errore.tryAsync({
|
|
|
361
365
|
})
|
|
362
366
|
```
|
|
363
367
|
|
|
368
|
+
> **Best practices for `try` / `tryAsync`:**
|
|
369
|
+
> - **Use as low as possible in the call stack** — only at boundaries with uncontrolled dependencies (third-party libs, `JSON.parse`, `fetch`, file I/O). Your own functions should return errors as values, never throw.
|
|
370
|
+
> - **Keep the callback minimal** — wrap only the single throwing call, not your business logic. The `try` callback should be a one-liner.
|
|
371
|
+
> - **Always prefer `errore.try` over `errore.tryFn`** — they are the same function, but `try` is the canonical name.
|
|
372
|
+
|
|
364
373
|
### Transformations
|
|
365
374
|
|
|
366
375
|
**Transform and chain** operations:
|
|
@@ -381,6 +390,54 @@ const posts = errore.andThen(user, u => fetchPosts(u.id))
|
|
|
381
390
|
const logged = errore.tap(user, u => console.log('Got user:', u.name))
|
|
382
391
|
```
|
|
383
392
|
|
|
393
|
+
### Resource Cleanup (defer)
|
|
394
|
+
|
|
395
|
+
errore ships `DisposableStack` and `AsyncDisposableStack` polyfills for Go-like `defer` cleanup. Works in every runtime — no native `DisposableStack` support needed:
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
import * as errore from 'errore'
|
|
399
|
+
|
|
400
|
+
async function processRequest(id: string): Promise<DbError | Result> {
|
|
401
|
+
// await using = cleanup runs automatically when scope exits
|
|
402
|
+
await using cleanup = new errore.AsyncDisposableStack()
|
|
403
|
+
|
|
404
|
+
const db = await connectDb()
|
|
405
|
+
cleanup.defer(() => db.close())
|
|
406
|
+
|
|
407
|
+
const cache = await openCache()
|
|
408
|
+
cleanup.defer(() => cache.flush())
|
|
409
|
+
|
|
410
|
+
// ... use db and cache ...
|
|
411
|
+
return result
|
|
412
|
+
// cleanup runs in LIFO order: cache.flush() → db.close()
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Resources are released in **reverse order** (last deferred = first cleaned up), just like Go's `defer`. Cleanup runs on normal return, early error return, or thrown exception.
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
// Sync version with using
|
|
420
|
+
function readConfig(path: string): ParseError | Config {
|
|
421
|
+
using cleanup = new errore.DisposableStack()
|
|
422
|
+
|
|
423
|
+
const file = openFileSync(path)
|
|
424
|
+
cleanup.defer(() => file.closeSync())
|
|
425
|
+
|
|
426
|
+
const lock = acquireLock(path)
|
|
427
|
+
cleanup.defer(() => lock.release())
|
|
428
|
+
|
|
429
|
+
return parseConfig(file.readSync())
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
You can also register existing `Disposable` objects directly:
|
|
434
|
+
|
|
435
|
+
```ts
|
|
436
|
+
await using cleanup = new errore.AsyncDisposableStack()
|
|
437
|
+
cleanup.use(dbConnection) // calls dbConnection[Symbol.dispose]() on exit
|
|
438
|
+
cleanup.adopt(handle, (h) => h.close()) // custom cleanup for non-disposable values
|
|
439
|
+
```
|
|
440
|
+
|
|
384
441
|
### Extraction
|
|
385
442
|
|
|
386
443
|
**Extract values** or throw, **split arrays** by success/error:
|
|
@@ -675,6 +732,8 @@ Effect is powerful if you need its full feature set. But if you just want type-s
|
|
|
675
732
|
| Learning curve | Steep (new paradigm) | Minimal (just `instanceof`) |
|
|
676
733
|
| Codebase impact | Pervasive (everything becomes an Effect) | Surgical (adopt incrementally) |
|
|
677
734
|
| Bundle size | ~50KB+ | **~0 bytes** |
|
|
735
|
+
| Resource cleanup | `Scope` + `addFinalizer` + `acquireRelease` | `using` + `DisposableStack.defer()` |
|
|
736
|
+
| Cancellation | Fiber interruption model | Native `AbortController` |
|
|
678
737
|
| Use case | Full FP framework | Just error handling |
|
|
679
738
|
|
|
680
739
|
**Use Effect** when you want dependency injection, structured concurrency, and the full functional programming experience.
|