forked from annv/MinigameTest
minigame
This commit is contained in:
271
node_modules/selenium-webdriver/lib/promise.js
generated
vendored
Normal file
271
node_modules/selenium-webdriver/lib/promise.js
generated
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines a handful of utility functions to simplify working
|
||||
* with promises.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const { isObject, isPromise } = require('./util')
|
||||
|
||||
/**
|
||||
* Creates a promise that will be resolved at a set time in the future.
|
||||
* @param {number} ms The amount of time, in milliseconds, to wait before
|
||||
* resolving the promise.
|
||||
* @return {!Promise<void>} The promise.
|
||||
*/
|
||||
function delayed(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a function that expects a node-style callback as its final
|
||||
* argument. This callback expects two arguments: an error value (which will be
|
||||
* null if the call succeeded), and the success value as the second argument.
|
||||
* The callback will the resolve or reject the returned promise, based on its
|
||||
* arguments.
|
||||
* @param {!Function} fn The function to wrap.
|
||||
* @param {...?} args The arguments to apply to the function, excluding the
|
||||
* final callback.
|
||||
* @return {!Thenable} A promise that will be resolved with the
|
||||
* result of the provided function's callback.
|
||||
*/
|
||||
function checkedNodeCall(fn, ...args) {
|
||||
return new Promise(function (fulfill, reject) {
|
||||
try {
|
||||
fn(...args, function (error, value) {
|
||||
error ? reject(error) : fulfill(value)
|
||||
})
|
||||
} catch (ex) {
|
||||
reject(ex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a listener to invoke when a promise is resolved, regardless
|
||||
* of whether the promise's value was successfully computed. This function
|
||||
* is synonymous with the {@code finally} clause in a synchronous API:
|
||||
*
|
||||
* // Synchronous API:
|
||||
* try {
|
||||
* doSynchronousWork();
|
||||
* } finally {
|
||||
* cleanUp();
|
||||
* }
|
||||
*
|
||||
* // Asynchronous promise API:
|
||||
* doAsynchronousWork().finally(cleanUp);
|
||||
*
|
||||
* __Note:__ similar to the {@code finally} clause, if the registered
|
||||
* callback returns a rejected promise or throws an error, it will silently
|
||||
* replace the rejection error (if any) from this promise:
|
||||
*
|
||||
* try {
|
||||
* throw Error('one');
|
||||
* } finally {
|
||||
* throw Error('two'); // Hides Error: one
|
||||
* }
|
||||
*
|
||||
* let p = Promise.reject(Error('one'));
|
||||
* promise.finally(p, function() {
|
||||
* throw Error('two'); // Hides Error: one
|
||||
* });
|
||||
*
|
||||
* @param {!IThenable<?>} promise The promise to add the listener to.
|
||||
* @param {function(): (R|IThenable<R>)} callback The function to call when
|
||||
* the promise is resolved.
|
||||
* @return {!Promise<R>} A promise that will be resolved with the callback
|
||||
* result.
|
||||
* @template R
|
||||
*/
|
||||
async function thenFinally(promise, callback) {
|
||||
try {
|
||||
await Promise.resolve(promise)
|
||||
return callback()
|
||||
} catch (e) {
|
||||
await callback()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an array and inserts the result into a
|
||||
* new array, which is used as the fulfillment value of the promise returned
|
||||
* by this function.
|
||||
*
|
||||
* If the return value of the mapping function is a promise, this function
|
||||
* will wait for it to be fulfilled before inserting it into the new array.
|
||||
*
|
||||
* If the mapping function throws or returns a rejected promise, the
|
||||
* promise returned by this function will be rejected with the same reason.
|
||||
* Only the first failure will be reported; all subsequent errors will be
|
||||
* silently ignored.
|
||||
*
|
||||
* @param {!(Array<TYPE>|IThenable<!Array<TYPE>>)} array The array to iterate
|
||||
* over, or a promise that will resolve to said array.
|
||||
* @param {function(this: SELF, TYPE, number, !Array<TYPE>): ?} fn The
|
||||
* function to call for each element in the array. This function should
|
||||
* expect three arguments (the element, the index, and the array itself.
|
||||
* @param {SELF=} self The object to be used as the value of 'this' within `fn`.
|
||||
* @template TYPE, SELF
|
||||
*/
|
||||
async function map(array, fn, self = undefined) {
|
||||
const v = await Promise.resolve(array)
|
||||
if (!Array.isArray(v)) {
|
||||
throw TypeError('not an array')
|
||||
}
|
||||
|
||||
const arr = /** @type {!Array} */ (v)
|
||||
const values = []
|
||||
|
||||
for (const [index, item] of arr.entries()) {
|
||||
values.push(await Promise.resolve(fn.call(self, item, index, arr)))
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an array, and if the function returns
|
||||
* true adds the element to a new array.
|
||||
*
|
||||
* If the return value of the filter function is a promise, this function
|
||||
* will wait for it to be fulfilled before determining whether to insert the
|
||||
* element into the new array.
|
||||
*
|
||||
* If the filter function throws or returns a rejected promise, the promise
|
||||
* returned by this function will be rejected with the same reason. Only the
|
||||
* first failure will be reported; all subsequent errors will be silently
|
||||
* ignored.
|
||||
*
|
||||
* @param {!(Array<TYPE>|IThenable<!Array<TYPE>>)} array The array to iterate
|
||||
* over, or a promise that will resolve to said array.
|
||||
* @param {function(this: SELF, TYPE, number, !Array<TYPE>): (
|
||||
* boolean|IThenable<boolean>)} fn The function
|
||||
* to call for each element in the array.
|
||||
* @param {SELF=} self The object to be used as the value of 'this' within `fn`.
|
||||
* @template TYPE, SELF
|
||||
*/
|
||||
async function filter(array, fn, self = undefined) {
|
||||
const v = await Promise.resolve(array)
|
||||
if (!Array.isArray(v)) {
|
||||
throw TypeError('not an array')
|
||||
}
|
||||
|
||||
const arr = /** @type {!Array} */ (v)
|
||||
const values = []
|
||||
|
||||
for (const [index, item] of arr.entries()) {
|
||||
const isConditionTrue = await Promise.resolve(
|
||||
fn.call(self, item, index, arr)
|
||||
)
|
||||
if (isConditionTrue) {
|
||||
values.push(item)
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise that will be resolved with the input value in a
|
||||
* fully-resolved state. If the value is an array, each element will be fully
|
||||
* resolved. Likewise, if the value is an object, all keys will be fully
|
||||
* resolved. In both cases, all nested arrays and objects will also be
|
||||
* fully resolved. All fields are resolved in place; the returned promise will
|
||||
* resolve on {@code value} and not a copy.
|
||||
*
|
||||
* Warning: This function makes no checks against objects that contain
|
||||
* cyclical references:
|
||||
*
|
||||
* var value = {};
|
||||
* value['self'] = value;
|
||||
* promise.fullyResolved(value); // Stack overflow.
|
||||
*
|
||||
* @param {*} value The value to fully resolve.
|
||||
* @return {!Thenable} A promise for a fully resolved version
|
||||
* of the input value.
|
||||
*/
|
||||
async function fullyResolved(value) {
|
||||
value = await Promise.resolve(value)
|
||||
if (Array.isArray(value)) {
|
||||
return fullyResolveKeys(/** @type {!Array} */ (value))
|
||||
}
|
||||
|
||||
if (isObject(value)) {
|
||||
return fullyResolveKeys(/** @type {!Object} */ (value))
|
||||
}
|
||||
|
||||
if (typeof value === 'function') {
|
||||
return fullyResolveKeys(/** @type {!Object} */ (value))
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!(Array|Object)} obj the object to resolve.
|
||||
* @return {!Thenable} A promise that will be resolved with the
|
||||
* input object once all of its values have been fully resolved.
|
||||
*/
|
||||
async function fullyResolveKeys(obj) {
|
||||
const isArray = Array.isArray(obj)
|
||||
const numKeys = isArray ? obj.length : Object.keys(obj).length
|
||||
|
||||
if (!numKeys) {
|
||||
return obj
|
||||
}
|
||||
|
||||
async function forEachProperty(obj, fn) {
|
||||
for (let key in obj) {
|
||||
await fn(obj[key], key)
|
||||
}
|
||||
}
|
||||
|
||||
async function forEachElement(arr, fn) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
await fn(arr[i], i)
|
||||
}
|
||||
}
|
||||
|
||||
const forEachKey = isArray ? forEachElement : forEachProperty
|
||||
await forEachKey(obj, async function (partialValue, key) {
|
||||
if (
|
||||
!Array.isArray(partialValue) &&
|
||||
(!partialValue || typeof partialValue !== 'object')
|
||||
) {
|
||||
return
|
||||
}
|
||||
obj[key] = await fullyResolved(partialValue)
|
||||
})
|
||||
return obj
|
||||
}
|
||||
|
||||
// PUBLIC API
|
||||
|
||||
module.exports = {
|
||||
checkedNodeCall,
|
||||
delayed,
|
||||
filter,
|
||||
finally: thenFinally,
|
||||
fullyResolved,
|
||||
isPromise,
|
||||
map,
|
||||
}
|
||||
Reference in New Issue
Block a user