The first simplification to the scopes API was to make each invocation of run() use its own frame. I propose two more:
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();
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;
}
The first simplification to the scopes API was to make each invocation of
run()use its own frame. I propose two more:ScopeasOperation. Right now,ScopeimplementsOperation, but this is more easily handled by a task grouping construct such asparallelin starfxclose()from theScopeAPI, and pass it explicitly to the caller ofuseScope(). The following makes no sense.instead,
closeis only for the creator of the scope:set()method toScopeto allow for setting context directly on the frame. This allows programmatically setting a context from outside Effection:In summary, scope becomes the way to interact with Effection from outside, and that is its only responsibility. The new interface for
Scopewill be: