import { validate as isUUID } from 'uuid';
export const typeRegistry = new Map();
export class AbstractCellType {
    is(t) {
        return this instanceof t.constructor;
    }
}
function isCellTypeConstructor(fn) {
    return fn === AbstractCellType || fn.prototype instanceof AbstractCellType;
}
export function defineCellType(id, displayName, defaultValue, validate, extended) {
    if (!isUUID(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;
    }
}
export const numberCellType = defineCellType('21112007-716a-4c28-80f3-a058aea50a0b', 'number', 0, (value) => typeof value === 'number');
export const stringCellType = defineCellType('00bfb075-9d08-4ab6-ba2d-f7bcccdb09b0', 'string', '', (value) => typeof value === 'string');
export const objectCellType = defineCellType('e01e830e-8dd5-4c2e-a8eb-dc3945d8c001', 
// name in `python`
'dict', {}, (value) => typeof value === 'object');
export const booleanCellType = defineCellType('1b692f8e-6f4d-4708-bf04-e624e7101a3d', 'boolean', false, (value) => typeof value === 'boolean');
export const arrayCellType = defineCellType('6f84aa0b-aa88-48e3-96f8-c19f00f60ee0', 'array', [], (value) => Array.isArray(value));
export const baseCellTypes = {
    array: arrayCellType,
    boolean: booleanCellType,
    object: objectCellType,
    number: numberCellType,
    string: stringCellType
};
export function createSheetFunction(id, name, type, inputs, outputs, defaultConfig, fn, configPanel, description) {
    return {
        id,
        type,
        [type === 'reduce' ? 'input' : 'inputs']: inputs,
        [type === 'reduce' ? 'output' : 'outputs']: outputs,
        name,
        defaultConfig,
        fn,
        configPanel,
        description
    };
}
//# sourceMappingURL=index.js.map