thefrontside/effection

Scope simplification

Closed this issue · 0 comments

The first simplification to the scopes API was to make each invocation of run() use its own frame. I propose two more:

  • Remove Scope as Operation. Right now, Scope implements Operation, but this is more easily handled by a task grouping construct such as parallel in starfx
  • remove close() from the Scope API, and pass it explicitly to the caller of useScope(). The following makes no sense.
function* op() {
  let scope = yield* useScope();
  yield* scope.halt(); 
}

instead, close is only for the creator of the scope:

let [scope, destroy] = createScope();
await scope.run(function*() {
  yield* sleep(100);
});
await destroy();
  • add a set() method to Scope to allow for setting context directly on the frame. This allows programmatically setting a context from outside Effection:
scope.set(StoreContext, store);
scope.get(StoreContext) === store //=> true

In summary, scope becomes the way to interact with Effection from outside, and that is its only responsibility. The new interface for Scope will be:

export interface Scope {
  run<T>(operation: () => Operation<T>): Task<T>;
  get<T>(context: Context<T>): T;
  set<T>(context: Context<T>, value: T): T;
}