types/global.js

'use strict';

/**
 * @author schukai GmbH
 */

import {Monster} from '../namespace.js';
import {validateFunction, validateString, validateObject} from "./validate.js";

/**
 * @type {objec}
 * @private
 */
var globalReference;

/**
 * @private
 */
(function () {
    if (typeof globalThis === 'object') {
        globalReference = globalThis;
        return;
    }

    Object.defineProperty(Object.prototype, '__monster__', {
        get: function () {
            return this;
        },
        configurable: true
    });
    
    __monster__.globalThis = __monster__;
    delete Object.prototype.__monster__;

    globalReference = globalThis;

}());

/**
 * return globalThis
 *
 * if globalThis is not available, it will be polyfilled
 *
 * @since 1.6.0
 * @memberOf Monster/Types
 * @returns {objec} globalThis
 */
function getGlobal() {
    return globalReference;
}

/**
 * return global object or throw Error
 *
 * you can call the method via the monster namespace `Monster.Types.getGlobalObject()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/global.js';
 * console.log(Monster.Types.getGlobalObject('document')) // ↦ { }
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this function individually.
 *
 * ```
 * <script type="module">
 * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/global.js';
 * console.log(getGlobalObject('document')) // ↦ { }
 * </script>
 * ```
 *
 * @since 1.6.0
 * @memberOf Monster/Types
 * @param {string} name
 * @returns {objec}
 * @throws {Error} the object is not defined
 * @throws {TypeError} value is not a object
 * @throws {TypeError} value is not a string
 */
function getGlobalObject(name) {
    validateString(name);
    let o = globalReference?.[name];
    if (typeof o === 'undefined') throw new Error('the object '+name+' is not defined');
    validateObject(o);
    return o;
}

/**
 * return global function or throw Error
 *
 * you can call the method via the monster namespace `Monster.Types.getGlobalFunction()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/global.js';
 * console.log(Monster.Types.getGlobalFunction('parseInt')) // ↦ f parseInt() { }
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this function individually.
 *
 * ```
 * <script type="module">
 * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/global.js';
 * console.log(getGlobalFunction('parseInt')) // ↦ f parseInt() { }
 * </script>
 * ```
 *
 * @since 1.6.0
 * @memberOf Monster/Types
 * @param {string} name
 * @returns {objec}
 * @throws {TypeError} value is not a function
 * @throws {Error} the function is not defined
 * @throws {TypeError} value is not a string
 */
function getGlobalFunction(name) {
    validateString(name);
    let f = globalReference?.[name];
    if (typeof f === 'undefined') throw new Error('the function '+name+' is not defined');
    validateFunction(f);
    return f;
}


Monster.assignToNamespace('Monster.Types', getGlobal, getGlobalObject, getGlobalFunction);
export {Monster, getGlobal, getGlobalObject, getGlobalFunction}