resultar 3.9.1 → 4.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.
- package/README.md +676 -766
- package/dist/agent/SKILL.md +257 -74
- package/dist/agent/examples/workflow.mjs +5 -3
- package/dist/agent/examples/workflow.mts +13 -8
- package/dist/agent/references/api.md +350 -91
- package/dist/agent/references/integrations.md +64 -10
- package/dist/agent/references/patterns.md +232 -74
- package/dist/agent/references/review-checklist.md +60 -19
- package/dist/agent/references/services.md +26 -6
- package/dist/agent/versions.json +8 -8
- package/dist/index.d.ts +3204 -943
- package/dist/index.js +5604 -2215
- package/dist/llms.txt +1 -1
- package/package.json +9 -9
|
@@ -5,15 +5,18 @@ validation. Report only issues supported by the installed Resultar version and r
|
|
|
5
5
|
|
|
6
6
|
## Source And Scope
|
|
7
7
|
|
|
8
|
-
- Confirm
|
|
8
|
+
- Confirm installed `resultar`, request adapter, and checker versions.
|
|
9
|
+
- Import all synchronous, lazy `ResultTask`, and in-flight/eager `ResultAsync` helpers and types from `resultar`. Existing Result/Task/Async/tagged-error bridges remain available; migration preserves their contracts.
|
|
9
10
|
- Inspect local exports, types, package README files, and runnable examples before suggesting an API.
|
|
10
11
|
- Separate issues introduced by the change from pre-existing workspace or dependency problems.
|
|
11
12
|
- Preserve unrelated changes in a dirty worktree.
|
|
12
13
|
|
|
13
14
|
## Failure Model
|
|
14
15
|
|
|
15
|
-
-
|
|
16
|
-
|
|
16
|
+
- New sync failures return `Result` / `StrictResult`; new async workflows return lazy `ResultTask`
|
|
17
|
+
with concrete error and requirement types. Programmer defects may still throw.
|
|
18
|
+
- `ResultAsync` / `StrictResultAsync` are the official in-flight `Result` types returned by `task.runResult()`. Legacy adapters and static orchestration helpers on `ResultAsync` remain deprecated for existing eager boundaries; migration
|
|
19
|
+
preserves their start-once and repeat-await behavior until callers move to explicit Task workflows and runners.
|
|
17
20
|
- Tagged errors have stable names, useful metadata, inferred template props, and preserved causes.
|
|
18
21
|
- Error unions remain concrete instead of widening early to `Error`, `unknown`, or a string.
|
|
19
22
|
- `TaggedEnum` is limited to lightweight non-Error domain variants.
|
|
@@ -21,12 +24,19 @@ validation. Report only issues supported by the installed Resultar version and r
|
|
|
21
24
|
|
|
22
25
|
## Composition
|
|
23
26
|
|
|
24
|
-
- `map`
|
|
25
|
-
-
|
|
27
|
+
- Result and Task `map` / `mapErr` perform synchronous success/error transforms. Async retains its
|
|
28
|
+
Promise-awaiting callbacks; a Task mapper returning a Promise stores it as a success value.
|
|
26
29
|
- `filterOrElse` represents predicate validation.
|
|
27
|
-
- `andThen` composes
|
|
30
|
+
- Task `andThen` composes Task or synchronous Result steps. `fromResult` lifts a Result, and
|
|
31
|
+
structural `fromResultAsync(factory)` defers a `PromiseLike<Result>` producer. `Result.asyncAndThen`
|
|
32
|
+
/ `Result.asyncMap` (and the `.asyncAndThen` / `.asyncMap` instance methods) bridge synchronous Results into eager `ResultAsync`.
|
|
33
|
+
- Prefer `task.runResult()` (or `ResultTask.runResult(task)`) when bridging a requirement-free Task into an in-flight `ResultAsync`, and `errAsync(new DomainError(props))` in eager compatibility code;
|
|
34
|
+
`ResultAsync.fromTask`, Task `toResultAsync`, and tagged `.errAsync()` remain supported.
|
|
28
35
|
- `orElse` recovers the whole error channel; `catchTag` / `catchTags` recover selected domain cases.
|
|
29
|
-
- `
|
|
36
|
+
- `Result.gen` / `Result.fn` and legacy `safeTry` support sync and async bodies. Modern
|
|
37
|
+
`Result.gen` returns plain success values; `safeTry` returns a final Result.
|
|
38
|
+
New async generators use `ResultTask.gen`, yielding Tasks, Results, and services.
|
|
39
|
+
No raw Promise yields, raw `await`, or broad `try/catch` bypass typed composition.
|
|
30
40
|
- Returned `Result`, `ResultAsync`, and `ResultTask` values are handled or explicitly discarded by supported policy.
|
|
31
41
|
- Type assertions do not narrow away possible errors.
|
|
32
42
|
|
|
@@ -34,23 +44,39 @@ validation. Report only issues supported by the installed Resultar version and r
|
|
|
34
44
|
|
|
35
45
|
- External throws and rejections are wrapped once, close to the uncontrolled dependency.
|
|
36
46
|
- Error mappers accept `unknown` and produce concrete errors with `cause`.
|
|
37
|
-
- Promise factories use `
|
|
38
|
-
-
|
|
47
|
+
- New Promise factories use `ResultTask.tryPromise({ try, catch })` and forward its signal.
|
|
48
|
+
- Existing eager adapters import `tryResultAsync`, `fromPromise`, and `fromSafePromise` from
|
|
49
|
+
`resultar`, using factories for fresh work and `fromPromise` for existing Promises,
|
|
50
|
+
and `fromSafePromise` only when rejection is impossible by contract.
|
|
39
51
|
- Callback integrations provide cleanup and model `AbortError` where applicable.
|
|
40
52
|
- Retry policy defines bounded attempts, delay/jitter, retryable errors, and cancellation.
|
|
53
|
+
- Retry configuration shared across ResultAsync and ResultTask uses `Retry.policy`, preserving
|
|
54
|
+
each execution model. Canonical predicates use zero-based context and only run with budget;
|
|
55
|
+
older Task options and eager Async options keep their distinct callback signatures and jitter behavior.
|
|
56
|
+
- Task promise adapters choose `'wait'` or `'detach'` deliberately. Detachment stops waiting,
|
|
57
|
+
while the adapter owns resources acquired by underlying work after interruption.
|
|
41
58
|
- Timeout scope is explicit: per attempt or across the complete retry budget.
|
|
42
|
-
- `race
|
|
59
|
+
- `ResultAsync.race` / `raceAll` select the first `Ok`; if every task fails, return the last completed `Err`. `ResultAsync.raceFirst` selects the first completed `Result`.
|
|
60
|
+
- ResultAsync races and timeouts abort pending losers without waiting for their settlement or cleanup.
|
|
61
|
+
- `ResultTask.race` selects the first success; `ResultTask.raceFirst` selects the first outcome. Both await loser cleanup.
|
|
62
|
+
- `Fiber.await` observes completion; `join` composes the result and `interrupt` requests cancellation.
|
|
63
|
+
- `yieldEvery` / `scheduler` configure instruction scheduling, not synchronous preemption or time.
|
|
64
|
+
Tests use a deterministic scheduler when ordering across yields matters.
|
|
43
65
|
- Signals reach the underlying client so cancellation is cooperative rather than cosmetic.
|
|
44
66
|
- Batch concurrency is bounded when workload size or dependency capacity requires it.
|
|
45
67
|
- `validateAll` is used only when collecting all independent failures is desired.
|
|
46
|
-
- `
|
|
47
|
-
|
|
68
|
+
- Task resources use `acquireRelease` / `acquireDisposable` + `scoped` for awaited cleanup and
|
|
69
|
+
preserved release failures. Existing Async `withResource` cleanup stays best-effort; an eager
|
|
70
|
+
cleanup failure that must affect control flow is modeled as an explicit fallible step.
|
|
48
71
|
|
|
49
72
|
## Boundaries And Recovery
|
|
50
73
|
|
|
51
74
|
- Domain code does not contain transport status codes, framework responses, or CLI exit behavior.
|
|
52
75
|
- `matchTags` handles the complete tagged error union at the boundary.
|
|
53
76
|
- `matchTagsPartial` and `matchErrorPartial` have intentional fallbacks.
|
|
77
|
+
- Task `match` / `matchTags` / `matchTagsPartial` are compositional folds, followed by an explicit
|
|
78
|
+
runner at the boundary. Async instance matching remains a native Promise terminal;
|
|
79
|
+
Async static/direct/curried matching returns a composable Async value.
|
|
54
80
|
- An `Error` handler exists when untagged errors can reach tagged matching.
|
|
55
81
|
- Recovery is local only when the fallback is genuine domain/application policy.
|
|
56
82
|
- `_unsafeUnwrap*` remains in tests; `runSync`, `runPromise`, and `unwrapOrThrow` appear only at
|
|
@@ -67,12 +93,19 @@ validation. Report only issues supported by the installed Resultar version and r
|
|
|
67
93
|
- Numeric HTTP handlers take precedence over generic HTTP mapping where needed.
|
|
68
94
|
- Retry uses a request factory and does not retry non-retryable `4xx`, JSON, or validation failures
|
|
69
95
|
without explicit policy.
|
|
96
|
+
- Request helpers really return eager Async. A new lazy workflow invokes them inside
|
|
97
|
+
`ResultTask.fromResultAsync((signal) => ...)` and forwards the signal to fetch; it does not capture
|
|
98
|
+
an already-started request and claim it was deferred.
|
|
70
99
|
|
|
71
100
|
## Observability And Cleanup
|
|
72
101
|
|
|
73
|
-
- `
|
|
74
|
-
|
|
102
|
+
- `inspect` / `inspectError` / `inspectBoth` and `log` across all models are best-effort and never
|
|
103
|
+
execute returned Tasks. Deprecated Result and Async `tap` / `tapError` keep that observer contract.
|
|
104
|
+
- Only Task `tap` / `tapError` / `tapCause` / `tapBoth` compose effectful side operations and can
|
|
105
|
+
introduce typed failures or defects.
|
|
75
106
|
- Resource cleanup and observation use the semantics of the concrete execution model.
|
|
107
|
+
- `Result.gen` / `safeTry` do not close a suspended generator on early `Err`; cleanup does not rely
|
|
108
|
+
on `finally` on that path. `ResultTask.gen` interprets yielded generator cleanup.
|
|
76
109
|
- Audits, publishes, or cleanup that must succeed use `andThen`, `orElse`, or another Resultar
|
|
77
110
|
boundary.
|
|
78
111
|
- Logs expose stable tags and safe context without leaking redacted values.
|
|
@@ -87,8 +120,15 @@ validation. Report only issues supported by the installed Resultar version and r
|
|
|
87
120
|
- Documentation examples compile or have a matching runnable example.
|
|
88
121
|
- Core request, TypeBox, and Zod docs link to one another as alternatives/adapters.
|
|
89
122
|
- API names, package links, and version claims match current source.
|
|
90
|
-
- `Result.gen`
|
|
91
|
-
|
|
123
|
+
- `Result.gen` and `ResultTask.gen` return plain success values and compose fallible steps or early
|
|
124
|
+
errors via `yield*`; `safeTry` retains its final-Result contract.
|
|
125
|
+
- Eager compatibility APIs exported from `resultar` preserve eagerness and legacy callback
|
|
126
|
+
semantics. Prefer canonical Task names while preserving deprecated aliases during migration.
|
|
127
|
+
- Stable checker names such as `preferResultAsync` describe an existing eager-contract policy,
|
|
128
|
+
scoped deliberately; they do not override the Task default for new workflows.
|
|
129
|
+
- Instance `task.runResult()`, `runPromise()`, `runExit()`, and `runFork()` use the same options,
|
|
130
|
+
service checks, and deferred release error types as their supported static forms. Prefer instance
|
|
131
|
+
runners in new recipes. `runResult` rejection paths and deferred release errors are handled at the owning boundary.
|
|
92
132
|
- An intentional-discard fix is not mistaken for executing or handling a lazy task.
|
|
93
133
|
|
|
94
134
|
## Validation Order
|
|
@@ -107,16 +147,17 @@ validation. Report only issues supported by the installed Resultar version and r
|
|
|
107
147
|
channel.
|
|
108
148
|
- A broad `try/catch` surrounds an entire workflow instead of wrapping one external boundary.
|
|
109
149
|
- Project-wide `try/catch` remains after the strict `noTryCatch` migration rule is enabled.
|
|
110
|
-
- `map` returns another
|
|
150
|
+
- `map` returns another Resultar container, or a Task mapper returns a Promise instead of composing
|
|
151
|
+
an asynchronous step.
|
|
111
152
|
- `orElse` only replaces one error with another and should be `mapErr`.
|
|
112
153
|
- A raw promise is awaited inside a Resultar workflow without a typed mapper.
|
|
113
|
-
- `safeTry`
|
|
154
|
+
- `Result.gen` / `safeTry` contain raw `await`, plain `yield`, or broad `try/catch` instead of supported Result composition.
|
|
114
155
|
- A Resultar value is created and ignored.
|
|
115
156
|
- `_unsafeUnwrap()` appears in production code.
|
|
116
157
|
- An assertion makes an error union narrower than the implementation can guarantee.
|
|
117
158
|
- Tagged errors override generated constructors, mismatch class names, or omit useful causes.
|
|
118
159
|
- A schema adapter returns a broad JSON type or duplicates the schema with a drifting interface.
|
|
119
160
|
- A promise rather than a request factory is configured for retry.
|
|
120
|
-
- Hand-written retry, timeout, or race logic duplicates
|
|
161
|
+
- Hand-written retry, timeout, or race logic duplicates the built-in policy of the chosen model.
|
|
121
162
|
- A lint-only pass is described as full Resultar validation.
|
|
122
163
|
- Documentation recommends an API absent from the installed package.
|
|
@@ -5,14 +5,19 @@ versions. The application DI helpers are `createModule`, `service`, `Service`, a
|
|
|
5
5
|
Named factory overloads and low-level adapter access use the same `resultar-di` entry point.
|
|
6
6
|
The former `/advanced` subpath has been removed; migrate existing imports to `resultar-di`.
|
|
7
7
|
|
|
8
|
+
Use `ResultTask` for new asynchronous service methods and initialization. Tasks are lazy and
|
|
9
|
+
nonthenable: return them directly from methods, compose them with `andThen` or `ResultTask.gen`,
|
|
10
|
+
and execute them through an explicit runner (`task.runResult()`, `task.runPromise()`, `task.runExit()`, or `task.runFork()`) at the owning application or request boundary.
|
|
11
|
+
`task.runResult()` returns an in-flight `ResultAsync<T, E>`. Existing methods returning eager `ResultAsync` or `StrictResultAsync` directly remain eager compatibility contracts; import in-flight constructors, eager compatibility helpers, and `ResultAsync` directly from `resultar`.
|
|
12
|
+
|
|
8
13
|
- Use `ResultTask.service<Contract>()('name')` in core or `Service.require<Contract>()('name')`
|
|
9
14
|
in DI to infer the literal identifier. The direct core overload remains supported; do not invent
|
|
10
15
|
`Result.service`. Service requirements are represented by `R` in `ResultTask<T, E, R>`.
|
|
11
16
|
- Declare class services with `Service('name', { requires: { alias: Token }, make: ({ alias }) =>
|
|
12
|
-
({ ... }) })`. The readonly dependency object is inferred; `make` can return the service
|
|
17
|
+
({ ... }) })`. The readonly dependency object is inferred; `make` can return the service
|
|
13
18
|
object directly or a ResultTask. Factories remain lazy and synchronous values add no typed
|
|
14
19
|
initialization errors. Promises and thenables are rejected. Use `ResultTask.gen` for
|
|
15
|
-
initialization with typed failures, additional requirements or owned resources. Without `requires`, pass a task
|
|
20
|
+
initialization with typed failures, additional requirements or owned resources. Without `requires`, pass a task or a zero-argument factory returning a synchronous value or ResultTask. Tasks can yield requirements inline or by token.
|
|
16
21
|
Both forms support `Service<Contract>()('name', definition)`.
|
|
17
22
|
- Keep provider registration explicit. `requires` does not acquire or register dependencies.
|
|
18
23
|
Inline tokens resolve by name in DI or `provideServices`; core `provideService` supplies an exact
|
|
@@ -25,6 +30,9 @@ The former `/advanced` subpath has been removed; migrate existing imports to `re
|
|
|
25
30
|
live resource from a completed scope returns a resource whose finalizer has already run.
|
|
26
31
|
- Use `createHonoApp` for Hono routes. Ordinary `await` and `result.match` inside a route are valid;
|
|
27
32
|
generator-specific restrictions do not apply to a route body.
|
|
33
|
+
For a Task-returning method, either run `await task.runResult().matchTags(...)` or compose `task.matchTags(...)` and return
|
|
34
|
+
`responseTask.runPromise()` from the route. For an existing Async method, awaiting it
|
|
35
|
+
still observes its eager execution; `await task` never executes a Task.
|
|
28
36
|
Export `type AppHono = Hono<{ Bindings: InferRequestServices<typeof createApplication> }>`
|
|
29
37
|
from `main.ts`, using `InferRequestServices` from `resultar-hono`. Separate route files import
|
|
30
38
|
`AppHono` with `import type` and receive `(app: AppHono)`. Bindings follow the application
|
|
@@ -41,6 +49,12 @@ The former `/advanced` subpath has been removed; migrate existing imports to `re
|
|
|
41
49
|
`ready()` or before the first request. Direct resources live until close and release before
|
|
42
50
|
singleton dependencies; scoped/transient dependencies are rejected. A failure rolls back the
|
|
43
51
|
application root, preserving cleanup causes. Hono close cancels pending startup cooperatively.
|
|
52
|
+
The low-level lifecycle sessions retain eager Async `ready` / `close` or `finish` values where
|
|
53
|
+
exposed by their installed types; these bridge an explicitly running Task and are compatibility
|
|
54
|
+
boundaries, not a recommendation to make new service methods eager.
|
|
55
|
+
Prefer `task.runResult()` (or `ResultTask.runResult(task)`) when bridging a requirement-free Task into an in-flight `ResultAsync`;
|
|
56
|
+
`ResultAsync.fromTask(task)` and static/instance `ResultTask.toResultAsync` remain supported as deprecated aliases. The inbound `ResultTask.fromResultAsync` bridge accepts structural
|
|
57
|
+
`PromiseLike<Result>` values or factories and needs no class registration.
|
|
44
58
|
- Use `createHonoServices(module).middleware(keys, { locals })` to add services to an existing Hono
|
|
45
59
|
router. Inline route middleware infers `c.var.services` while preserving `c.env` and native RPC
|
|
46
60
|
responses. Install one services middleware per request; consume/cancel responses before `close()`.
|
|
@@ -56,9 +70,12 @@ The former `/advanced` subpath has been removed; migrate existing imports to `re
|
|
|
56
70
|
Infer decorators with `InferAppServices` / `InferRequestServices`; augment Fastify in the application
|
|
57
71
|
or use its typed `getDecorator`. Annotate module/locals callback parameters with native Fastify
|
|
58
72
|
types when their inferred return values participate in selection checking.
|
|
59
|
-
- Keep business logic in plain factories with
|
|
60
|
-
`service(name, dependencies, factory)`.
|
|
61
|
-
|
|
73
|
+
- Keep business logic in plain factories with methods returning Tasks when sufficient. Register
|
|
74
|
+
them using `service(name, dependencies, factory)`. Wrap a Promise client with `ResultTask.tryPromise`
|
|
75
|
+
and keep `map` synchronous. For an existing eager Async repository or request helper, invoke it
|
|
76
|
+
inside `ResultTask.fromResultAsync((signal) => adapter(signal))` to create a fresh operation per run.
|
|
77
|
+
Map results through compositional `matchTags`, an explicit runner, and native response APIs;
|
|
78
|
+
the framework adapters install no status table or `reply.result` helper.
|
|
62
79
|
- `scope.useSingletons(keys, callback)` restricts selected services and callback tokens to the root
|
|
63
80
|
lifetime. Keep its callback active while serving; it is not a free-standing resolver. Factory
|
|
64
81
|
initialization stays lazy until selection; resource release remains explicit.
|
|
@@ -70,9 +87,12 @@ The former `/advanced` subpath has been removed; migrate existing imports to `re
|
|
|
70
87
|
cannot capture scoped services or request-local data. Extracting authentication remains the
|
|
71
88
|
framework adapter's responsibility.
|
|
72
89
|
|
|
73
|
-
For a complete runnable pattern, see the workspace `examples/hono/` and `examples/
|
|
90
|
+
For a complete runnable pattern, see the workspace `examples/hono/` and `examples/cookbook/`
|
|
74
91
|
application lifecycle examples. The distributed guide includes the checked core recipe at
|
|
75
92
|
`examples/workflow.mjs`; use the published declarations to adapt companion integrations.
|
|
93
|
+
Some maintained examples and installed request adapters keep eager Async methods to demonstrate
|
|
94
|
+
compatibility. Preserve that behavior during an incremental migration; new Task methods require
|
|
95
|
+
explicit callers/runners and cannot be substituted by a return-type annotation alone.
|
|
76
96
|
|
|
77
97
|
## Framework DI exports
|
|
78
98
|
|
package/dist/agent/versions.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"resultar-check": "
|
|
3
|
-
"resultar-di": "0.
|
|
4
|
-
"resultar-fastify": "0.
|
|
5
|
-
"resultar-hono": "0.
|
|
6
|
-
"resultar-request": "0.
|
|
7
|
-
"resultar-request-typebox": "0.
|
|
8
|
-
"resultar-request-zod": "0.
|
|
9
|
-
"resultar": "
|
|
2
|
+
"resultar-check": "4.0.0",
|
|
3
|
+
"resultar-di": "1.0.0",
|
|
4
|
+
"resultar-fastify": "1.0.0",
|
|
5
|
+
"resultar-hono": "1.0.0",
|
|
6
|
+
"resultar-request": "1.0.0",
|
|
7
|
+
"resultar-request-typebox": "1.0.0",
|
|
8
|
+
"resultar-request-zod": "1.0.0",
|
|
9
|
+
"resultar": "4.0.0"
|
|
10
10
|
}
|