UNPKG

20 kBJavaScriptView Raw
1// A type of promise-like that resolves synchronously and supports only one observer
2export const _Pact = /*#__PURE__*/(function() {
3 function _Pact() {}
4 _Pact.prototype.then = function(onFulfilled, onRejected) {
5 const result = new _Pact();
6 const state = this.s;
7 if (state) {
8 const callback = state & 1 ? onFulfilled : onRejected;
9 if (callback) {
10 try {
11 _settle(result, 1, callback(this.v));
12 } catch (e) {
13 _settle(result, 2, e);
14 }
15 return result;
16 } else {
17 return this;
18 }
19 }
20 this.o = function(_this) {
21 try {
22 const value = _this.v;
23 if (_this.s & 1) {
24 _settle(result, 1, onFulfilled ? onFulfilled(value) : value);
25 } else if (onRejected) {
26 _settle(result, 1, onRejected(value));
27 } else {
28 _settle(result, 2, value);
29 }
30 } catch (e) {
31 _settle(result, 2, e);
32 }
33 };
34 return result;
35 }
36 return _Pact;
37})();
38
39// Settles a pact synchronously
40export function _settle(pact, state, value) {
41 if (!pact.s) {
42 if (value instanceof _Pact) {
43 if (value.s) {
44 if (state & 1) {
45 state = value.s;
46 }
47 value = value.v;
48 } else {
49 value.o = _settle.bind(null, pact, state);
50 return;
51 }
52 }
53 if (value && value.then) {
54 value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2));
55 return;
56 }
57 pact.s = state;
58 pact.v = value;
59 const observer = pact.o;
60 if (observer) {
61 observer(pact);
62 }
63 }
64}
65
66export function _isSettledPact(thenable) {
67 return thenable instanceof _Pact && thenable.s & 1;
68}
69
70// Converts argument to a function that always returns a Promise
71export function _async(f) {
72 return function() {
73 for (var args = [], i = 0; i < arguments.length; i++) {
74 args[i] = arguments[i];
75 }
76 try {
77 return Promise.resolve(f.apply(this, args));
78 } catch(e) {
79 return Promise.reject(e);
80 }
81 }
82}
83
84// Awaits on a value that may or may not be a Promise (equivalent to the await keyword in ES2015, with continuations passed explicitly)
85export function _await(value, then, direct) {
86 if (direct) {
87 return then ? then(value) : value;
88 }
89 if (!value || !value.then) {
90 value = Promise.resolve(value);
91 }
92 return then ? value.then(then) : value;
93}
94
95// Awaits on a value that may or may not be a Promise, then ignores it
96export function _awaitIgnored(value, direct) {
97 if (!direct) {
98 return value && value.then ? value.then(_empty) : Promise.resolve();
99 }
100}
101
102// Proceeds after a value has resolved, or proceeds immediately if the value is not thenable
103export function _continue(value, then) {
104 return value && value.then ? value.then(then) : then(value);
105}
106
107// Proceeds after a value has resolved, or proceeds immediately if the value is not thenable
108export function _continueIgnored(value) {
109 if (value && value.then) {
110 return value.then(_empty);
111 }
112}
113
114// Asynchronously iterate through an object that has a length property, passing the index as the first argument to the callback (even as the length property changes)
115export function _forTo(array, body, check) {
116 var i = -1, pact, reject;
117 function _cycle(result) {
118 try {
119 while (++i < array.length && (!check || !check())) {
120 result = body(i);
121 if (result && result.then) {
122 if (_isSettledPact(result)) {
123 result = result.v;
124 } else {
125 result.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2)));
126 return;
127 }
128 }
129 }
130 if (pact) {
131 _settle(pact, 1, result);
132 } else {
133 pact = result;
134 }
135 } catch (e) {
136 _settle(pact || (pact = new _Pact()), 2, e);
137 }
138 }
139 _cycle();
140 return pact;
141}
142
143// Asynchronously iterate through an object's properties (including properties inherited from the prototype)
144// Uses a snapshot of the object's properties
145export function _forIn(target, body, check) {
146 var keys = [];
147 for (var key in target) {
148 keys.push(key);
149 }
150 return _forTo(keys, function(i) { return body(keys[i]); }, check);
151}
152
153// Asynchronously iterate through an object's own properties (excluding properties inherited from the prototype)
154// Uses a snapshot of the object's properties
155export function _forOwn(target, body, check) {
156 var keys = [];
157 for (var key in target) {
158 if (Object.prototype.hasOwnProperty.call(target, key)) {
159 keys.push(key);
160 }
161 }
162 return _forTo(keys, function(i) { return body(keys[i]); }, check);
163}
164
165export const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";
166
167// Asynchronously iterate through an object's values
168// Uses for...of if the runtime supports it, otherwise iterates until length on a copy
169export function _forOf(target, body, check) {
170 if (typeof target[_iteratorSymbol] === "function") {
171 var iterator = target[_iteratorSymbol](), step, pact, reject;
172 function _cycle(result) {
173 try {
174 while (!(step = iterator.next()).done && (!check || !check())) {
175 result = body(step.value);
176 if (result && result.then) {
177 if (_isSettledPact(result)) {
178 result = result.v;
179 } else {
180 result.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2)));
181 return;
182 }
183 }
184 }
185 if (pact) {
186 _settle(pact, 1, result);
187 } else {
188 pact = result;
189 }
190 } catch (e) {
191 _settle(pact || (pact = new _Pact()), 2, e);
192 }
193 }
194 _cycle();
195 if (iterator.return) {
196 var _fixup = function(value) {
197 try {
198 if (!step.done) {
199 iterator.return();
200 }
201 } catch(e) {
202 }
203 return value;
204 }
205 if (pact && pact.then) {
206 return pact.then(_fixup, function(e) {
207 throw _fixup(e);
208 });
209 }
210 _fixup();
211 }
212 return pact;
213 }
214 // No support for Symbol.iterator
215 if (!("length" in target)) {
216 throw new TypeError("Object is not iterable");
217 }
218 // Handle live collections properly
219 var values = [];
220 for (var i = 0; i < target.length; i++) {
221 values.push(target[i]);
222 }
223 return _forTo(values, function(i) { return body(values[i]); }, check);
224}
225
226export const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";
227
228// Asynchronously iterate on a value using it's async iterator if present, or its synchronous iterator if missing
229export function _forAwaitOf(target, body, check) {
230 if (typeof target[_asyncIteratorSymbol] === "function") {
231 var pact = new _Pact();
232 var iterator = target[_asyncIteratorSymbol]();
233 iterator.next().then(_resumeAfterNext).then(void 0, _reject);
234 return pact;
235 function _resumeAfterBody(result) {
236 if (check && check()) {
237 return _settle(pact, 1, iterator.return ? iterator.return().then(function() { return result; }) : result);
238 }
239 iterator.next().then(_resumeAfterNext).then(void 0, _reject);
240 }
241 function _resumeAfterNext(step) {
242 if (step.done) {
243 _settle(pact, 1);
244 } else {
245 Promise.resolve(body(step.value)).then(_resumeAfterBody).then(void 0, _reject);
246 }
247 }
248 function _reject(error) {
249 _settle(pact, 2, iterator.return ? iterator.return().then(function() { return error; }) : error);
250 }
251 }
252 return Promise.resolve(_forOf(target, function(value) { return Promise.resolve(value).then(body); }, check));
253}
254
255// Asynchronously implement a generic for loop
256export function _for(test, update, body) {
257 var stage;
258 for (;;) {
259 var shouldContinue = test();
260 if (_isSettledPact(shouldContinue)) {
261 shouldContinue = shouldContinue.v;
262 }
263 if (!shouldContinue) {
264 return result;
265 }
266 if (shouldContinue.then) {
267 stage = 0;
268 break;
269 }
270 var result = body();
271 if (result && result.then) {
272 if (_isSettledPact(result)) {
273 result = result.s;
274 } else {
275 stage = 1;
276 break;
277 }
278 }
279 if (update) {
280 var updateValue = update();
281 if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
282 stage = 2;
283 break;
284 }
285 }
286 }
287 var pact = new _Pact();
288 var reject = _settle.bind(null, pact, 2);
289 (stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
290 return pact;
291 function _resumeAfterBody(value) {
292 result = value;
293 do {
294 if (update) {
295 updateValue = update();
296 if (updateValue && updateValue.then && !_isSettledPact(updateValue)) {
297 updateValue.then(_resumeAfterUpdate).then(void 0, reject);
298 return;
299 }
300 }
301 shouldContinue = test();
302 if (!shouldContinue || (_isSettledPact(shouldContinue) && !shouldContinue.v)) {
303 _settle(pact, 1, result);
304 return;
305 }
306 if (shouldContinue.then) {
307 shouldContinue.then(_resumeAfterTest).then(void 0, reject);
308 return;
309 }
310 result = body();
311 if (_isSettledPact(result)) {
312 result = result.v;
313 }
314 } while (!result || !result.then);
315 result.then(_resumeAfterBody).then(void 0, reject);
316 }
317 function _resumeAfterTest(shouldContinue) {
318 if (shouldContinue) {
319 result = body();
320 if (result && result.then) {
321 result.then(_resumeAfterBody).then(void 0, reject);
322 } else {
323 _resumeAfterBody(result);
324 }
325 } else {
326 _settle(pact, 1, result);
327 }
328 }
329 function _resumeAfterUpdate() {
330 if (shouldContinue = test()) {
331 if (shouldContinue.then) {
332 shouldContinue.then(_resumeAfterTest).then(void 0, reject);
333 } else {
334 _resumeAfterTest(shouldContinue);
335 }
336 } else {
337 _settle(pact, 1, result);
338 }
339 }
340}
341
342// Asynchronously implement a do ... while loop
343export function _do(body, test) {
344 var awaitBody;
345 do {
346 var result = body();
347 if (result && result.then) {
348 if (_isSettledPact(result)) {
349 result = result.v;
350 } else {
351 awaitBody = true;
352 break;
353 }
354 }
355 var shouldContinue = test();
356 if (_isSettledPact(shouldContinue)) {
357 shouldContinue = shouldContinue.v;
358 }
359 if (!shouldContinue) {
360 return result;
361 }
362 } while (!shouldContinue.then);
363 const pact = new _Pact();
364 const reject = _settle.bind(null, pact, 2);
365 (awaitBody ? result.then(_resumeAfterBody) : shouldContinue.then(_resumeAfterTest)).then(void 0, reject);
366 return pact;
367 function _resumeAfterBody(value) {
368 result = value;
369 for (;;) {
370 shouldContinue = test();
371 if (_isSettledPact(shouldContinue)) {
372 shouldContinue = shouldContinue.v;
373 }
374 if (!shouldContinue) {
375 break;
376 }
377 if (shouldContinue.then) {
378 shouldContinue.then(_resumeAfterTest).then(void 0, reject);
379 return;
380 }
381 result = body();
382 if (result && result.then) {
383 if (_isSettledPact(result)) {
384 result = result.v;
385 } else {
386 result.then(_resumeAfterBody).then(void 0, reject);
387 return;
388 }
389 }
390 }
391 _settle(pact, 1, result);
392 }
393 function _resumeAfterTest(shouldContinue) {
394 if (shouldContinue) {
395 do {
396 result = body();
397 if (result && result.then) {
398 if (_isSettledPact(result)) {
399 result = result.v;
400 } else {
401 result.then(_resumeAfterBody).then(void 0, reject);
402 return;
403 }
404 }
405 shouldContinue = test();
406 if (_isSettledPact(shouldContinue)) {
407 shouldContinue = shouldContinue.v;
408 }
409 if (!shouldContinue) {
410 _settle(pact, 1, result);
411 return;
412 }
413 } while (!shouldContinue.then);
414 shouldContinue.then(_resumeAfterTest).then(void 0, reject);
415 } else {
416 _settle(pact, 1, result);
417 }
418 }
419}
420
421// Asynchronously implement a switch statement
422export function _switch(discriminant, cases) {
423 var dispatchIndex = -1;
424 var awaitBody;
425 outer: {
426 for (var i = 0; i < cases.length; i++) {
427 var test = cases[i][0];
428 if (test) {
429 var testValue = test();
430 if (testValue && testValue.then) {
431 break outer;
432 }
433 if (testValue === discriminant) {
434 dispatchIndex = i;
435 break;
436 }
437 } else {
438 // Found the default case, set it as the pending dispatch case
439 dispatchIndex = i;
440 }
441 }
442 if (dispatchIndex !== -1) {
443 do {
444 var body = cases[dispatchIndex][1];
445 while (!body) {
446 dispatchIndex++;
447 body = cases[dispatchIndex][1];
448 }
449 var result = body();
450 if (result && result.then) {
451 awaitBody = true;
452 break outer;
453 }
454 var fallthroughCheck = cases[dispatchIndex][2];
455 dispatchIndex++;
456 } while (fallthroughCheck && !fallthroughCheck());
457 return result;
458 }
459 }
460 const pact = new _Pact();
461 const reject = _settle.bind(null, pact, 2);
462 (awaitBody ? result.then(_resumeAfterBody) : testValue.then(_resumeAfterTest)).then(void 0, reject);
463 return pact;
464 function _resumeAfterTest(value) {
465 for (;;) {
466 if (value === discriminant) {
467 dispatchIndex = i;
468 break;
469 }
470 if (++i === cases.length) {
471 if (dispatchIndex !== -1) {
472 break;
473 } else {
474 _settle(pact, 1, result);
475 return;
476 }
477 }
478 test = cases[i][0];
479 if (test) {
480 value = test();
481 if (value && value.then) {
482 value.then(_resumeAfterTest).then(void 0, reject);
483 return;
484 }
485 } else {
486 dispatchIndex = i;
487 }
488 }
489 do {
490 var body = cases[dispatchIndex][1];
491 while (!body) {
492 dispatchIndex++;
493 body = cases[dispatchIndex][1];
494 }
495 var result = body();
496 if (result && result.then) {
497 result.then(_resumeAfterBody).then(void 0, reject);
498 return;
499 }
500 var fallthroughCheck = cases[dispatchIndex][2];
501 dispatchIndex++;
502 } while (fallthroughCheck && !fallthroughCheck());
503 _settle(pact, 1, result);
504 }
505 function _resumeAfterBody(result) {
506 for (;;) {
507 var fallthroughCheck = cases[dispatchIndex][2];
508 if (!fallthroughCheck || fallthroughCheck()) {
509 break;
510 }
511 dispatchIndex++;
512 var body = cases[dispatchIndex][1];
513 while (!body) {
514 dispatchIndex++;
515 body = cases[dispatchIndex][1];
516 }
517 result = body();
518 if (result && result.then) {
519 result.then(_resumeAfterBody).then(void 0, reject);
520 return;
521 }
522 }
523 _settle(pact, 1, result);
524 }
525}
526
527// Asynchronously call a function and pass the result to explicitly passed continuations
528export function _call(body, then, direct) {
529 if (direct) {
530 return then ? then(body()) : body();
531 }
532 try {
533 var result = Promise.resolve(body());
534 return then ? result.then(then) : result;
535 } catch (e) {
536 return Promise.reject(e);
537 }
538}
539
540// Asynchronously call a function and swallow the result
541export function _callIgnored(body, direct) {
542 return _call(body, _empty, direct);
543}
544
545// Asynchronously call a function and pass the result to explicitly passed continuations
546export function _invoke(body, then) {
547 var result = body();
548 if (result && result.then) {
549 return result.then(then);
550 }
551 return then(result);
552}
553
554// Asynchronously call a function and swallow the result
555export function _invokeIgnored(body) {
556 var result = body();
557 if (result && result.then) {
558 return result.then(_empty);
559 }
560}
561
562// Asynchronously call a function and send errors to recovery continuation
563export function _catch(body, recover) {
564 try {
565 var result = body();
566 } catch(e) {
567 return recover(e);
568 }
569 if (result && result.then) {
570 return result.then(void 0, recover);
571 }
572 return result;
573}
574
575// Asynchronously await a promise and pass the result to a finally continuation
576export function _finallyRethrows(body, finalizer) {
577 try {
578 var result = body();
579 } catch (e) {
580 return finalizer(true, e);
581 }
582 if (result && result.then) {
583 return result.then(finalizer.bind(null, false), finalizer.bind(null, true));
584 }
585 return finalizer(false, result);
586}
587
588// Asynchronously await a promise and invoke a finally continuation that always overrides the result
589export function _finally(body, finalizer) {
590 try {
591 var result = body();
592 } catch (e) {
593 return finalizer();
594 }
595 if (result && result.then) {
596 return result.then(finalizer, finalizer);
597 }
598 return finalizer();
599}
600
601// Rethrow or return a value from a finally continuation
602export function _rethrow(thrown, value) {
603 if (thrown)
604 throw value;
605 return value;
606}
607
608// Empty function to implement break and other control flow that ignores asynchronous results
609export function _empty() {
610}
611
612// Sentinel value for early returns in generators
613export const _earlyReturn = /*#__PURE__*/ {};
614
615// Asynchronously call a function and send errors to recovery continuation, skipping early returns
616export function _catchInGenerator(body, recover) {
617 return _catch(body, function(e) {
618 if (e === _earlyReturn) {
619 throw e;
620 }
621 return recover(e);
622 });
623}
624
625// Asynchronous generator class; accepts the entrypoint of the generator, to which it passes itself when the generator should start
626export const _AsyncGenerator = /*#__PURE__*/(function() {
627 function _AsyncGenerator(entry) {
628 this._entry = entry;
629 this._pact = null;
630 this._resolve = null;
631 this._return = null;
632 this._promise = null;
633 }
634
635 function _wrapReturnedValue(value) {
636 return { value: value, done: true };
637 }
638 function _wrapYieldedValue(value) {
639 return { value: value, done: false };
640 }
641
642 _AsyncGenerator.prototype._yield = function(value) {
643 // Yield the value to the pending next call
644 this._resolve(value && value.then ? value.then(_wrapYieldedValue) : _wrapYieldedValue(value));
645 // Return a pact for an upcoming next/return/throw call
646 return this._pact = new _Pact();
647 };
648 _AsyncGenerator.prototype.next = function(value) {
649 // Advance the generator, starting it if it has yet to be started
650 const _this = this;
651 return _this._promise = new Promise(function (resolve) {
652 const _pact = _this._pact;
653 if (_pact === null) {
654 const _entry = _this._entry;
655 if (_entry === null) {
656 // Generator is started, but not awaiting a yield expression
657 // Abandon the next call!
658 return resolve(_this._promise);
659 }
660 // Start the generator
661 _this._entry = null;
662 _this._resolve = resolve;
663 function returnValue(value) {
664 _this._resolve(value && value.then ? value.then(_wrapReturnedValue) : _wrapReturnedValue(value));
665 _this._pact = null;
666 _this._resolve = null;
667 }
668 var result = _entry(_this);
669 if (result && result.then) {
670 result.then(returnValue, function(error) {
671 if (error === _earlyReturn) {
672 returnValue(_this._return);
673 } else {
674 const pact = new _Pact();
675 _this._resolve(pact);
676 _this._pact = null;
677 _this._resolve = null;
678 _resolve(pact, 2, error);
679 }
680 });
681 } else {
682 returnValue(result);
683 }
684 } else {
685 // Generator is started and a yield expression is pending, settle it
686 _this._pact = null;
687 _this._resolve = resolve;
688 _settle(_pact, 1, value);
689 }
690 });
691 };
692 _AsyncGenerator.prototype.return = function(value) {
693 // Early return from the generator if started, otherwise abandons the generator
694 const _this = this;
695 return _this._promise = new Promise(function (resolve) {
696 const _pact = _this._pact;
697 if (_pact === null) {
698 if (_this._entry === null) {
699 // Generator is started, but not awaiting a yield expression
700 // Abandon the return call!
701 return resolve(_this._promise);
702 }
703 // Generator is not started, abandon it and return the specified value
704 _this._entry = null;
705 return resolve(value && value.then ? value.then(_wrapReturnedValue) : _wrapReturnedValue(value));
706 }
707 // Settle the yield expression with a rejected "early return" value
708 _this._return = value;
709 _this._resolve = resolve;
710 _this._pact = null;
711 _settle(_pact, 2, _earlyReturn);
712 });
713 };
714 _AsyncGenerator.prototype.throw = function(error) {
715 // Inject an exception into the pending yield expression
716 const _this = this;
717 return _this._promise = new Promise(function (resolve, reject) {
718 const _pact = _this._pact;
719 if (_pact === null) {
720 if (_this._entry === null) {
721 // Generator is started, but not awaiting a yield expression
722 // Abandon the throw call!
723 return resolve(_this._promise);
724 }
725 // Generator is not started, abandon it and return a rejected Promise containing the error
726 _this._entry = null;
727 return reject(error);
728 }
729 // Settle the yield expression with the value as a rejection
730 _this._resolve = resolve;
731 _this._pact = null;
732 _settle(_pact, 2, error);
733 });
734 };
735
736 _AsyncGenerator.prototype[_asyncIteratorSymbol] = function() {
737 return this;
738 };
739
740 return _AsyncGenerator;
741})();