vasille-jsx
Version:
The same framework which is designed to build bulletproof frontends (JSX components)
104 lines (103 loc) • 3.24 kB
JavaScript
import { safe, userError } from "vasille";
import { DevArrayModel, DevArrayView, DevFragment, DevMapModel, DevMapView, DevSetModel, DevSetView, DevSwitchedNode, DevWatch as DevCoreWatch, errorToString, } from "vasille/dev";
export function DevSlot({ model, slot, ...options }, ctx, defaultSlot, usage) {
try {
if (model) {
model(options, ctx);
}
else if (slot) {
slot({}, ctx);
}
else if (defaultSlot) {
defaultSlot(ctx);
}
}
catch (e) {
ctx.runner.inspector.reportComponentSlotError({
targetId: "id" in ctx && typeof ctx.id === "number" ? ctx.id : 0,
error: errorToString(e),
usage: usage,
time: Date.now(),
});
console.error(e);
}
}
export function DevSwitch(options, ctx, _slot, usage) {
ctx.create(new DevSwitchedNode(usage, ctx.runner, options.cases, options.default));
}
export function DevFor({ of: model, slot: _slot }, ctx, defaultSlot, usage) {
const slot = _slot ?? defaultSlot;
if (!slot) {
return;
}
if (model instanceof DevArrayModel) {
ctx.create(new DevArrayView({
model,
slot: slot,
}, ctx.runner, usage));
}
else if (model instanceof DevMapModel) {
ctx.create(new DevMapView({
model,
slot,
}, ctx.runner, usage));
}
else if (model instanceof DevSetModel) {
ctx.create(new DevSetView({
model,
slot: slot,
}, ctx.runner, usage));
}
// fallback if is used external Array/Map/Set
else {
const safeSlot = safe(slot);
console.warn("Vasille <For of/> fallback detected. Please provide reactive data.");
if (model instanceof Array) {
model.forEach((value) => {
safeSlot(ctx, value, value);
});
}
else if (model instanceof Map) {
model.forEach((value, key) => {
safeSlot(ctx, value, key);
});
}
else if (model instanceof Set) {
model.forEach(value => {
safeSlot(ctx, value, value);
});
}
else {
throw userError("wrong use of `<For of/>` component", "wrong-model");
}
}
}
export function DevWatch({ $model, slot: _slot }, ctx, defaultSlot, usage) {
const slot = _slot ?? defaultSlot;
/* istanbul ignore else */
if (slot) {
ctx.create(new DevCoreWatch({ model: $model, slot: safe(slot) }, ctx.runner, usage));
}
}
export function DevDelay({ time, slot: _slot }, ctx, defaultSlot, usage) {
const fragment = new DevFragment(ctx.runner, null, usage, "Delay", {
time,
slot: _slot,
});
const slot = _slot ?? defaultSlot;
let timer;
ctx.create(fragment, function (node) {
/* istanbul ignore else */
if (slot) {
timer = setTimeout(() => {
safe(slot)(node);
timer = undefined;
}, time);
}
node.runOnDestroy(() => {
if (timer !== undefined) {
clearTimeout(timer);
}
});
});
}