resultar 3.8.0 → 3.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.
- package/README.md +13 -4
- package/dist/agent/SKILL.md +5 -1
- package/dist/agent/references/services.md +59 -3
- package/dist/agent/versions.json +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/llms.txt +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -494,13 +494,12 @@ The callback runs only when the task executes. Use `tryPromise({ try, catch })`
|
|
|
494
494
|
specific error type; both forms receive the runtime signal and preserve interruption semantics.
|
|
495
495
|
|
|
496
496
|
Workflows can request typed services with `yield*` and receive them at the boundary. Pass the service
|
|
497
|
-
type
|
|
497
|
+
type first, then let the second call infer its literal identifier:
|
|
498
498
|
|
|
499
499
|
```ts
|
|
500
500
|
const Database = ResultTask.service<
|
|
501
|
-
{ findUser: (id: string) => Promise<string> }
|
|
502
|
-
|
|
503
|
-
>('Database')
|
|
501
|
+
{ findUser: (id: string) => Promise<string> }
|
|
502
|
+
>()('Database')
|
|
504
503
|
|
|
505
504
|
const taskWithDatabase = ResultTask.gen(function* () {
|
|
506
505
|
const database = yield* Database
|
|
@@ -529,6 +528,16 @@ await ResultTask.runResult(readyWithOne)
|
|
|
529
528
|
await ResultTask.runResult(readyWithAll)
|
|
530
529
|
```
|
|
531
530
|
|
|
531
|
+
The direct form `ResultTask.service<DatabaseContract, 'Database'>('Database')` remains supported.
|
|
532
|
+
The curried form can also be yielded inline: `yield* ResultTask.service<DatabaseContract>()('Database')`.
|
|
533
|
+
Requirements belong to `R` in `ResultTask<T, E, R>`; `Result` has no service lookup API.
|
|
534
|
+
|
|
535
|
+
Every tag creation has its own symbol identity. Inline tags resolve through named environments
|
|
536
|
+
(`provideServices` or the DI module). `provideService(token, value)` supplies both an exact token binding and a named fallback.
|
|
537
|
+
Reuse the same token to select its exact binding when identifiers collide; a separately created
|
|
538
|
+
same-name tag can resolve the named fallback. Exact token bindings take precedence. For class services and explicit dependency maps, see
|
|
539
|
+
[`Service.require` and `requires` in resultar-di](../di/README.md#class-services-and-explicit-requirements).
|
|
540
|
+
|
|
532
541
|
Infrastructure such as a dependency-injection adapter can resolve service tags lazily with
|
|
533
542
|
`provideServiceResolver(task, { Logger: () => loggerTask })`. Each required identifier has a
|
|
534
543
|
typed lazy provider. Provider errors and external requirements remain in the resulting task type;
|
package/dist/agent/SKILL.md
CHANGED
|
@@ -42,7 +42,11 @@ work, typed service requirements, or owned resource lifetimes. Preserve existing
|
|
|
42
42
|
contracts; converting an already-started Promise or ResultAsync cannot undo its execution.
|
|
43
43
|
`ResultTask.runResult` can reject on defects, interruption, and composite causes. Use `runExit`
|
|
44
44
|
when the boundary must inspect every exit without rejection. See [API details](references/api.md).
|
|
45
|
-
For DI, Hono and Fastify, read [services and HTTP scopes](references/services.md).
|
|
45
|
+
For DI, Hono and Fastify, read [services and HTTP scopes](references/services.md). Use
|
|
46
|
+
`ResultTask.service<T>()(name)` or DI `Service.require<T>()(name)` for inferred identifiers. Class
|
|
47
|
+
services support optional `requires` with a factory returning a synchronous value or ResultTask
|
|
48
|
+
(Promises and thenables are rejected); generator-only `make`
|
|
49
|
+
remains available. Check installed versions before using these overloads.
|
|
46
50
|
|
|
47
51
|
## Apply Opinionated Defaults
|
|
48
52
|
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
# Typed services and HTTP scopes
|
|
2
2
|
|
|
3
3
|
Read the installed `resultar-di/README.md`, `resultar-hono/README.md` and `resultar-fastify/README.md` for the exact companion
|
|
4
|
-
versions. The
|
|
5
|
-
|
|
4
|
+
versions. The application DI helpers are `createModule`, `service`, `Service`, and `resource`.
|
|
5
|
+
Named factory overloads and low-level adapter access use the same `resultar-di` entry point.
|
|
6
|
+
The former `/advanced` subpath has been removed; migrate existing imports to `resultar-di`.
|
|
6
7
|
|
|
8
|
+
- Use `ResultTask.service<Contract>()('name')` in core or `Service.require<Contract>()('name')`
|
|
9
|
+
in DI to infer the literal identifier. The direct core overload remains supported; do not invent
|
|
10
|
+
`Result.service`. Service requirements are represented by `R` in `ResultTask<T, E, R>`.
|
|
11
|
+
- Declare class services with `Service('name', { requires: { alias: Token }, make: ({ alias }) =>
|
|
12
|
+
({ ... }) })`. The readonly dependency object is inferred; `make` can return the service
|
|
13
|
+
object directly or a ResultTask. Factories remain lazy and synchronous values add no typed
|
|
14
|
+
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 directly as `make` and yield requirements inline or by token.
|
|
16
|
+
Both forms support `Service<Contract>()('name', definition)`.
|
|
17
|
+
- Keep provider registration explicit. `requires` does not acquire or register dependencies.
|
|
18
|
+
Inline tokens resolve by name in DI or `provideServices`; core `provideService` supplies an exact
|
|
19
|
+
token binding plus a named fallback. Reuse the same token for exact identity when identifiers
|
|
20
|
+
collide; separately created tags can resolve the named fallback.
|
|
7
21
|
- Register a service token with `.singleton(Token)`, `.scoped(Token)`, or `.transient(Token)`.
|
|
8
22
|
Dependency objects are inferred from tokens. Use `service(name, task)` for asynchronous
|
|
9
23
|
initialization; an async function passed as an ordinary factory is a defect in the contract.
|
|
@@ -11,10 +25,32 @@ named factory overloads belong to `resultar-di/advanced`.
|
|
|
11
25
|
live resource from a completed scope returns a resource whose finalizer has already run.
|
|
12
26
|
- Use `createHonoApp` for Hono routes. Ordinary `await` and `result.match` inside a route are valid;
|
|
13
27
|
generator-specific restrictions do not apply to a route body.
|
|
28
|
+
Export `type AppHono = Hono<{ Bindings: InferRequestServices<typeof createApplication> }>`
|
|
29
|
+
from `main.ts`, using `InferRequestServices` from `resultar-hono`. Separate route files import
|
|
30
|
+
`AppHono` with `import type` and receive `(app: AppHono)`. Bindings follow the application
|
|
31
|
+
selection without repeating service tokens.
|
|
32
|
+
- `bindings` is optional in `createHonoApp`, `createFastifyApp` and `createFastifyPlugin`.
|
|
33
|
+
Omission selects all registrations; an explicit list restricts the view and `[]` selects none.
|
|
34
|
+
Selected services resolve before the handler, preserving each lifetime and resource ownership.
|
|
35
|
+
Unused default-selected services can still fail acquisition and prevent the handler.
|
|
36
|
+
Fastify `appBindings` continues to default to `[]`; locals satisfy requirements without being
|
|
37
|
+
automatically exposed as registrations. The Hono middleware API still takes explicit keys.
|
|
38
|
+
- `startup` is optional in the native application adapters and accepts a `ResultTask<void, E, R>`
|
|
39
|
+
whose requirements are checked against the module. Fastify runs it in `onReady` after plugin
|
|
40
|
+
loading and also accepts `(app: FastifyInstance) => ResultTask<void, E, R>`. Hono runs it on
|
|
41
|
+
`ready()` or before the first request. Direct resources live until close and release before
|
|
42
|
+
singleton dependencies; scoped/transient dependencies are rejected. A failure rolls back the
|
|
43
|
+
application root, preserving cleanup causes. Hono close cancels pending startup cooperatively.
|
|
14
44
|
- Use `createHonoServices(module).middleware(keys, { locals })` to add services to an existing Hono
|
|
15
45
|
router. Inline route middleware infers `c.var.services` while preserving `c.env` and native RPC
|
|
16
46
|
responses. Install one services middleware per request; consume/cancel responses before `close()`.
|
|
17
|
-
- Use `
|
|
47
|
+
- Use `createFastifyApp({ services, bindings? }, configure)` for a new native Fastify application,
|
|
48
|
+
or `createFastifyPlugin({ services, bindings?, appBindings?, locals? })` for an existing server.
|
|
49
|
+
Derive `FastifyRequest.services` once with
|
|
50
|
+
`InferRequestServices<typeof createApplication>` directly in `main.ts` or in a declaration
|
|
51
|
+
file included by TypeScript. `InferAppServices` also accepts the application return type. Both follow the
|
|
52
|
+
selected bindings or custom exposed views; no global types or runtime metadata are installed
|
|
53
|
+
by the adapter. Native routes and autoload do not need wrappers.
|
|
18
54
|
`app.services` contains the selected startup singletons; `request.services` is available from
|
|
19
55
|
`preHandler` through response completion. Register authentication providing locals earlier.
|
|
20
56
|
Infer decorators with `InferAppServices` / `InferRequestServices`; augment Fastify in the application
|
|
@@ -37,3 +73,23 @@ named factory overloads belong to `resultar-di/advanced`.
|
|
|
37
73
|
For a complete runnable pattern, see the workspace `examples/hono/` and `examples/resultar/`
|
|
38
74
|
application lifecycle examples. The distributed guide includes the checked core recipe at
|
|
39
75
|
`examples/workflow.mjs`; use the published declarations to adapt companion integrations.
|
|
76
|
+
|
|
77
|
+
## Framework DI exports
|
|
78
|
+
|
|
79
|
+
`resultar-fastify` and `resultar-hono` reexport the application DI helpers: `createModule`, `Service`,
|
|
80
|
+
`service`, `resource`, plus `HttpApplication`, `ServiceClass`, `ServiceLifetime`, `ServiceModule`
|
|
81
|
+
and `ServiceScope` types. In framework-specific code, import these from the adapter together
|
|
82
|
+
with its integration helpers. Core APIs such as `ResultTask` still come from `resultar`.
|
|
83
|
+
Keep direct `resultar-di` imports and dependencies in framework-independent shared code and
|
|
84
|
+
for framework adapter helpers such as `withProvider` and `useServiceAccess`. Check the installed adapter exports before using this convenience
|
|
85
|
+
with older versions.
|
|
86
|
+
|
|
87
|
+
## Runnable HTTP examples
|
|
88
|
+
|
|
89
|
+
The maintained Fastify and Hono examples each contain their own `services.ts`, `routes.ts`
|
|
90
|
+
and `main.ts`. `services.ts` declares `Cache`, `UsersRepository` and `Users` classes,
|
|
91
|
+
function-based `Health`, and the `createServices` module factory. `main.ts` omits
|
|
92
|
+
`bindings` and owns framework typing and startup. The default request view includes all
|
|
93
|
+
registered services, including the cache and repository. Do not introduce
|
|
94
|
+
a shared package, separate `users.ts` or an extra `app.ts` for these small examples.
|
|
95
|
+
Start either example with `pnpm dev` from its directory; `PORT` defaults to 3000.
|
package/dist/agent/versions.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"resultar-check": "3.2.0",
|
|
3
|
-
"resultar-di": "0.
|
|
4
|
-
"resultar-fastify": "0.
|
|
5
|
-
"resultar-hono": "0.
|
|
3
|
+
"resultar-di": "0.4.0",
|
|
4
|
+
"resultar-fastify": "0.4.0",
|
|
5
|
+
"resultar-hono": "0.4.0",
|
|
6
6
|
"resultar-request": "0.1.2",
|
|
7
7
|
"resultar-request-typebox": "0.1.2",
|
|
8
8
|
"resultar-request-zod": "0.1.2",
|
|
9
|
-
"resultar": "3.
|
|
9
|
+
"resultar": "3.9.1"
|
|
10
10
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -898,6 +898,8 @@ export declare class ResultTask<out A, out E = never, out R = never> extends Pip
|
|
|
898
898
|
static scoped<A, E, R>(task: ResultTask<A, E, R>): ResultTask<A, E | ScopeError<R>, WithoutScope<R>>;
|
|
899
899
|
/** Creates a service tag that can be requested with `yield*` inside `ResultTask.gen`. */
|
|
900
900
|
static service<Service, const Identifier extends string>(identifier: Identifier): ServiceTag<Identifier, Service>;
|
|
901
|
+
/** Infers the literal identifier after specifying the service contract. */
|
|
902
|
+
static service<Service>(): <const Identifier extends string>(identifier: Identifier) => ServiceTag<Identifier, Service>;
|
|
901
903
|
/** Builds a task from a generator and short-circuits on the first failed task. */
|
|
902
904
|
static gen<Yield, Return, Next>(body: () => Generator<Yield, Return, Next>): ResultTask<Return, GeneratorError<Yield>, GeneratorRequirements<Yield>>;
|
|
903
905
|
/** Maps the success value without executing the task. */
|
package/dist/index.js
CHANGED
|
@@ -1222,8 +1222,8 @@ var ResultTask = class ResultTask extends Pipeable {
|
|
|
1222
1222
|
return interruptSuccess(await scope.close(interruptSuccess(exit, context.signal)), context.signal);
|
|
1223
1223
|
});
|
|
1224
1224
|
}
|
|
1225
|
-
/** Creates a service tag that can be requested with `yield*` inside `ResultTask.gen`. */
|
|
1226
1225
|
static service(identifier) {
|
|
1226
|
+
if (identifier === void 0) return (name) => new ServiceTagValue(name);
|
|
1227
1227
|
return new ServiceTagValue(identifier);
|
|
1228
1228
|
}
|
|
1229
1229
|
/** Builds a task from a generator and short-circuits on the first failed task. */
|
package/dist/llms.txt
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "resultar",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.1",
|
|
4
4
|
"description": "Result pattern for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"error-handling",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"fallow": "3.25.0",
|
|
50
50
|
"tsx": "4.23.13",
|
|
51
51
|
"typescript": "7.0.2",
|
|
52
|
-
"vite-plus": "0.3.
|
|
52
|
+
"vite-plus": "0.3.2",
|
|
53
53
|
"vitest": "4.1.11"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|