Managing resources

How to use .manage() to register effection resources with thunks/api


Managed resources ✅ #

starfx supports managing Effection resources and exposing them via a Context using the .manage() helper on thunks (from createThunks) and api (from createApi). The manage call will start the resource inside the scope and return a Context you can get() or expect() inside your operations to access the provided value.

A resource is useful in encapsulating logic or functionality. It is particularly useful for managing connections such as a WebSocket connections, Web Workers, auth or telemetry. These processes can be wired up, including failure, restart and shutdown logic, and then used in any of your actions. See the effectionx repo for published packages which implement an effection resource and also serve as good examples. Resources are only available in the thunk or api managing it.

Example #

This is a contrived resource, but demonstrates the implementation and use of a resource.

 1import { resource } from "effection";
 2
 3function guessAge(): Operation<{ guess: number; cumulative: number | null }> {
 4  return resource(function* (provide) {
 5    let cumulative: number | null = 0;
 6    try {
 7      // this wouldn't be valuable per se, but demonstrates how the functionality is exposed
 8      yield* provide({
 9        get guess() {
10          const n = Math.floor(Math.random() * 100);
11          if (cumulative !== null) cumulative += n;
12          return n;
13        },
14        get cumulative() {
15          return cumulative;
16        },
17      });
18    } finally {
19      // cleanup when the resource is closed
20      cumulative = null;
21    }
22  });
23}

Manage the resource:

 1// With `createThunks` (the pattern is the same for `createApi`):
 2const thunks = createThunks();
 3const GuesserCtx = thunks.manage("guesser", guessAge());
 4
 5// inside an operation (thunk, middleware, etc.)
 6const action = thunks.create("do-thing", function* (ctx, next) {
 7  // use the managed resource inside an action
 8  const g = yield* GuesserCtx.get(); // may return undefined
 9  const g2 = yield* GuesserCtx.expect(); // will throw if resource is not available
10
11  console.log(g2.guess, g2.cumulative);
12  yield* next();
13});
<< PREV
FX
NEXT >>
Error Handling