UNPKG

vasille-jsx

Version:

The first Developer eXperience Orientated front-end framework (JSX components)

94 lines (93 loc) 2.84 kB
import { Fragment, App, reportError, IValue, Reference } from "vasille"; function create(node, renderer, props, callback, slot, name) { if (!node) { throw new Error("Vasille: Component context is missing"); } const frag = new Fragment(props, node.runner, name); if (slot) { props.slot = slot; } node.create(frag); try { const result = renderer(frag, props); if (result !== undefined && callback) { callback(result); } } catch (e) { reportError(e); } } function fieldError(key) { return new Error([ `Vasille: Field ${key} has a reactive value, which is not allowed in model.`, "Use bridge.stored() to disable the reactivity of value,", "or hybridView properties parameter which accepts reactive values.", ].join(" ")); } function getProp(target, p, isModel) { if (isModel) { const value = target[p]; if (value instanceof IValue) { throw fieldError(String(p)); } return value; } else { const value = target[p]; if (value instanceof IValue) { return value; } return (target[p] = new Reference(target[p])); } } export function mvvmView(renderer, name) { return function (props, node, slot) { create(node, renderer, new Proxy(props, { get(target, p) { return getProp(target, p); }, }), props.callback, slot, name); }; } export function mvcView(renderer, name) { return function (props, node, slot) { for (const key in props) { if (props[key] instanceof IValue) { throw fieldError(key); } } create(node, renderer, props, props.callback, slot, name); }; } export function hybridView(renderer, modelProps, name) { if (modelProps.length === 0) { return mvvmView(renderer, name); } else if (modelProps.length === 1) { const key = modelProps[0]; return function (props, node, slot) { create(node, renderer, new Proxy(props, { get(target, p) { return getProp(target, p, key === p); }, }), props.callback, slot, name); }; } const modelPropsSet = new Set(modelProps); return function (props, node, slot) { create(node, renderer, new Proxy(props, { get(target, p) { return getProp(target, p, modelPropsSet.has(p)); }, }), props.callback, slot, name); }; } export function mount(tag, view, runner, $) { const root = new App(tag, runner, {}); const frag = new Fragment({}, runner, ":app-root"); root.create(frag, function () { view($, frag); }); return root; }