Home Reference Source Test

dist/decoration.js

/**
 * InputKinds are passed into the @Input() decorator to define what data
 * type the inputs takes. If you're using TypeScript and you define the
 * types of your properties, we can automatically infer some of these
 * except for the ones marked "not inferrable".
 *
 * For example:
 *
 * ```
 * @Control({ name: 'button' })
 * class Button {
 *   @Input()
 *   public dimensions: Mixer.IDimensions;
 *
 *   @Input({ kind: Mixer.InputKind.Color })
 *   public background: string;
 * }
 * ```
 */
export var InputKind;
(function (InputKind) {
    InputKind[InputKind["Dimensions"] = 0] = "Dimensions";
    InputKind[InputKind["Number"] = 1] = "Number";
    InputKind[InputKind["String"] = 2] = "String";
    InputKind[InputKind["Boolean"] = 3] = "Boolean";
    InputKind[InputKind["Color"] = 4] = "Color";
    InputKind[InputKind["Duration"] = 5] = "Duration";
    InputKind[InputKind["Url"] = 6] = "Url";
    InputKind[InputKind["JSON"] = 7] = "JSON";
})(InputKind || (InputKind = {}));
const sceneMetaKey = '__mix_scene';
const controlMetaKey = '__miix_control';
const descriptorMetaKey = '__miix_descriptor';
/**
 * The Registry is a simple class that maintains a list of available
 * controls and scenes, and can return them given control kinds or scene IDs.
 */
export class Registry {
    constructor() {
        this.scenes = Object.create(null);
        this.controls = Object.create(null);
        this.config = window.mixerPackageConfig;
    }
    /**
     * Adds a collection of controls and scenes to the registry. This will throw
     * if anything given is not a scene or control.
     * @param {...*} things
     * @returns {Registry}
     */
    register(...things) {
        things.forEach(thing => {
            if (thing[sceneMetaKey]) {
                this.registerScene(thing, thing[sceneMetaKey]);
            }
            else if (thing[controlMetaKey]) {
                this.registerControl(thing, thing[controlMetaKey]);
            }
            else {
                throw new Error(`Passed ${thing.name} to the miix registry, but it wasn't decorated with ` +
                    '@Control or @Scene!');
            }
        });
        return this;
    }
    /**
     * Returns the Control descriptor for a control of the given kind, or
     * thows if it's not found.
     * @param {string} kind
     * @returns {IControlDescriptor}
     * @throws {Error} if the control kind is not found
     */
    getControl(kind) {
        const control = this.controls[kind];
        if (!control) {
            throw new Error(`No control was found for kind "${kind}"! If you have a class already, ` +
                `make sure you're passing it to the Registry.register() function.`);
        }
        return control;
    }
    /**
     * Returns the Scene descriptor for the given scene ID, returning the
     * default scene if a specific handler wasn't found. Throws if no default
     * scene is present and the specific ID is not registered.
     * @param {string} id
     * @returns {ISceneDescriptor}
     * @throws {Error} if an appropriate scene implementation is not found
     */
    getScene(id) {
        const scene = this.scenes[id] || this.defaultScene;
        if (!scene) {
            throw new Error(`No scene class was found for scene ID "${id}" and no default scene was ` +
                `registered! If you have a default handler, make sure you pass it to the ` +
                `Registry.register() function, or create a specific class for this scene.`);
        }
        return scene;
    }
    /**
     * Returns inputs defined on the given control instance.
     * @param {object} control
     * @returns {IInputDescriptor[]}
     * @throws {Error} if the passed object is not decorated with @{@link Scene}
     * or @{@link Control}.
     */
    getInputs(control) {
        const descriptor = control.constructor[descriptorMetaKey];
        if (!descriptor) {
            throw new Error(`Tried to get inputs on ${control.constructor.name}, but it isn't a ` +
                `@Scene or @Control object!`);
        }
        return descriptor.inputs || [];
    }
    registerScene(scene, options) {
        const existing = options.id && this.scenes[options.id];
        const id = options.id || 'default';
        if (existing) {
            throw new Error(`Duplicate scene IDs registered! Both ${existing.ctor.name} and ` +
                `${scene.name} registered themselves for scene ID ${id}`);
        }
        const descriptor = Object.assign({}, options, this.config.scenes[id], { ctor: scene });
        Object.defineProperty(scene, descriptorMetaKey, { value: descriptor });
        this.scenes[id] = descriptor;
        if (options.default) {
            this.defaultScene = descriptor;
        }
    }
    registerControl(control, options) {
        const existing = options.kind && this.controls[options.kind];
        if (existing) {
            throw new Error(`Duplicate controls registered! Both ${existing.ctor.name} and ` +
                `${control.name} registered themselves for control kind ${options.kind}`);
        }
        const descriptor = Object.assign({}, options, this.config.controls[options.kind], { ctor: control });
        Object.defineProperty(control, descriptorMetaKey, { value: descriptor });
        this.controls[options.kind] = descriptor;
    }
}
/**
 * Scene is a decorator you can use to designate a class as a Scene. See
 * documentation on {@link ISceneOptions} for more info.
 * @param {ISceneOptions} [options]
 */
export function Scene(options = { default: true }) {
    return (ctor) => {
        Object.defineProperty(ctor, sceneMetaKey, { value: options });
    };
}
/**
 * Scene is a decorator you can use to designate a class as a Scene. See
 * documentation on {@link IControlOptions} for more info.
 * @param {IControlOptions} [options]
 */
export function Control(options) {
    return (ctor) => {
        Object.defineProperty(ctor, controlMetaKey, { value: options });
    };
}
/**
 * @Input decorates a property on a control. It makes it configurable in the
 * Interactive studio and settable for Preact components. See the
 * {@link IInputOptions} for more info.
 * @param {IInputOptions} [_options]
 */
export function Input(_options = {}) {
    return (_host, _propertyName) => {
        // noop, this is handled by static analysis
    };
}