/// <reference types="./python.d.ts" />
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('uuid')) :
    typeof define === 'function' && define.amd ? define(['exports', 'uuid'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DevKit = {}, global.uuid));
})(this, (function (exports, uuid) { 'use strict';

    const typeRegistry = new Map();
    class AbstractCellType {
        is(t) {
            return this instanceof t.constructor;
        }
    }
    function isCellTypeConstructor(fn) {
        return fn === AbstractCellType || fn.prototype instanceof AbstractCellType;
    }
    function defineCellType(id, displayName, defaultValue, validate, extended) {
        if (!uuid.validate(id)) {
            throw new TypeError('\'id\' is not a uuid');
        }
        else if (typeRegistry.has(id)) {
            if (typeof window === 'undefined') {
                // Server Side Rendering
                //  early return
                return typeRegistry.get(id);
            }
            throw new Error(`'id' ${id} already exists`);
        }
        else {
            let SuperCellType;
            if (extended) {
                if (!isCellTypeConstructor(extended.constructor)) {
                    throw new TypeError('\'extended\' is not an instance of \'AbstractCellType\'');
                }
                SuperCellType = extended.constructor;
            }
            else {
                SuperCellType = AbstractCellType;
            }
            const cellType = new (class extends SuperCellType {
                constructor() {
                    super(...arguments);
                    Object.defineProperty(this, "id", {
                        enumerable: true,
                        configurable: true,
                        writable: true,
                        value: id
                    });
                    Object.defineProperty(this, "displayName", {
                        enumerable: true,
                        configurable: true,
                        writable: true,
                        value: displayName
                    });
                    Object.defineProperty(this, "defaultValue", {
                        enumerable: true,
                        configurable: true,
                        writable: true,
                        value: defaultValue
                    });
                    Object.defineProperty(this, "validate", {
                        enumerable: true,
                        configurable: true,
                        writable: true,
                        value: validate
                    });
                }
            })();
            typeRegistry.set(id, cellType);
            return cellType;
        }
    }
    const numberCellType = defineCellType('21112007-716a-4c28-80f3-a058aea50a0b', 'number', 0, (value) => typeof value === 'number');
    const stringCellType = defineCellType('00bfb075-9d08-4ab6-ba2d-f7bcccdb09b0', 'string', '', (value) => typeof value === 'string');
    const objectCellType = defineCellType('e01e830e-8dd5-4c2e-a8eb-dc3945d8c001', 
    // name in `python`
    'dict', {}, (value) => typeof value === 'object');
    const booleanCellType = defineCellType('1b692f8e-6f4d-4708-bf04-e624e7101a3d', 'boolean', false, (value) => typeof value === 'boolean');
    const arrayCellType = defineCellType('6f84aa0b-aa88-48e3-96f8-c19f00f60ee0', 'array', [], (value) => Array.isArray(value));
    const baseCellTypes = {
        array: arrayCellType,
        boolean: booleanCellType,
        object: objectCellType,
        number: numberCellType,
        string: stringCellType
    };

    const f = (...args) => fetch(...args)
        .then(response => response.json());
    function matchType(type) {
        switch (type) {
            case 'str': {
                return baseCellTypes.string;
            }
            case 'int': {
                return baseCellTypes.number;
            }
            case 'dict': {
                return baseCellTypes.object;
            }
            case 'list': {
                return baseCellTypes.array;
            }
            default: {
                if (type.startsWith('typing.List')) {
                    const size = 'typing.List'.length;
                    return matchType(type.substr(size + 1, type.length - size - 2));
                }
                return baseCellTypes.string;
            }
        }
    }
    async function getList(url, init) {
        return f(url, {
            ...init,
            method: 'GET'
        });
    }
    async function getParam(url, init) {
        return f(url, {
            ...init,
            method: 'GET'
        });
    }
    async function callFunction(url, body, init) {
        return f(url, {
            ...init,
            method: 'POST',
            body: JSON.stringify(body),
            headers: {
                ...init?.headers,
                'Content-Type': 'application/json'
            }
        });
    }

    exports.callFunction = callFunction;
    exports.getList = getList;
    exports.getParam = getParam;
    exports.matchType = matchType;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=python.js.map
