@effection/core
Advanced tools
Comparing version 2.0.0-preview.1-e00037d to 2.0.0-preview.2-0835ec2
# @effection/core | ||
## 2.0.0-preview.2 | ||
### Patch Changes | ||
- 93ec0d6: Include CHANGELOGS and src with all packages | ||
## 2.0.0-preview.1 | ||
### Patch Changes | ||
- 80143d5: Fix packaging |
@@ -6,2 +6,3 @@ import { Controller } from './controller'; | ||
import { Trapper } from '../trapper'; | ||
declare type Continuation = () => IteratorResult<Operation<unknown>>; | ||
export declare class IteratorController<TOut> implements Controller<TOut>, Trapper { | ||
@@ -11,8 +12,12 @@ private controls; | ||
private didHalt; | ||
private didEnter; | ||
private subTask?; | ||
private continuations; | ||
constructor(controls: Controls<TOut>, iterator: OperationIterator<TOut>); | ||
start(): Promise<void>; | ||
resume(iter: () => IteratorResult<Operation<unknown>>): void; | ||
resume(iter: Continuation): void; | ||
step(iter: Continuation): void; | ||
trap(child: Task): void; | ||
halt(): void; | ||
} | ||
export {}; |
@@ -228,2 +228,4 @@ 'use strict'; | ||
this.didHalt = false; | ||
this.didEnter = false; | ||
this.continuations = []; | ||
} // make this an async function to delay the first iteration until the next event loop tick | ||
@@ -246,5 +248,30 @@ | ||
} | ||
} // the purpose of this method is solely to make `step` reentrant, that is we | ||
// should be able to handle a `halt` which occurs while we are already in a | ||
// generator. This is a rare case and should only happen under some edge | ||
// cases, for example a task halting itself, or a task causing one of its | ||
// siblings to fail. | ||
; | ||
_proto.resume = function resume(iter) { | ||
if (this.didEnter) { | ||
// if we're already in a `step`, store the continuation for later instead | ||
// of running it immediately. | ||
this.continuations.push(iter); | ||
} else { | ||
this.didEnter = true; // acquire lock | ||
this.step(iter); | ||
this.didEnter = false; // release lock | ||
// resume with stored continuation it happened while we were in the step | ||
var continuation = this.continuations.shift(); | ||
if (continuation) { | ||
this.resume(continuation); | ||
} | ||
} | ||
}; | ||
_proto.resume = function resume(iter) { | ||
_proto.step = function step(iter) { | ||
var next; | ||
@@ -698,14 +725,11 @@ | ||
function sleep(duration) { | ||
return function* () { | ||
var timeoutId; | ||
try { | ||
yield new Promise(function (resolve) { | ||
timeoutId = setTimeout(resolve, duration); | ||
return function (task) { | ||
return function (resolve) { | ||
var timeoutId = setTimeout(resolve, duration); | ||
task.ensure(function () { | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
}); | ||
} finally { | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
} | ||
}; | ||
}; | ||
@@ -712,0 +736,0 @@ } |
@@ -1,2 +0,2 @@ | ||
"use strict";var t=require("events");function r(t,r){for(var e=0;e<r.length;e++){var n=r[e];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function e(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function n(t,r){t.prototype=Object.create(r.prototype),t.prototype.constructor=t,o(t,r)}function i(t){return(i=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function o(t,r){return(o=Object.setPrototypeOf||function(t,r){return t.__proto__=r,t})(t,r)}function s(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}function c(t,r,e){return(c=s()?Reflect.construct:function(t,r,e){var n=[null];n.push.apply(n,r);var i=new(Function.bind.apply(t,n));return e&&o(i,e.prototype),i}).apply(null,arguments)}function a(t){var r="function"==typeof Map?new Map:void 0;return(a=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==r){if(r.has(t))return r.get(t);r.set(t,e)}function e(){return c(t,arguments,i(this).constructor)}return e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),o(e,t)})(t)}var u=function(){function t(t){this.controls=t}var r=t.prototype;return r.start=function(){},r.halt=function(){this.controls.halted()},t}();function h(){var t=function(){},r=function(){},e=new Promise((function(e,n){t=e,r=n}));return{resolve:t,reject:r,promise:e}}var l=Symbol("halt"),f=function(){function t(t,r){this.controls=t,this.promise=r,this.haltSignal=h()}var r=t.prototype;return r.start=function(){var t=this;Promise.race([this.promise,this.haltSignal.promise]).then((function(r){r===l?t.controls.halted():t.controls.resolve(r)}),(function(r){t.controls.reject(r)}))},r.halt=function(){this.haltSignal.resolve(l)},t}();function p(t){return t&&"function"==typeof t.then}var d=function(t){function r(){return t.call(this,"halted")||this}return n(r,t),e(r,[{key:"__isEffectionHaltError",get:function(){return!0}}]),r}(a(Error));function v(t){var r;if(!(r=t)||!r.__isEffectionHaltError)throw t}var m=function(){function t(t,r){this.controls=t,this.iterator=r,this.didHalt=!1}var r=t.prototype;return r.start=function(){try{var t=this;return t.resume((function(){return t.iterator.next()})),Promise.resolve()}catch(t){return Promise.reject(t)}},r.resume=function(t){var r;try{r=t()}catch(t){return void this.controls.reject(t)}r.done?this.didHalt?this.controls.halted():this.controls.resolve(r.value):(this.subTask=new E(r.value),this.subTask.addTrapper(this),this.subTask.start())},r.trap=function(t){var r=this;"completed"===t.state&&this.resume((function(){return r.iterator.next(t.result)})),"errored"===t.state&&this.resume((function(){return r.iterator.throw(t.error)})),"halted"===t.state&&this.resume((function(){return r.iterator.throw(new d)}))},r.halt=function(){var t=this;this.didHalt||(this.didHalt=!0,this.subTask&&(this.subTask.removeTrapper(this),this.subTask.halt()),this.resume((function(){return t.iterator.return(void 0)})))},t}(),y=function(){function t(t,r){this.controls=t,this.resolution=r}var r=t.prototype;return r.start=function(){try{this.resolution(this.controls.resolve,this.controls.reject)}catch(t){this.controls.reject(t)}},r.halt=function(){this.controls.halted()},t}(),g=function(){function t(t,r){this.controls=t,this.operation=r}var r=t.prototype;return r.start=function(t){var r,e;try{r=this.operation(t)}catch(t){return void this.controls.reject(t)}e=p(r)?new f(this.controls,r):"function"==typeof r?new y(this.controls,r):new m(this.controls,r),this.controller=e,e.start()},r.halt=function(){try{if(!this.controller)throw new Error("INTERNAL ERROR: halt called before start, this should never happen");return this.controller.halt(),Promise.resolve()}catch(t){return Promise.reject(t)}},t}();function w(t){return JSON.stringify(t)}var b=function(){function t(t){this.emitter=t,this.current="pending"}var r=t.prototype;return r.transition=function(t,r){var e=this.current,n=r[e];if(!n){var i=Object.keys(r).map(w).join(", ");throw new Error("INTERNAL ERROR: state transition "+w(t)+" is not valid in current state "+w(e)+", should be one of "+i)}this.current=n,this.emitter.emit("state",{from:e,to:n})},r.start=function(){this.transition("start",{pending:"running"})},r.resolve=function(){this.transition("resolve",{running:"completing",completing:"completing",erroring:"erroring",halting:"halting"})},r.reject=function(){this.transition("reject",{running:"erroring",completing:"erroring",halting:"erroring",erroring:"erroring"})},r.halt=function(){this.transition("halt",{running:"halting",completing:"halting",halting:"halting",erroring:"erroring",halted:"halted",completed:"completed",errored:"errored"})},r.finish=function(){this.transition("finish",{completing:"completed",erroring:"errored",halting:"halted"})},e(t,[{key:"isFinishing",get:function(){return["completing","halting","erroring"].includes(this.current)}}]),t}(),j=0,E=function(t){function r(r,e){var n;if(void 0===e&&(e={}),(n=t.call(this)||this).operation=r,n.options=e,n.id=++j,n.children=new Set,n.trappers=new Set,n.ensureHandlers=new Set,n.deferred=h(),n.stateMachine=new b(function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(n)),n.controls={resolve:function(t){n.stateMachine.resolve(),n.result=t,n.children.forEach((function(t){t.options.blockParent||t.halt()})),n.resume()},reject:function(t){n.stateMachine.reject(),n.result=void 0,n.error=t,n.children.forEach((function(t){return t.halt()})),n.resume()},halted:function(){n.stateMachine.halt(),n.children.forEach((function(t){return t.halt()})),n.resume()}},r)if(p(r))n.controller=new f(n.controls,r);else{if("function"!=typeof r)throw new Error("unkown type of operation: "+r);n.controller=new g(n.controls,r)}else n.controller=new u(n.controls);return n.deferred.promise.catch((function(){})),n}n(r,t);var i=r.prototype;return i.start=function(){this.stateMachine.start(),this.controller.start(this)},i.resume=function(){var t=this;this.stateMachine.isFinishing&&0===this.children.size&&(this.stateMachine.finish(),this.ensureHandlers.forEach((function(t){return t()})),this.trappers.forEach((function(r){return r.trap(t)})),"completed"===this.state?this.deferred.resolve(this.result):"halted"===this.state?this.deferred.reject(new d):"errored"===this.state&&this.deferred.reject(this.error))},i.then=function(t,r){return this.deferred.promise.then(t,r)},i.catch=function(t){return this.deferred.promise.catch(t)},i.catchHalt=function(){return this.deferred.promise.catch(v)},i.finally=function(t){return this.deferred.promise.finally(t)},i.spawn=function(t,e){if("running"!==this.state)throw new Error("cannot spawn a child on a task which is not running");var n=new r(t,e);return this.link(n),n.start(),n},i.link=function(t){this.children.has(t)||(t.addTrapper(this),this.children.add(t),this.emit("link",t))},i.unlink=function(t){this.children.has(t)&&(t.removeTrapper(this),this.children.delete(t),this.emit("unlink",t))},i.trap=function(t){this.children.has(t)&&("errored"!==t.state||this.options.ignoreChildErrors||this.controls.reject(t.error),this.unlink(t)),this.resume()},i.ensure=function(t){this.ensureHandlers.add(t)},i.addTrapper=function(t){this.trappers.add(t)},i.removeTrapper=function(t){this.trappers.delete(t)},i.halt=function(){try{return this.controller.halt(),Promise.resolve(this.catch((function(){}))).then((function(){}))}catch(t){return Promise.reject(t)}},e(r,[{key:"state",get:function(){return this.stateMachine.current}},{key:Symbol.toStringTag,get:function(){return"[Task "+this.id+"]"}}]),r}(t.EventEmitter);function k(){var t=new E(void 0,{ignoreChildErrors:!0});return t.start(),t}var T={root:k(),reset:function(){try{return Promise.resolve(T.root.halt()).then((function(){T.root=k()}))}catch(t){return Promise.reject(t)}}};exports.Deferred=h,exports.Effection=T,exports.Task=E,exports.deprecated=function(t,r){return function(){try{throw new Error("trace")}catch(r){var e=r.stack.split("\n").slice(3,4),n=e[0];console.warn(t,"\n"+n)}for(var i=arguments.length,o=new Array(i),s=0;s<i;s++)o[s]=arguments[s];return r.call.apply(r,[this].concat(o))}},exports.run=function(t,r){return T.root.spawn(t,r)},exports.sleep=function(t){return function*(){var r;try{yield new Promise((function(e){r=setTimeout(e,t)}))}finally{r&&clearTimeout(r)}}}; | ||
"use strict";var t=require("events");function r(t,r){for(var e=0;e<r.length;e++){var n=r[e];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function e(t,e,n){return e&&r(t.prototype,e),n&&r(t,n),t}function n(t,r){t.prototype=Object.create(r.prototype),t.prototype.constructor=t,o(t,r)}function i(t){return(i=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function o(t,r){return(o=Object.setPrototypeOf||function(t,r){return t.__proto__=r,t})(t,r)}function s(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}function c(t,r,e){return(c=s()?Reflect.construct:function(t,r,e){var n=[null];n.push.apply(n,r);var i=new(Function.bind.apply(t,n));return e&&o(i,e.prototype),i}).apply(null,arguments)}function a(t){var r="function"==typeof Map?new Map:void 0;return(a=function(t){if(null===t||-1===Function.toString.call(t).indexOf("[native code]"))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==r){if(r.has(t))return r.get(t);r.set(t,e)}function e(){return c(t,arguments,i(this).constructor)}return e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),o(e,t)})(t)}var u=function(){function t(t){this.controls=t}var r=t.prototype;return r.start=function(){},r.halt=function(){this.controls.halted()},t}();function h(){var t=function(){},r=function(){},e=new Promise((function(e,n){t=e,r=n}));return{resolve:t,reject:r,promise:e}}var l=Symbol("halt"),f=function(){function t(t,r){this.controls=t,this.promise=r,this.haltSignal=h()}var r=t.prototype;return r.start=function(){var t=this;Promise.race([this.promise,this.haltSignal.promise]).then((function(r){r===l?t.controls.halted():t.controls.resolve(r)}),(function(r){t.controls.reject(r)}))},r.halt=function(){this.haltSignal.resolve(l)},t}();function p(t){return t&&"function"==typeof t.then}var d=function(t){function r(){return t.call(this,"halted")||this}return n(r,t),e(r,[{key:"__isEffectionHaltError",get:function(){return!0}}]),r}(a(Error));function v(t){var r;if(!(r=t)||!r.__isEffectionHaltError)throw t}var m=function(){function t(t,r){this.controls=t,this.iterator=r,this.didHalt=!1,this.didEnter=!1,this.continuations=[]}var r=t.prototype;return r.start=function(){try{var t=this;return t.resume((function(){return t.iterator.next()})),Promise.resolve()}catch(t){return Promise.reject(t)}},r.resume=function(t){if(this.didEnter)this.continuations.push(t);else{this.didEnter=!0,this.step(t),this.didEnter=!1;var r=this.continuations.shift();r&&this.resume(r)}},r.step=function(t){var r;try{r=t()}catch(t){return void this.controls.reject(t)}r.done?this.didHalt?this.controls.halted():this.controls.resolve(r.value):(this.subTask=new j(r.value),this.subTask.addTrapper(this),this.subTask.start())},r.trap=function(t){var r=this;"completed"===t.state&&this.resume((function(){return r.iterator.next(t.result)})),"errored"===t.state&&this.resume((function(){return r.iterator.throw(t.error)})),"halted"===t.state&&this.resume((function(){return r.iterator.throw(new d)}))},r.halt=function(){var t=this;this.didHalt||(this.didHalt=!0,this.subTask&&(this.subTask.removeTrapper(this),this.subTask.halt()),this.resume((function(){return t.iterator.return(void 0)})))},t}(),g=function(){function t(t,r){this.controls=t,this.resolution=r}var r=t.prototype;return r.start=function(){try{this.resolution(this.controls.resolve,this.controls.reject)}catch(t){this.controls.reject(t)}},r.halt=function(){this.controls.halted()},t}(),y=function(){function t(t,r){this.controls=t,this.operation=r}var r=t.prototype;return r.start=function(t){var r,e;try{r=this.operation(t)}catch(t){return void this.controls.reject(t)}e=p(r)?new f(this.controls,r):"function"==typeof r?new g(this.controls,r):new m(this.controls,r),this.controller=e,e.start()},r.halt=function(){try{if(!this.controller)throw new Error("INTERNAL ERROR: halt called before start, this should never happen");return this.controller.halt(),Promise.resolve()}catch(t){return Promise.reject(t)}},t}();function w(t){return JSON.stringify(t)}var b=function(){function t(t){this.emitter=t,this.current="pending"}var r=t.prototype;return r.transition=function(t,r){var e=this.current,n=r[e];if(!n){var i=Object.keys(r).map(w).join(", ");throw new Error("INTERNAL ERROR: state transition "+w(t)+" is not valid in current state "+w(e)+", should be one of "+i)}this.current=n,this.emitter.emit("state",{from:e,to:n})},r.start=function(){this.transition("start",{pending:"running"})},r.resolve=function(){this.transition("resolve",{running:"completing",completing:"completing",erroring:"erroring",halting:"halting"})},r.reject=function(){this.transition("reject",{running:"erroring",completing:"erroring",halting:"erroring",erroring:"erroring"})},r.halt=function(){this.transition("halt",{running:"halting",completing:"halting",halting:"halting",erroring:"erroring",halted:"halted",completed:"completed",errored:"errored"})},r.finish=function(){this.transition("finish",{completing:"completed",erroring:"errored",halting:"halted"})},e(t,[{key:"isFinishing",get:function(){return["completing","halting","erroring"].includes(this.current)}}]),t}(),E=0,j=function(t){function r(r,e){var n;if(void 0===e&&(e={}),(n=t.call(this)||this).operation=r,n.options=e,n.id=++E,n.children=new Set,n.trappers=new Set,n.ensureHandlers=new Set,n.deferred=h(),n.stateMachine=new b(function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(n)),n.controls={resolve:function(t){n.stateMachine.resolve(),n.result=t,n.children.forEach((function(t){t.options.blockParent||t.halt()})),n.resume()},reject:function(t){n.stateMachine.reject(),n.result=void 0,n.error=t,n.children.forEach((function(t){return t.halt()})),n.resume()},halted:function(){n.stateMachine.halt(),n.children.forEach((function(t){return t.halt()})),n.resume()}},r)if(p(r))n.controller=new f(n.controls,r);else{if("function"!=typeof r)throw new Error("unkown type of operation: "+r);n.controller=new y(n.controls,r)}else n.controller=new u(n.controls);return n.deferred.promise.catch((function(){})),n}n(r,t);var i=r.prototype;return i.start=function(){this.stateMachine.start(),this.controller.start(this)},i.resume=function(){var t=this;this.stateMachine.isFinishing&&0===this.children.size&&(this.stateMachine.finish(),this.ensureHandlers.forEach((function(t){return t()})),this.trappers.forEach((function(r){return r.trap(t)})),"completed"===this.state?this.deferred.resolve(this.result):"halted"===this.state?this.deferred.reject(new d):"errored"===this.state&&this.deferred.reject(this.error))},i.then=function(t,r){return this.deferred.promise.then(t,r)},i.catch=function(t){return this.deferred.promise.catch(t)},i.catchHalt=function(){return this.deferred.promise.catch(v)},i.finally=function(t){return this.deferred.promise.finally(t)},i.spawn=function(t,e){if("running"!==this.state)throw new Error("cannot spawn a child on a task which is not running");var n=new r(t,e);return this.link(n),n.start(),n},i.link=function(t){this.children.has(t)||(t.addTrapper(this),this.children.add(t),this.emit("link",t))},i.unlink=function(t){this.children.has(t)&&(t.removeTrapper(this),this.children.delete(t),this.emit("unlink",t))},i.trap=function(t){this.children.has(t)&&("errored"!==t.state||this.options.ignoreChildErrors||this.controls.reject(t.error),this.unlink(t)),this.resume()},i.ensure=function(t){this.ensureHandlers.add(t)},i.addTrapper=function(t){this.trappers.add(t)},i.removeTrapper=function(t){this.trappers.delete(t)},i.halt=function(){try{return this.controller.halt(),Promise.resolve(this.catch((function(){}))).then((function(){}))}catch(t){return Promise.reject(t)}},e(r,[{key:"state",get:function(){return this.stateMachine.current}},{key:Symbol.toStringTag,get:function(){return"[Task "+this.id+"]"}}]),r}(t.EventEmitter);function k(){var t=new j(void 0,{ignoreChildErrors:!0});return t.start(),t}var T={root:k(),reset:function(){try{return Promise.resolve(T.root.halt()).then((function(){T.root=k()}))}catch(t){return Promise.reject(t)}}};exports.Deferred=h,exports.Effection=T,exports.Task=j,exports.deprecated=function(t,r){return function(){try{throw new Error("trace")}catch(r){var e=r.stack.split("\n").slice(3,4),n=e[0];console.warn(t,"\n"+n)}for(var i=arguments.length,o=new Array(i),s=0;s<i;s++)o[s]=arguments[s];return r.call.apply(r,[this].concat(o))}},exports.run=function(t,r){return T.root.spawn(t,r)},exports.sleep=function(t){return function(r){return function(e){var n=setTimeout(e,t);r.ensure((function(){n&&clearTimeout(n)}))}}}; | ||
//# sourceMappingURL=core.cjs.production.min.js.map |
@@ -226,2 +226,4 @@ import { EventEmitter } from 'events'; | ||
this.didHalt = false; | ||
this.didEnter = false; | ||
this.continuations = []; | ||
} // make this an async function to delay the first iteration until the next event loop tick | ||
@@ -244,5 +246,30 @@ | ||
} | ||
} // the purpose of this method is solely to make `step` reentrant, that is we | ||
// should be able to handle a `halt` which occurs while we are already in a | ||
// generator. This is a rare case and should only happen under some edge | ||
// cases, for example a task halting itself, or a task causing one of its | ||
// siblings to fail. | ||
; | ||
_proto.resume = function resume(iter) { | ||
if (this.didEnter) { | ||
// if we're already in a `step`, store the continuation for later instead | ||
// of running it immediately. | ||
this.continuations.push(iter); | ||
} else { | ||
this.didEnter = true; // acquire lock | ||
this.step(iter); | ||
this.didEnter = false; // release lock | ||
// resume with stored continuation it happened while we were in the step | ||
var continuation = this.continuations.shift(); | ||
if (continuation) { | ||
this.resume(continuation); | ||
} | ||
} | ||
}; | ||
_proto.resume = function resume(iter) { | ||
_proto.step = function step(iter) { | ||
var next; | ||
@@ -696,14 +723,11 @@ | ||
function sleep(duration) { | ||
return function* () { | ||
var timeoutId; | ||
try { | ||
yield new Promise(function (resolve) { | ||
timeoutId = setTimeout(resolve, duration); | ||
return function (task) { | ||
return function (resolve) { | ||
var timeoutId = setTimeout(resolve, duration); | ||
task.ensure(function () { | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
}); | ||
} finally { | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
} | ||
}; | ||
}; | ||
@@ -710,0 +734,0 @@ } |
{ | ||
"name": "@effection/core", | ||
"version": "2.0.0-preview.1-e00037d", | ||
"version": "2.0.0-preview.2-0835ec2", | ||
"main": "dist/index.js", | ||
@@ -5,0 +5,0 @@ "types": "dist/index.d.ts", |
@@ -8,6 +8,11 @@ import { Controller } from './controller'; | ||
type Continuation = () => IteratorResult<Operation<unknown>>; | ||
export class IteratorController<TOut> implements Controller<TOut>, Trapper { | ||
private didHalt = false; | ||
private didEnter = false; | ||
private subTask?: Task; | ||
private continuations: Continuation[] = []; | ||
constructor(private controls: Controls<TOut>, private iterator: OperationIterator<TOut>) { | ||
@@ -21,3 +26,26 @@ } | ||
resume(iter: () => IteratorResult<Operation<unknown>>) { | ||
// the purpose of this method is solely to make `step` reentrant, that is we | ||
// should be able to handle a `halt` which occurs while we are already in a | ||
// generator. This is a rare case and should only happen under some edge | ||
// cases, for example a task halting itself, or a task causing one of its | ||
// siblings to fail. | ||
resume(iter: Continuation) { | ||
if(this.didEnter) { | ||
// if we're already in a `step`, store the continuation for later instead | ||
// of running it immediately. | ||
this.continuations.push(iter); | ||
} else { | ||
this.didEnter = true; // acquire lock | ||
this.step(iter); | ||
this.didEnter = false; // release lock | ||
// resume with stored continuation it happened while we were in the step | ||
let continuation = this.continuations.shift(); | ||
if(continuation) { | ||
this.resume(continuation) | ||
} | ||
} | ||
} | ||
step(iter: Continuation) { | ||
let next; | ||
@@ -24,0 +52,0 @@ try { |
import { Operation } from './operation'; | ||
export function sleep(duration: number): Operation<void> { | ||
return function*() { | ||
let timeoutId; | ||
try { | ||
yield new Promise((resolve) => { | ||
timeoutId = setTimeout(resolve, duration); | ||
}); | ||
} finally { | ||
return (task) => (resolve) => { | ||
let timeoutId = setTimeout(resolve, duration); | ||
task.ensure(() => { | ||
if(timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
} | ||
}); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
155213
1950