@@ -780,337 +780,6 @@ class Tooltip {
780780 }
781781} ;
782782
783- /**
784- * Creates an asynchronous construct similar to a Promise. The only difference is that it accepts a spread (array) of arguments for its resolver and/or rejector.
785- * @simply new Async(ƒ (onResolve, onReject)) → Async<#Promise>
786- *
787- * @author Medium {@link https://medium.com/@manojsingh047/polyfill-for-javascript-promise-81053b284e37 @manojsingh047}
788- * @see https://medium.com/@manojsingh047/polyfill-for-javascript-promise-81053b284e37
789- */
790- class Async {
791- /** @typedef {string } AsyncStatus
792- * The status of an Async (Promise-like) object
793- *
794- * @property {string } PENDING - Denotes a pending (not resolved or rejected) Async
795- * @property {string } FULFILLED - Denotes a fulfilled (resolved) Async
796- * @property {string } REJECTED - Denotes a rejected (rejected) Async
797- */
798- static PENDING = 'pending' ;
799- static FULFILLED = 'fulfilled' ;
800- static REJECTED = 'rejected' ;
801-
802- #resolvers = [ ] ;
803- #values;
804-
805- #rejectors = [ ] ;
806- #errors;
807-
808- #chain = [ ] ;
809-
810- #status = Async . PENDING ;
811- #volley = Async . PENDING ;
812- #called = false ;
813- #settled = false ;
814- #fulfilled = false ;
815- #rejected = false ;
816-
817- /** @constructor
818- *
819- * @param {function } executor The same arguments for Promises: a resolver, and (optional) rejector.
820- * @return {Async } Returns a Promise-like object
821- */
822- constructor ( executor ) {
823- return executor ( this . #resolver. bind ( this ) , this . #rejector. bind ( this ) ) ;
824- }
825-
826- /**
827- * A method to chain Promise-like resolutions.
828- * Returns an {Async} object, allowing you to chain calls to other async methods.
829- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then Promise.prototype.then}.
830- *
831- * @param {function } callback The function to call when the previous {Async} or <b>then</b> fulfills
832- * @return {Async } The values that the {Async} or previous <b>then</b> was fulfilled with
833- */
834- then ( callback ) {
835- this . #resolvers. push ( callback ) ;
836- this . #chain. push ( callback ) ;
837-
838- Object . defineProperties ( callback , { signal : { value : Async . FULFILLED } } ) ;
839-
840- return this ;
841- }
842-
843- /**
844- * A method to chain Promise-like rejections.
845- * Returns an {Async} object, allowing you to chain calls to other async methods.
846- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch Promise.prototype.catch}.
847- *
848- * @param {function } callback The function to call when the previous {Async} or <b>catch</b> rejects
849- * @return {Async } The errors that the {Async} or previous <b>catch</b> was rejected with
850- */
851- catch ( callback ) {
852- this . #rejectors. push ( callback ) ;
853- this . #chain. push ( callback ) ;
854-
855- Object . defineProperties ( callback , { signal : { value : Async . REJECTED } } ) ;
856-
857- return this ;
858- }
859-
860- /**
861- * A method to terminate Promise-like streams.
862- * Returns an {Async} object, allowing you to chain calls to other async methods.
863- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally Promise.prototype.finally}.
864- *
865- * @param {function } callback The function to call when the previous {Async} or <b>then</b> fulfills
866- * @return {Async } The values that the {Async} or previous <b>then</b> was fulfilled with
867- */
868- finally ( callback ) {
869- this . #chain. push ( callback ) ;
870-
871- return this ;
872- }
873-
874- /**
875- * Returns the status of the Async
876- *
877- * @return {AsyncStatus } Returns the pending status of the Async
878- */
879- status ( ) {
880- let pending = Symbol ( Async . PENDING ) ;
881-
882- return Async . race ( [ this , pending ] ) . then ( response => response === pending ? Async . PENDING : Async . FULFILLED , ( ) => Async . REJECTED ) ;
883- }
884-
885- /**
886- * Returns a resolved {Async} object.
887- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve Promise.resolve}.
888- *
889- * @param {any } [...values] The values to pass to the following <b>then</b>
890- * @return {any[] } All of the values that were given
891- */
892- static resolve ( ...values ) {
893- return new Async ( function ( resolve , reject ) {
894- resolve . apply ( this , values ) ;
895- } ) ;
896- }
897-
898- /**
899- * Returns a rejected {Async} object.
900- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject Promise.reject}.
901- *
902- * @param {any } [...errors] The errors to pass to the following <b>catch</b>
903- * @return {Error[] } All of the errors that were caught
904- */
905- static reject ( ...errors ) {
906- return new Async ( function ( resolve , reject ) {
907- reject . apply ( this , errors ) ;
908- } ) ;
909- }
910-
911- /**
912- * Returns an array once <strong>all</strong> Asyncs have fulfilled.
913- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all Promise.all}.
914- *
915- * @param {Async } [...asyncs] The Asyncs to iterate and wait for fulfillment
916- * @return {(Async|Error) } This will fulfill to a promise or the first rejection
917- */
918- static all ( asyncs ) {
919- return new Async ( function ( resolve , reject ) {
920- let finished = 0 ;
921- let responses = [ ] ;
922-
923- if ( asyncs . length == 0 )
924- return resolve ( asyncs ) ;
925-
926- for ( let index = 0 ; index < asyncs . length ; ++ index )
927- asyncs [ index ]
928- . then ( ( ...values ) => done ( values , index ) )
929- . catch ( ( ...errors ) => reject . apply ( this , errors ) ) ;
930-
931- function done ( values , index ) {
932- ++ finished ;
933- responses [ index ] = values ;
934-
935- if ( finished == asyncs . length )
936- resolve . apply ( this , values ) ;
937- }
938- } ) ;
939- }
940-
941- /**
942- * Returns an array of Async statuses.
943- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled Promise.allSettled}.
944- *
945- * @param {Async } [...asyncs] The Asyncs to iterate and retrieve statuses from
946- * @return {object[] } This will be an array of objects that describe each Async's status
947- */
948- static allSettled ( asyncs ) {
949- return new Async ( function ( resolve , reject ) {
950- let settled = 0 ;
951- let statuses = [ ] ;
952-
953- for ( let index = 0 ; index < asyncs . length ; ++ index )
954- asyncs [ index ]
955- . then ( ( ...values ) => done ( values , index ) )
956- . catch ( ( ...errors ) => fail ( errors , index ) ) ;
957-
958- function done ( values , index ) {
959- ++ settled ;
960- statuses [ index ] = { status : 'fulfilled' , values } ;
961-
962- if ( settled == asyncs . length )
963- resolve . apply ( this , statuses ) ;
964- }
965-
966- function fail ( reasons , index ) {
967- ++ settled ;
968- statuses [ index ] = { status : 'rejected' , reasons } ;
969-
970- if ( settled == asyncs . length )
971- resolve . apply ( this , statuses ) ;
972- }
973- } ) ;
974- }
975-
976- /**
977- * Returns the first fulfilled Async, or an array of rejections.
978- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any Promise.any}.
979- *
980- * @param {Async } [...asyncs] The Asyncs to iterate
981- * @return {(any|AggregateError) } This will be a fulfillment or AggregateError (array)
982- */
983- static any ( asyncs ) {
984- return new Async ( function ( resolve , reject ) {
985- let failed = 0 ;
986- let reasons = [ ] ;
987-
988- if ( asyncs . length == 0 )
989- return resolve ( asyncs ) ;
990-
991- for ( let index = 0 ; index < asyncs . length ; ++ index )
992- asyncs [ index ]
993- . then ( ( ...values ) => resolve . apply ( this , values ) )
994- . catch ( ( ...errors ) => fail ( errors , index ) ) ;
995-
996- function fail ( errors , index ) {
997- ++ failed ;
998- reasons [ index ] = errors ;
999-
1000- if ( failed == asyncs . length )
1001- reject . apply ( this , new AggregateError ( errors ) ) ;
1002- }
1003- } ) ;
1004- }
1005-
1006- /**
1007- * Returns the first fulfilled Async, or an array of rejections.
1008- *
1009- * @param {Async } [...asyncs] The Asyncs to iterate
1010- * @return {(any|Error[]) } This will be a fulfillment or array of rejections
1011- */
1012- static anySettled ( asyncs ) {
1013- let errors = new Array ( asyncs . length ) ;
1014- let errd = 0 ;
1015-
1016- return new Async ( ( resolve , reject ) => {
1017- asyncs . map ( ( promise , index ) => {
1018- Async . resolve ( promise )
1019- // Resolve the async to a non-empty value
1020- . then ( result => {
1021- if ( nullish ( result ) )
1022- throw result ;
1023- resolve ( result ) ;
1024- } )
1025- // Reject the value, immediately
1026- . catch ( error => {
1027- errors [ index ] = error ;
1028-
1029- // All asyncs rejected; reject parent
1030- if ( ++ errd == promises . length )
1031- reject ( errors ) ;
1032- } ) ;
1033- } ) ;
1034- } ) ;
1035- }
1036-
1037- /**
1038- * Returns the first fulfilled Async.
1039- * Similar to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race Promise.race}.
1040- *
1041- * @param {Async } [...asyncs] The Asyncs to iterate
1042- * @return {Async } This will be a fulfillment or AggregateError (array)
1043- */
1044- static race ( asyncs ) {
1045- return new Async ( function ( resolve , reject ) {
1046- for ( let async of asyncs )
1047- async
1048- . then ( ( ...values ) => resolve . apply ( this , values ) )
1049- . catch ( ( ...errors ) => reject . apply ( this , errors ) ) ;
1050- } ) ;
1051- }
1052-
1053- #resolver( ...values ) {
1054- this . #status = Async . FULFILLED ;
1055- this . #volley = Async . FULFILLED ;
1056- this . #fulfilled = true ;
1057- this . #settled = true ;
1058- this . #values = values ;
1059-
1060- if ( ! this . #called) {
1061- this . #called = true ;
1062-
1063- chaining: for ( let callback of this . #chain)
1064- if ( ! callback . consumed ) {
1065- if ( callback . signal && ( this . #status != callback . signal ) && ( this . #volley != callback . signal ) )
1066- continue chaining;
1067-
1068- Object . defineProperties ( callback , { consumed : { value : true } } ) ;
1069-
1070- let values = this . #values;
1071-
1072- if ( ! ( values instanceof Array ) )
1073- values = Array . of ( values ) ;
1074-
1075- // If an error is raised within a `then` callback, raise the error and deviate to the `catch` chain
1076- try {
1077- this . #values = callback . apply ( this , values ) ;
1078- } catch ( error ) {
1079- this . #volley = Async . REJECTED ;
1080- }
1081- }
1082- }
1083- }
1084-
1085- #rejector( ...errors ) {
1086- this . #status = Async . REJECTED ;
1087- this . #volley = Async . REJECTED ;
1088- this . #rejected = true ;
1089- this . #settled = true ;
1090- this . #errors = errors ;
1091-
1092- if ( ! this . #called) {
1093- this . #called = true ;
1094-
1095- chaining: for ( let callback of this . #chain)
1096- if ( ! callback . consumed ) {
1097- if ( callback . signal && ( this . #status != callback . signal ) && ( this . #volley != callback . signal ) )
1098- continue chaining;
1099-
1100- Object . defineProperties ( callback , { consumed : { value : true } } ) ;
1101-
1102- let errors = this . #errors;
1103-
1104- if ( ! ( errors instanceof Array ) )
1105- errors = Array . of ( errors ) ;
1106-
1107- // Errors cannot be volleyed back :P
1108- this . #errors = callback . apply ( this , errors ) ;
1109- }
1110- }
1111- }
1112- }
1113-
1114783/** @typedef {string } CSSSelector
1115784 * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors CSS selectors}
1116785 */
0 commit comments