UNPKG

@ayonli/jsext

Version:

A JavaScript extension package for building strong and modern applications.

221 lines (217 loc) 6.83 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); if (!Symbol.asyncIterator) { Object.defineProperty(Symbol, "asyncIterator", { value: Symbol("Symbol.asyncIterator") }); } const source = Symbol("GeneratorSource"); const status = Symbol("GeneratorStatus"); const result = Symbol("GeneratorResult"); class Thenable { constructor(_source) { this[source] = _source; this[status] = "suspended"; this[result] = void 0; } then(onfulfilled, onrejected) { let res; if (this[source] === undefined || this[status] === "closed") { res = Promise.resolve(this[result]); } else if (this[status] === "erred") { res = Promise.reject(this[source]); } else if (typeof this[source].then === "function") { res = Promise.resolve(this[source]); } else if (typeof this[source].next === "function") { res = processIterator(this[source]); } else { res = Promise.resolve(this[source]); } this[status] = "closed"; return res .then(value => (this[result] = value)) .then(onfulfilled, onrejected); } catch(onrejected) { return Promise.resolve(this).then(null, onrejected); } } class ThenableGenerator extends Thenable { next(...args) { const value = args[0]; let res; if (this[source] === undefined || this[status] === "closed") { res = { value: void 0, done: true }; } else if (this[status] === "erred") { return this.throw(this[source]); } else if (typeof this[source].next === "function") { res = this[source].next(value); } else { res = { value: this[source], done: true }; } if (res.done === true) { this[status] = "closed"; this[result] = res.value; } return res; } return(value) { this[status] = "closed"; this[result] = value; if (this[source] && typeof this[source].return === "function") { return this[source].return(value); } else { return { value, done: true }; } } throw(err) { this[status] = "closed"; if (this[source] && typeof this[source].throw === "function") { return this[source].throw(err); } else { throw err; } } [Symbol.iterator]() { return this; } ; } class ThenableAsyncGenerator extends Thenable { next(...args) { const value = args[0]; let res; if (this[source] === undefined || this[status] === "closed") { res = Promise.resolve({ value: void 0, done: true }); } else if (typeof this[source].next === "function") { res = Promise.resolve(this[source].next(value)); } else { res = Promise.resolve(this[source]).then(value => { return { value, done: true }; }); } return res.then(res => { if (res.done === true) { this[status] = "closed"; this[result] = res.value; } return res; }); } return(value) { this[status] = "closed"; // The input value may be a promise-like object, using Promise.resolve() // to guarantee the value is resolved. return Promise.resolve(value).then(value => { this[result] = value; if (this[source] && typeof this[source].return === "function") { return Promise.resolve(this[source].return(value)); } else { return Promise.resolve({ value, done: true }); } }); } throw(err) { this[status] = "closed"; if (this[source] && typeof this[source].throw === "function") { return Promise.resolve(this[source].throw(err)); } else { return Promise.reject(err); } } [Symbol.asyncIterator]() { return this; } } const ThenableGeneratorFunction = (function (fn) { if (!(this instanceof ThenableGeneratorFunction)) { return new ThenableGeneratorFunction(fn); } function anonymous(...args) { try { const source = fn.apply(this, args); if (typeof source.then === "function" || isAsyncGenerator(source)) { return new ThenableAsyncGenerator(source); } else { return new ThenableGenerator(source); } } catch (err) { return Object.assign(new ThenableGenerator(err), { [status]: "erred" }); } } // HACK, let the returning function be an instance of // ThenableGeneratorFunction. anonymous.prototype = ThenableGeneratorFunction; anonymous.__proto__ = this; return anonymous; }); Object.setPrototypeOf(ThenableGeneratorFunction, Function); Object.setPrototypeOf(ThenableGeneratorFunction.prototype, Function.prototype); function create(fn) { return new ThenableGeneratorFunction(fn); } ThenableGeneratorFunction.create = create; function isAsyncGenerator(obj) { return obj !== null && typeof obj === "object" && typeof obj.next === "function" && typeof obj.return === "function" && typeof obj.throw === "function" && typeof obj[Symbol.asyncIterator] === "function"; } function processIterator(iterator) { return new Promise((resolve, reject) => { function fulfilled(value) { try { step(iterator.next(value)); } catch (e) { reject(e); } } function rejected(value) { var _a; try { step((_a = iterator.throw) === null || _a === void 0 ? void 0 : _a.call(iterator, value)); } catch (e) { reject(e); } } function step(item) { Promise.resolve(item).then(result => { result.done ? resolve(result.value) : new Promise(resolve => { resolve(result.value); }).then(fulfilled, rejected); }); } step(iterator.next()); }); } exports.Thenable = Thenable; exports.ThenableAsyncGenerator = ThenableAsyncGenerator; exports.ThenableGenerator = ThenableGenerator; exports.ThenableGeneratorFunction = ThenableGeneratorFunction; exports.create = create; exports.default = create; exports.result = result; exports.source = source; exports.status = status; //# sourceMappingURL=index.js.map