' @rokucommunity/promises v0.5.0
    ' Create a new promise
    namespace rooibos.promises
function create() as dynamic
    end function
end namespace
    ' TODO rename this to `then` once BrighterScript supports using keywords as namespaced function names
    namespace rooibos.promises
function onThen(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
    end function
end namespace
    ' TODO rename this to `catch` once BrighterScript supports using keywords as namespaced function names
    namespace rooibos.promises
function onCatch(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
    end function
end namespace
    ' TODO rename this to `finally` once BrighterScript supports using keywords as namespaced function names
    namespace rooibos.promises
function onFinally(promise as dynamic, callback as function, context = "__INVALID__" as object) as dynamic
    end function
end namespace
    ' Takes an array of promises as input and returns a single Promise.
    ' This returned promise fulfills when all of the input's promises fulfill (including when an empty array is passed), with an array of the fulfillment values.
    ' It rejects when any of the input's promises rejects, with this first rejection reason.
    namespace rooibos.promises
function all(promiseArray as dynamic) as dynamic
    end function
end namespace
    ' Takes an array of promises as input and returns a single Promise.
    ' This returned promise fulfills when all of the input's promises settle (including when an empty array is passed),
    ' with an array of objects that describe the outcome of each promise.
    namespace rooibos.promises
function allSettled(promiseArray as dynamic) as dynamic
    end function
end namespace
    ' Takes an array of promises as input and returns a single Promise.
    ' This returned promise fulfills when any of the input's promises fulfills, with this first fulfillment value.
    ' It rejects when all of the input's promises reject (including when an empty array is passed), with an AggregateError containing an array of rejection reasons.
    namespace rooibos.promises
function any(promiseArray as dynamic) as dynamic
    end function
end namespace
    ' Takes an array of promises as input and returns a single Promise.
    ' This returned promise settles with the eventual state of the first promise that settles.
    namespace rooibos.promises
function race(promiseArray as dynamic) as dynamic
    end function
end namespace
    namespace rooibos.promises
function resolve(result as dynamic, promise = invalid as dynamic) as object
    end function
end namespace
    namespace rooibos.promises
function reject(error as dynamic, promise = invalid as dynamic) as object
    end function
end namespace
    namespace rooibos.promises
function isComplete(promise as object) as boolean
    end function
end namespace
    ' Determines if the given item is a promise.
    '
    ' Will return true if at least one of the following conditions are true:
    ' - the SubType exactly equals "Promise"
    ' - the subtype ends with "_promise" case insensitive
    ' - the node has a field called "promiseState"
    namespace rooibos.promises
function isPromise(promise as dynamic) as boolean
    end function
end namespace
    ' Remove all promise storage from the current m
    namespace rooibos.promises
sub clean()
    end sub
end namespace
    'Allows chaining multiple promise operations in a row in a clean syntax
    namespace rooibos.promises
function chain(initialPromise as object, context = "__INVALID__" as object) as object
    end function
end namespace
    ' Makes sure the value supplied is a promise
    namespace rooibos.promises
function ensurePromise(value as object) as object
    end function
end namespace
    namespace rooibos.promises
enum PromiseState
        pending = "pending"
        resolved = "resolved"
        rejected = "rejected"
    end enum
end namespace
    namespace rooibos.promises
interface AggregateError
        message as string
        ' array of dynamic rejected values
        errors as dynamic
    end interface
end namespace

namespace rooibos.promises.internal
    enum PromiseState
        pending = "pending"
        resolved = "resolved"
        rejected = "rejected"
    end enum
    enum PromiseField
        promiseState = "promiseState"
        promiseResult = "promiseResult"
    end enum
    ' Clear storage for a given promise
    sub clearPromiseStorage(promise as object)
    end sub
    ' Get the storage for a promise on `m`
    function getPromiseStorage(promise as object) as object
    end function
    '
    ' Registers a listener for a promise for the then, catch, or finally events
    ' @param eventName - should be "then", "catch", or "finally"
    '
    function on(eventName as string, promise as dynamic, callback as function, context = {} as object) as dynamic
    end function
    '
    ' Notify all the listeners of a promise that it has been completed
    '
    sub notifyListeners(event as object)
    end sub
    ' Used to check if there is a storage item of listeners for the supplied promise
    function hasStorage(promise as dynamic) as boolean
    end function
    ' We use an internal value to represent unset. Check if the parameter is that value
    function isSet(value as dynamic) as boolean
    end function
    ' Is the supplied value a valid String type and is not empty
    ' @param value - The variable to be checked
    ' @return true if value is a non-empty string, false otherwise
    function isNonEmptyString(value as dynamic) as boolean
    end function
    ' Handle an individual promise listener
    sub processPromiseListener(originalPromise as object, storageItem as object, callCallback as boolean, promiseValue = "__INVALID__" as dynamic)
    end sub
    '
    ' Generates a new UUID
    '
    function createUuid() as string
    end function
    ' Makes a delayed call to the supplied function. Default behavior is essentially next tick.
    ' @param {Function} callback - The function to be called after a set delay
    ' @param {Dynamic} context - a single item of data to be passed into the callback when invoked
    ' @param {Float} [duration] - the amount of delay before invoking the callback
    sub delay(callback as function, context as dynamic, duration = 0.0001 as float)
    end sub
    ' Observes a node field using observeFieldScoped
    ' @param {roSGNode} node - The node to apply the observer
    ' @param {String} field - The name of the field to be monitored.
    ' @param {Dynamic} callback - The name or message port to be executed when the value of the field changes.
    ' @return true if field could be observed, false if not
    function observeFieldScoped(node as object, field as string, callback as dynamic, infoFields = [] as object)
    end function
    ' Unobserve a node field using unobserveFieldScoped
    ' @param {roSGNode} node - The node to remove the observer from
    ' @param {String} field - The name of the field to no longer be monitored.
    ' @return true if field could be unobserved, false if not
    function unobserveFieldScoped(node as object, field as string)
    end function
end namespace
