New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

battuta

Package Overview
Dependencies
Maintainers
0
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

battuta - npm Package Compare versions

Comparing version

to
0.0.15-modeless10

dist/macros.css.macro.d.ts

21

dist/cli.js

@@ -5,7 +5,8 @@ #!/usr/bin/env node

import c from "path";
import { compile as y, inferModes as S, transformJSX as v } from "./compiler.js";
import { optimize as w, optimizeStrings as x, optimizeFunctions as C } from "./optimizer.js";
import { createServer as h, build as j } from "vite";
import { compile as y } from "./compiler.js";
import { optimize as S, optimizeStrings as v, optimizeFunctions as w } from "./optimizer.js";
import { createServer as x, build as C } from "vite";
import p from "./vite.js";
import { execSync as m } from "child_process";
import { i as h, t as j } from "./modes-kS_CsyZ5.js";
const o = {

@@ -56,15 +57,15 @@ pattern: (t) => `${t} <file>`,

e.command("dev").action(async () => {
const t = await h({ plugins: [p()] });
const t = await x({ plugins: [p()] });
await t.listen(), t.printUrls(), t.bindCLIShortcuts({ print: !0 });
});
e.command("bundle").option("-m, --minify <boolean>", "Minify the chunks", !0).action(async (t) => {
await j({ plugins: [p()], build: { minify: t.minify } });
await C({ plugins: [p()], build: { minify: t.minify } });
});
e.command(o.pattern("compile")).action(o.wrap((t, n) => y(t, n)));
e.command(o.pattern("compile:modes")).action(o.wrap((t, n) => S(t, n)));
e.command(o.pattern("compile:jsx")).action(o.wrap((t) => v(t).code));
e.command(o.pattern("optimize")).action(o.wrap((t) => w(t).code));
e.command(o.pattern("optimize:strings")).action(o.wrap((t) => x(t).code));
e.command(o.pattern("optimize:functions")).action(o.wrap((t) => C(t).code));
e.command(o.pattern("compile:modes")).action(o.wrap((t, n) => h(t, n)));
e.command(o.pattern("compile:jsx")).action(o.wrap((t) => j(t).code));
e.command(o.pattern("optimize")).action(o.wrap((t) => S(t).code));
e.command(o.pattern("optimize:strings")).action(o.wrap((t) => v(t).code));
e.command(o.pattern("optimize:functions")).action(o.wrap((t) => w(t).code));
e.name("battuta").description("CLI tool for battuta").version("0.0.0");
e.parse(process.argv);

@@ -1,432 +0,9 @@

import O from "@babel/parser";
import j from "@babel/generator";
import G from "@babel/traverse";
import * as t from "@babel/types";
import { Project as K, SyntaxKind as F } from "ts-morph";
import T from "crypto";
const I = {
filter: !0,
defs: !0,
altGlyph: !0,
altGlyphDef: !0,
altGlyphItem: !0,
animate: !0,
animateColor: !0,
animateMotion: !0,
animateTransform: !0,
animation: !0,
circle: !0,
clipPath: !0,
"color-profile": !0,
cursor: !0,
desc: !0,
discard: !0,
ellipse: !0,
feBlend: !0,
feColorMatrix: !0,
feComponentTransfer: !0,
feComposite: !0,
feConvolveMatrix: !0,
feDiffuseLighting: !0,
feDisplacementMap: !0,
feDistantLight: !0,
feDropShadow: !0,
feFlood: !0,
feFuncA: !0,
feFuncB: !0,
feFuncG: !0,
feFuncR: !0,
feGaussianBlur: !0,
feImage: !0,
feMerge: !0,
feMergeNode: !0,
feMorphology: !0,
feOffset: !0,
fePointLight: !0,
feSpecularLighting: !0,
feSpotLight: !0,
feTile: !0,
feTurbulence: !0,
font: !0,
"font-face": !0,
"font-face-format": !0,
"font-face-name": !0,
"font-face-src": !0,
"font-face-uri": !0,
foreignObject: !0,
g: !0,
glyph: !0,
glyphRef: !0,
handler: !0,
hkern: !0,
image: !0,
line: !0,
linearGradient: !0,
listener: !0,
marker: !0,
mask: !0,
metadata: !0,
"missing-glyph": !0,
mpath: !0,
path: !0,
pattern: !0,
polygon: !0,
polyline: !0,
prefetch: !0,
radialGradient: !0,
rect: !0,
set: !0,
solidColor: !0,
stop: !0,
switch: !0,
symbol: !0,
tbreak: !0,
text: !0,
textArea: !0,
textPath: !0,
tref: !0,
tspan: !0,
unknown: !0,
use: !0,
view: !0,
vkern: !0
}, M = {
...I,
a: !0,
abbr: !0,
address: !0,
area: !0,
article: !0,
aside: !0,
audio: !0,
b: !0,
base: !0,
bdi: !0,
bdo: !0,
blockquote: !0,
body: !0,
br: !0,
button: !0,
canvas: !0,
caption: !0,
cite: !0,
code: !0,
col: !0,
colgroup: !0,
data: !0,
datalist: !0,
dd: !0,
del: !0,
details: !0,
dfn: !0,
dialog: !0,
div: !0,
dl: !0,
dt: !0,
em: !0,
embed: !0,
fieldset: !0,
figcaption: !0,
figure: !0,
footer: !0,
form: !0,
h1: !0,
h2: !0,
h3: !0,
h4: !0,
h5: !0,
h6: !0,
head: !0,
header: !0,
hgroup: !0,
hr: !0,
html: !0,
i: !0,
iframe: !0,
img: !0,
input: !0,
ins: !0,
kbd: !0,
label: !0,
legend: !0,
li: !0,
link: !0,
main: !0,
map: !0,
mark: !0,
math: !0,
menu: !0,
menuitem: !0,
meta: !0,
meter: !0,
nav: !0,
noscript: !0,
object: !0,
ol: !0,
optgroup: !0,
option: !0,
output: !0,
p: !0,
param: !0,
picture: !0,
pre: !0,
progress: !0,
q: !0,
rb: !0,
rp: !0,
rt: !0,
rtc: !0,
ruby: !0,
s: !0,
samp: !0,
script: !0,
search: !0,
section: !0,
select: !0,
slot: !0,
small: !0,
source: !0,
span: !0,
strong: !0,
style: !0,
sub: !0,
summary: !0,
sup: !0,
svg: !0,
table: !0,
tbody: !0,
td: !0,
template: !0,
textarea: !0,
tfoot: !0,
th: !0,
thead: !0,
time: !0,
title: !0,
tr: !0,
track: !0,
u: !0,
ul: !0,
var: !0,
video: !0,
wbr: !0
}, v = G.default, _ = j.default;
function H(e) {
const r = O.parse(e, {
sourceType: "module",
plugins: ["jsx", "typescript", "decorators"]
});
return v(r, {
JSXElement: (a) => {
a.replaceWith(S(a.node) || t.nullLiteral());
},
JSXFragment: (a) => {
a.replaceWith(S(a.node) || t.nullLiteral());
}
}), g(r, "createElement", "battuta/dom"), g(r, "createSVGElement", "battuta/dom"), g(r, "create", "battuta/runtime"), g(r, "assign", "battuta/runtime"), g(r, "set", "battuta/runtime"), g(r, "call", "battuta/runtime"), g(r, "append", "battuta/runtime"), _(r, {}, e);
import { i, t as n } from "./modes-kS_CsyZ5.js";
function m(r, t) {
return r = i(r, t), r = n(r).code, r;
}
function S(e) {
var h, b, $, C;
let r = "$d";
const a = () => e.children.map((f) => R(f, r)).filter(Boolean);
if (e.type == "JSXFragment") return t.arrayExpression(a());
const i = e.openingElement;
let u = "";
switch (i.name.type) {
case "JSXIdentifier":
u = i.name.name;
break;
case "JSXNamespacedName":
u = i.name.name.name;
break;
case "JSXMemberExpression":
u = i.name.object.name + "." + i.name.property.name;
break;
}
const s = (b = (h = i.attributes.find((f) => f.type === "JSXAttribute" && f.name.type == "JSXIdentifier" && W[f.name.name])) == null ? void 0 : h.name) == null ? void 0 : b.name;
s && (r = s);
const o = a(), c = M[u], x = I[u], m = i.attributes.map((f) => V(f)).filter(Boolean);
if (c)
return P(o, A(m, t.callExpression(t.identifier(p(x ? "createSVGElement" : "createElement")), [t.stringLiteral(u)])));
if (r === "$c") {
const w = (($ = m.find(({
key: n
}) => n[0].type == "StringLiteral" && n[0].value == "$c")) == null ? void 0 : $.value).elements.map((n) => n.elements.map((l) => l.value)), L = m.reduce((n, l) => (l.key.length > 1 || (n[l.key[0].value] = l.value), n), {}), J = w.map((n) => n.map((l) => L[l])), d = J.sort((n, l) => l.filter(Boolean).length - n.filter(Boolean).length)[0], X = d.findLastIndex(Boolean), k = d.slice(0, X + 1), N = w[J.indexOf(d)];
return P(o, A(m.filter((n) => n.key.length > 1 || !N.includes(n.key[0].value)), t.callExpression(t.memberExpression(t.identifier(u), t.identifier(p("create")), !0), k.map((n) => n || t.identifier("undefined")))));
}
if (r === "$f") {
const w = ((C = m.find(({
key: n
}) => n[0].type == "StringLiteral" && n[0].value == "$f")) == null ? void 0 : C.value).elements.map((n) => n.elements.map((l) => l.value)), L = m.reduce((n, l) => (l.key.length > 1 || (n[l.key[0].value] = l.value), n), {}), J = w.map((n) => n.map((l) => L[l])), d = J.sort((n, l) => l.filter(Boolean).length - n.filter(Boolean).length)[0], X = d.findLastIndex(Boolean), k = d.slice(0, X + 1), N = w[J.indexOf(d)];
return A(m.filter((n) => n.key.length > 1 || !N.includes(n.key[0].value)), t.callExpression(t.identifier(u), k.map((n) => n || t.identifier("undefined"))));
}
return t.callExpression(t.identifier(u), [t.objectExpression([...m.map(({
key: f,
value: E
}) => ["StringLiteral", "BooleanLiteral"].includes(E.type) ? t.objectProperty(t.stringLiteral(B(...f)), E) : t.objectMethod("get", t.identifier(B(...f)), [], t.blockStatement([t.returnStatement(E)]))), t.objectProperty(t.stringLiteral("children"), t.arrowFunctionExpression([t.identifier("_")], t.arrayExpression(o)))])]);
}
function A(e, r) {
return e.reduce((a, {
key: i,
value: u
}) => {
switch (!0) {
case (i[0].type == "StringLiteral" && ["$", "$c", "$d", "$f", "$n"].includes(i[0].value)):
return a;
case ["StringLiteral", "BooleanLiteral"].includes(u.type):
return t.callExpression(t.memberExpression(a, t.identifier(p("set")), !0), [u, ...i]);
case (u.type == "CallExpression" && u.callee.type == "Identifier" && u.callee.name == "$call"):
return t.callExpression(t.memberExpression(a, t.identifier(p("call")), !0), [t.arrowFunctionExpression([t.identifier("_")], t.arrayExpression(u.arguments)), ...i]);
default:
return t.callExpression(t.memberExpression(a, t.identifier(p("assign")), !0), [t.arrowFunctionExpression([t.identifier("_")], u), ...i]);
}
}, r);
}
function P(e, r) {
return !e || e.length == 0 ? r : t.callExpression(t.memberExpression(r, t.identifier(p("append")), !0), e);
}
function R(e, r) {
var a, i;
switch (e.type) {
case "JSXElement":
return S(e);
case "JSXText": {
const u = (i = (a = e.value) == null ? void 0 : a.trim) == null ? void 0 : i.call(a);
return u ? t.stringLiteral(u) : void 0;
}
case "JSXExpressionContainer":
switch (e.expression.type) {
case "JSXEmptyExpression":
return;
default:
return ["$f", "$n"].includes(r) ? e.expression : t.arrowFunctionExpression([t.identifier("_")], e.expression);
}
case "JSXFragment":
return S(e);
case "JSXSpreadChild":
return;
default:
return;
}
}
function V(e, r) {
switch (e.type) {
case "JSXAttribute": {
const a = z(e.value);
return a ? {
key: q(e.name),
value: a
} : void 0;
}
case "JSXSpreadAttribute":
return;
default:
return;
}
}
function q(e) {
switch (e == null ? void 0 : e.type) {
case "JSXIdentifier":
return [t.stringLiteral(e.name)];
case "JSXNamespacedName":
return [t.stringLiteral(e.namespace.name), t.stringLiteral(e.name.name)];
}
}
function z(e, r) {
switch (e == null ? void 0 : e.type) {
case "JSXElement":
return S(e);
case "JSXExpressionContainer":
switch (e.expression.type) {
case "JSXEmptyExpression":
return;
default:
return e.expression;
}
case "StringLiteral":
return e;
case "JSXFragment":
return S(e);
case void 0:
return t.booleanLiteral(!0);
}
}
function B(...e) {
return e.map((r) => r.value).join(":");
}
function g(e, r, a) {
let i = !1;
const u = p(r);
v(e, {
ImportDeclaration(s) {
const {
node: o
} = s;
o.specifiers.some((c) => t.isImportSpecifier(c) && c.local.name === u && c.imported.name === r) && (i = !0);
}
}), i || e.program.body.unshift(t.importDeclaration([t.importSpecifier(t.identifier(u), t.identifier(r))], t.stringLiteral(a)));
}
function p(e) {
return `$btt_${e}`;
}
const W = {
$d: !0,
$c: !0,
$f: !0
}, D = new K({}), y = {};
function Q(e, r) {
if (y[r]) {
const s = y[r].hash;
if (T.createHash("md5").update(e).digest("hex") != s)
D.removeSourceFile(y[r].file), delete y[r];
else
return y[r].result;
}
const a = D.addSourceFileAtPath(r), i = [];
a.getDescendantsOfKind(F.JsxElement).forEach((s) => i.push(s.getOpeningElement())), a.getDescendantsOfKind(F.JsxSelfClosingElement).forEach((s) => i.push(s)), i.forEach((s) => {
const o = U(s);
o && s.insertAttribute(0, o);
});
const u = a.print();
return y[r] = {
hash: T.createHash("md5").update(e).digest("hex"),
file: a,
result: u
}, u;
}
function U(e) {
const r = e.getTagNameNode();
if (M[r.getText()] || e.getAttribute("$f") || e.getAttribute("$d") || e.getAttribute("$c")) return;
const a = r.getType(), i = a.getConstructSignatures();
if (i.length > 0) {
const s = i.map(
(o) => o.getParameters().map(
(c) => c.getName()
)
);
return { name: "$c", initializer: `{${JSON.stringify(s)}}` };
}
const u = a.getCallSignatures();
if (u.length > 0) {
const s = `{${JSON.stringify(u.map(
(o) => o.getParameters().map(
(c) => c.getName()
)
))}}`;
if (u.some((o) => o.getParameters().length > 1)) return { name: "$f", initializer: s };
if (u.some((o) => o.getParameters().some((c) => !c.getDeclaredType().isObject() && !c.getDeclaredType().isAny()))) return { name: "$f", initializer: s };
if (u.some((o) => o.getParameters().some((c) => {
const x = c.getDeclaredType(), m = x.getSymbol(), h = m == null ? void 0 : m.getDeclarations(), b = h == null ? void 0 : h.filter(($) => $.getKindName() === "ClassDeclaration");
return x.isArray() || x.isClass() || !!(b != null && b.length);
}))) return { name: "$f", initializer: s };
}
return { name: "$d" };
}
function ne(e, r) {
return e = Q(e, r), e = H(e).code, e;
}
export {
ne as compile,
Q as inferModes,
H as transformJSX
m as compile,
i as inferModes,
n as transformJSX
};
import { MacroContext } from 'unplugin-macros';
export declare function css(this: any, css: TemplateStringsArray, ..._args: any[]): Record<string, string>;
export { MacroContext }

@@ -6,0 +4,0 @@

@@ -1,36 +0,1 @@

import c from "fs";
import u from "path";
import p from "postcss";
const l = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 };
function h(a, ...g) {
const m = this, t = {}, o = p.parse(a);
o.walkRules((e) => {
e.selectors = e.selectors.map((r) => r.replace(/\.[\w-]+/g, (n) => {
const s = n.slice(1);
return t[s] ?? (t[s] = d()), "." + t[s];
}));
});
const i = o.toString();
if (l) {
const e = ".temp", r = `${f()}.css`, n = u.join(process.cwd(), e, r);
return c.mkdirSync(u.dirname(n), { recursive: !0 }), c.writeFileSync(n, i, "utf8"), m.magicString.prepend(`import '/${e}/${r}';
`), new String(`(${JSON.stringify(t)})`);
} else
return new String(`
(() => {
const style = document.createElement("style");
style.innerHTML = ${JSON.stringify(i)};
document.head.appendChild(style);
return ${JSON.stringify(t)};
})();
`);
}
function d() {
return "cls-" + Math.random().toString(36).substr(2, 8);
}
function f() {
return "style-" + Math.random().toString(36).substr(2, 8);
}
export {
h as css
};

@@ -12,6 +12,6 @@ import { parse as S } from "@babel/parser";

function u(e) {
var g, P, b, k;
const i = (g = e.parentPath) == null ? void 0 : g.node;
if (!n.isFunction(i)) return;
const r = e.scope, t = [];
var h, P, b, k;
const r = (h = e.parentPath) == null ? void 0 : h.node;
if (!n.isFunction(r)) return;
const i = e.scope, t = [];
e.parentPath.traverse({

@@ -30,3 +30,3 @@ ReferencedIdentifier(s) {

}
}), t.every((s) => y.hasOwnBinding(s) || r.hasOwnBinding(s));
}), t.every((s) => y.hasOwnBinding(s) || i.hasOwnBinding(s));
let d = e.parentPath;

@@ -36,6 +36,6 @@ function v() {

if (w != s)
return !(!s || t.some((l) => {
return !(!s || t.some((m) => {
var B;
return ((B = w == null ? void 0 : w.scope) == null ? void 0 : B.hasOwnBinding(l)) && !r.hasOwnBinding(l);
}) || !t.every((l) => s.scope.hasBinding(l) || r.hasOwnBinding(l) || I[l]));
return ((B = w == null ? void 0 : w.scope) == null ? void 0 : B.hasOwnBinding(m)) && !i.hasOwnBinding(m);
}) || !t.every((m) => s.scope.hasBinding(m) || i.hasOwnBinding(m) || I[m]));
}

@@ -51,13 +51,13 @@ for (; v(); )

}
function m({
function l({
blockPath: e,
path: i
path: r
}) {
var d, v, f, p, g, P, b, k, s;
const r = F(), t = (d = i.parentPath) == null ? void 0 : d.node;
var d, v, f, p, h, P, b, k, s;
const i = F(), t = (d = r.parentPath) == null ? void 0 : d.node;
switch (t.type) {
case "ArrowFunctionExpression": {
(v = i.parentPath) == null || v.replaceWith(n.identifier(r)), e.unshiftContainer("body", n.variableDeclaration("const", [
(v = r.parentPath) == null || v.replaceWith(n.identifier(i)), e.unshiftContainer("body", n.variableDeclaration("const", [
n.variableDeclarator(
n.identifier(r),
n.identifier(i),
t

@@ -70,5 +70,5 @@ )

if (t.key.type == "Identifier" && t.key.name == "constructor") return;
(f = i.parentPath) == null || f.replaceWith(n.classProperty(
(f = r.parentPath) == null || f.replaceWith(n.classProperty(
t.key,
n.identifier(r),
n.identifier(i),
void 0,

@@ -79,3 +79,3 @@ t.decorators,

)), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(r),
n.identifier(i),
t.params,

@@ -90,9 +90,9 @@ t.body,

if (t.key.id.name == "constructor") return;
(p = i.parentPath) == null || p.replaceWith(n.classPrivateProperty(
(p = r.parentPath) == null || p.replaceWith(n.classPrivateProperty(
t.key,
n.identifier(r),
n.identifier(i),
t.decorators,
t.static
)), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(r),
n.identifier(i),
t.params,

@@ -106,4 +106,4 @@ t.body,

case "FunctionDeclaration": {
(g = i.parentPath) == null || g.replaceWith(n.identifier(r)), (P = t.id) != null && P.name && i.parentPath.scope.rename((b = t.id) == null ? void 0 : b.name, r), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(r),
(h = r.parentPath) == null || h.replaceWith(n.identifier(i)), (P = t.id) != null && P.name && r.parentPath.scope.rename((b = t.id) == null ? void 0 : b.name, i), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(i),
t.params,

@@ -117,4 +117,4 @@ t.body,

case "FunctionExpression": {
(k = i.parentPath) == null || k.replaceWith(n.identifier(r)), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(r),
(k = r.parentPath) == null || k.replaceWith(n.identifier(i)), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(i),
t.params,

@@ -128,5 +128,5 @@ t.body,

case "ObjectMethod": {
(s = i.parentPath) == null || s.replaceWith(n.objectProperty(
(s = r.parentPath) == null || s.replaceWith(n.objectProperty(
t.key,
n.identifier(r),
n.identifier(i),
t.computed,

@@ -136,3 +136,3 @@ void 0,

)), e.unshiftContainer("body", n.functionDeclaration(
n.identifier(r),
n.identifier(i),
t.params,

@@ -154,10 +154,10 @@ t.body,

Function(e) {
const i = e.node;
i.type == "ObjectMethod" && ["get", "set"].includes(i.kind) || u(e.get("body"));
const r = e.node;
r.type == "ObjectMethod" && ["get", "set"].includes(r.kind) || u(e.get("body"));
}
}), o.forEach(m);
const h = W(a, {}, c);
}), o.forEach(l);
const g = W(a, {}, c);
return {
code: h.code,
map: h.map
code: g.code,
map: g.map
};

@@ -182,3 +182,4 @@ }

}), o = {}, u = (e) => {
e in o ? o[e].count++ : o[e] = { count: 1, name: A(e) };
var r;
(r = o[e]) != null && r.count ? o[e].count++ : o[e] = { count: 1, name: A(e) };
};

@@ -190,12 +191,13 @@ D(a, {

ObjectProperty(e) {
const i = e.node.key;
i.type === "Identifier" && u(i.name);
if (e.node.computed) return;
const r = e.node.key;
r.type === "Identifier" && u(r.name);
}
});
const m = [];
for (const [e, { count: i, name: r }] of Object.entries(o))
i > 1 && m.push(
const l = [];
for (const [e, { count: r, name: i }] of Object.entries(o))
r > 1 && l.push(
n.variableDeclaration("const", [
n.variableDeclarator(
n.identifier(r),
n.identifier(i),
n.stringLiteral(e)

@@ -205,18 +207,19 @@ )

);
const y = (e, i, r) => {
e in o && o[e].count > 1 && i.replaceWith(r(o[e].name, i));
const y = (e, r, i) => {
e in o && o[e].count > 1 && r.replaceWith(i(o[e].name, r));
};
m.length > 0 && (D(a, {
l.length > 0 && (D(a, {
StringLiteral(e) {
y(e.node.value, e, (i, r) => (r.parent.type == "ObjectProperty" && r.parent.key == r.node && (r.parent.computed = !0), n.identifier(i)));
y(e.node.value, e, (r, i) => (i.parent.type == "ObjectProperty" && i.parent.key == i.node && (i.parent.computed = !0), n.identifier(r)));
},
ObjectProperty(e) {
const i = e.node.key;
i.type === "Identifier" && y(i.name, e, (r) => n.objectProperty(n.identifier(r), e.node.value, !0));
if (e.node.computed) return;
const r = e.node.key;
r.type === "Identifier" && y(r.name, e, (i) => n.objectProperty(n.identifier(i), e.node.value, !0));
}
}), a.program.body.unshift(...m));
const h = L(a, {}, c);
}), a.program.body.unshift(...l));
const g = L(a, {}, c);
return {
code: h.code,
map: h.map
code: g.code,
map: g.map
};

@@ -223,0 +226,0 @@ }

@@ -1,39 +0,41 @@

import { currentContext as x, contextStack as j } from "./contexts.js";
import { useEffect as y } from "./signals.js";
const b = Symbol("insert"), w = Symbol("append"), A = Symbol("assign"), I = Symbol("set"), R = Symbol("create"), S = Symbol("listeners"), d = Symbol("on"), O = Symbol("childrenIndex"), C = Symbol("remove"), r = Symbol("context"), E = Symbol("call"), T = Symbol("empty"), g = Symbol("parent"), f = Symbol("cleanup"), c = Object.prototype;
c[O] = function() {
import { currentContext as x, contextStack as w } from "./contexts.js";
import { useEffect as v } from "./signals.js";
const b = Symbol("insert"), O = Symbol("append"), I = Symbol("assign"), R = Symbol("set"), E = Symbol("create"), a = Symbol("listeners"), y = Symbol("on"), S = Symbol("childrenIndex"), A = Symbol("remove"), r = Symbol("context"), g = Symbol("call"), P = Symbol("empty"), q = Symbol("parent"), p = Symbol("cleanup"), e = Object.prototype;
e[S] = function() {
return -1;
};
c[b] = function() {
e[b] = function() {
return this;
};
c[R] = function(...t) {
e[P] = function() {
};
e[E] = function(...t) {
return Reflect.construct(this, t);
};
c[w] = function(...t) {
return p(this, t, this), this;
e[O] = function(...t) {
return m(this, t, this), this;
};
c[f] = function(t) {
const o = this[S], n = o.cleanup, s = !!this[C];
if (n) for (const l of n) l(s);
delete o.cleanup, !t && s && this[C]();
e[p] = function(t) {
const o = this[a], n = o.cleanup, c = !!this[A];
if (n) for (const i of n) i(c);
delete o.cleanup, !t && c && this[A]();
};
c[d] = function(t, o) {
const n = this[S];
e[y] = function(t, o) {
const n = this[a];
return n[t] ?? (n[t] = []), n[t].push(o), this;
};
c[I] = function(t, ...o) {
e[R] = function(t, ...o) {
const n = o.pop();
return a(this, o)[n] = t, this;
return j(this, o)[n] = t, this;
};
c[A] = function(t, ...o) {
const n = o.pop(), s = a(this, o);
return y(() => s[n] = t()), this;
e[I] = function(t, ...o) {
const n = o.pop(), c = j(this, o);
return v(() => c[n] = t()), this;
};
c[E] = function(t, ...o) {
const n = o.pop(), s = a(this, o), l = s[n].bind(s);
return y(() => l(...t())), this;
e[g] = function(t, ...o) {
const n = o.pop(), c = j(this, o), i = c[n].bind(c);
return v(() => i(...t())), this;
};
const h = Symbol("l");
Object.defineProperty(c, S, {
Object.defineProperty(e, a, {
get() {

@@ -43,51 +45,54 @@ return this[h] ?? (this[h] = {}), this[h];

});
function p(t, o, n, s = { v: -1 }) {
let l = null;
for (let m = 0; m < o.length; m++) {
const u = o[m];
function m(t, o, n, c = { v: -1 }) {
let i;
for (let d = 0; d < o.length; d++) {
const u = o[d];
if (typeof u == "function") {
let e = s;
y(() => {
const i = new Object();
n[d]("cleanup", () => i[f]()), n[r] ?? (n[r] = x()), i[r] = {
let l = c;
v(() => {
const s = new Object();
n[y]("cleanup", () => s[p]()), n[r] ?? (n[r] = x()), s[r] = {
...n[r],
[b]: (...P) => p(t, P, i, e),
[g]: i
}, j.push(i[r]);
const v = p(t, [u()], i, e);
return j.pop(), l ?? (l = v), () => {
e = { v: t[O](v) }, i[f]();
[b]: (...T) => f = m(t, T, s, { v: t[S](f) + 1 }),
[q]: s
}, w.push(s[r]);
let f;
const C = f = m(t, [u()], s, l);
return w.pop(), i ?? (i = C), () => {
l = { v: t[S](C) }, s[p]();
};
});
} else if (Array.isArray(u)) {
const e = p(t, u, n, s);
l ?? (l = e);
const l = m(t, u, n, c);
i ?? (i = l);
} else {
const e = t[b](u ?? t[T](), s.v);
s.v > -1 && s.v++, e[r] = n[r], n[d]("cleanup", (i) => e[f](i)), l ?? (l = e);
const l = u ?? t[P]();
if (l == null) continue;
const s = t[b](l, c.v);
c.v > -1 && c.v++, s[r] = n[r], n[y]("cleanup", (f) => s[p](f)), i ?? (i = s);
}
}
return l;
return i;
}
function a(t, o) {
function j(t, o) {
for (; o.length; ) t = t[o.shift()];
return t;
}
const B = (t, o) => o[w](t);
const D = (t, o) => o[O](t);
export {
w as append,
A as assign,
E as call,
O as childrenIndex,
f as cleanup,
O as append,
I as assign,
g as call,
S as childrenIndex,
p as cleanup,
r as context,
R as create,
T as empty,
E as create,
P as empty,
b as insert,
S as listeners,
d as on,
g as parent,
C as remove,
B as render,
I as set
a as listeners,
y as on,
q as parent,
A as remove,
D as render,
R as set
};

@@ -1,7 +0,15 @@

export declare function createSignal<T>(defaultValue: T): readonly [() => T, (_value: T) => void];
export declare function coalesce(f: Function, depth?: number): any;
export declare function createSignal<T>(defaultValue: T): GetSet<T>;
export declare type GetSet<T> = Parameters<(get: () => T, set: (v: T) => void) => void>;
export declare function notify(f: Function & {
[prev]: Function;
}): void;
declare const prev: unique symbol;
export declare function untrack<T>(f: (...args: any) => T): T;
export declare function useDebounced(callback: Function, debounceTime?: number): void;
export declare function useEffect(callback: Function): void;

@@ -8,0 +16,0 @@

@@ -1,33 +0,38 @@

const o = [];
let c = !1;
const u = Symbol("prev");
function a(e) {
const t = /* @__PURE__ */ new Set();
let s = e;
const n = [], o = [], i = Symbol("untracked"), r = Symbol("prev");
function d(t) {
const e = /* @__PURE__ */ new Set();
let c = t;
return [() => {
const n = o[o.length - 1];
return n && !c && t.add(n), s;
}, (n) => {
s = n, t.forEach((r) => (typeof r[u] == "function" && r[u](), r[u] = r()));
const s = n[n.length - 1];
return s && !s[i] && e.add(s), c;
}, (s) => {
c = s;
const u = o[o.length - 1];
if (u) return e.forEach((a) => u.add(a));
f(() => e.forEach(p));
}];
}
function i(e) {
o.push(e), e[u] = e(), o.pop();
function h(t) {
n.push(t), t[r] = t(), n.pop();
}
function p(e, t = 250) {
let s = !0, f;
i(() => {
s ? (s = !1, e()) : (clearTimeout(f), setTimeout(e, t));
});
function f(t, e = 1 / 0) {
if (e == 0) return t();
o.push(/* @__PURE__ */ new Set()), t();
const c = o.pop();
c.size != 0 && f(() => c.forEach(p), e - 1);
}
function b(e) {
c = !0;
const t = e();
return c = !1, t;
function p(t) {
typeof t[r] == "function" && t[r](), h(t);
}
function g(t) {
t[i] = !0, n.push(t);
const e = t();
return n.pop(), e;
}
export {
a as createSignal,
b as untrack,
p as useDebounced,
i as useEffect
f as coalesce,
d as createSignal,
p as notify,
g as untrack,
h as useEffect
};

@@ -5,11 +5,13 @@ import { default as battutaMacros } from 'unplugin-macros/vite';

export declare function battutaCompiler(config?: Config["compiler"]): Plugin_2;
export declare function battutaConfig(): Plugin_2;
export declare function battutaFolders(config?: any): Plugin_2;
export declare function battutaFolders(config?: FoldersConfig): Plugin_2;
export declare function battutaInferModes(config?: ModesConfig): Plugin_2;
export declare function battutaJSX(config?: JSXConfig): Plugin_2;
export { battutaMacros }
export declare function battutaOptimizer(config?: Config["optimizer"]): Plugin_2;
export declare function battutaOptimizer(config?: OptimizerConfig): Plugin_2;

@@ -19,18 +21,31 @@ declare function battutaPlugin(config?: Config): Plugin_2[];

export declare function battutaVirtualRoot(root?: string): Plugin_2;
export declare function battutaVirtualRoot(opts?: RootConfig): Plugin_2;
declare type Config = {
macros?: Options;
compiler?: {};
folders?: {
temp: string;
move: string;
};
optimizer?: {
strings?: boolean;
functions?: boolean;
};
root?: string;
modes?: ModesConfig;
jsx?: JSXConfig;
optimizer?: OptimizerConfig;
root?: RootConfig;
folders?: FoldersConfig;
};
declare type FoldersConfig = {
temp: string;
move: string;
};
declare type JSXConfig = {};
declare type ModesConfig = {};
declare type OptimizerConfig = {
strings?: boolean;
functions?: boolean;
};
declare type RootConfig = {
pages: Record<string, string>;
};
export { }

@@ -37,0 +52,0 @@

@@ -1,40 +0,42 @@

import { compile as h } from "./compiler.js";
import b from "unplugin-macros/vite";
import { default as I } from "unplugin-macros/vite";
import { existsSync as u, mkdirSync as s, rmdirSync as d, readdirSync as v, lstatSync as x, renameSync as y, readFileSync as m } from "fs";
import o, { resolve as p, join as c } from "path";
import { optimize as f } from "./optimizer.js";
function F(t) {
import { i as S, t as $ } from "./modes-kS_CsyZ5.js";
import F from "unplugin-macros/vite";
import { default as A } from "unplugin-macros/vite";
import { existsSync as i, mkdirSync as h, rmdirSync as v, readdirSync as M, lstatSync as D, renameSync as P, readFileSync as p } from "fs";
import m, { resolve as f, join as y } from "path";
import { optimize as z } from "./optimizer.js";
function C(t) {
return {
name: "battuta-build-folders",
generateBundle(r, e) {
S(r.dir, (t == null ? void 0 : t.temp) ?? ".temp"), C(r.dir, (t == null ? void 0 : t.move) ?? ".move");
E(r.dir, (t == null ? void 0 : t.temp) ?? ".temp"), O(r.dir, (t == null ? void 0 : t.move) ?? ".move");
}
};
}
function S(t, r) {
const e = p(r), a = c(t);
u(a) || s(a, { recursive: !0 }), u(e) && d(e, { recursive: !0, force: !0 });
function E(t, r) {
const e = f(r), n = y(t);
i(n) || h(n, { recursive: !0 }), i(e) && v(e, { recursive: !0, force: !0 });
}
function C(t, r) {
const e = p(r), a = c(t);
u(a) || s(a, { recursive: !0 }), u(e) && (v(e).forEach((i) => {
const n = o.join(e, i), l = o.join(a, i);
x(n).isFile() && y(n, l);
}), d(e, { recursive: !0, force: !0 }));
function O(t, r) {
const e = f(r), n = y(t);
i(n) || h(n, { recursive: !0 }), i(e) && (M(e).forEach((a) => {
const u = m.join(e, a), s = m.join(n, a);
D(u).isFile() && P(u, s);
}), v(e, { recursive: !0, force: !0 }));
}
function D(t) {
const r = P(t ?? "/src/main.tsx");
function T(t) {
const r = (t == null ? void 0 : t.pages) || { index: "/src/main.tsx" }, e = b(r, (a, u) => [`${a}.html`, u]), n = b(e, (a, u) => [a, w(u)]);
return {
name: "battuta-virtual-root",
enforce: "pre",
load: (e) => e !== "index.html" ? void 0 : u("./index.html") ? m("./index.html", "utf-8") : r,
resolveId: (e, a, i) => {
if (i.isEntry) return "index.html";
load: (a) => n[a] ? i(`./${a}`) ? p(`./${a}`, "utf-8") : n[a] : void 0,
resolveId: (a, u, s) => {
if (s.isEntry) return m.relative(m.resolve("./"), a);
},
configureServer: (e) => {
e.middlewares.use((a, i, n) => {
if (a.url !== "/") return n();
const l = u("./index.html") ? m("./index.html", "utf-8") : r;
i.setHeader("Content-Type", "text/html"), i.statusCode = 200, i.end(l);
configureServer: (a) => {
a.middlewares.use((u, s, x) => {
var d, c;
const o = (c = (d = u.url) == null ? void 0 : d.slice(1)) == null ? void 0 : c.replace(".html", ""), l = o ? `${o}.html` : "index.html";
if (!n[l]) return x();
const j = i(`./${l}`) ? p(`./${l}`, "utf-8") : k(n[l]);
s.setHeader("Content-Type", "text/html"), s.statusCode = 200, s.end(j);
});

@@ -44,3 +46,3 @@ },

optimizeDeps: {
entries: ["index.html"]
entries: Object.keys(e)
}

@@ -50,3 +52,9 @@ })

}
const P = (t) => `
function b(t, r) {
return Object.fromEntries(Object.entries(t).map(([e, n]) => r(e, n)));
}
function k(t) {
return t.replace("<head>", '<head><script type="module" src="/@vite/client"><\/script>');
}
const w = (t) => `
<!DOCTYPE html>

@@ -69,7 +77,7 @@ <html lang="en">

`;
function z() {
function B() {
return {
name: "battuta-config",
config: (t) => {
var r, e, a, i;
var r, e, n, a;
return {

@@ -85,4 +93,4 @@ build: {

server: {
host: ((a = t.server) == null ? void 0 : a.host) ?? "0.0.0.0",
port: ((i = t.server) == null ? void 0 : i.port) ?? 5173
host: ((n = t.server) == null ? void 0 : n.host) ?? "0.0.0.0",
port: ((a = t.server) == null ? void 0 : a.port) ?? 5173
}

@@ -93,35 +101,46 @@ };

}
function T(t) {
function H(t) {
return {
name: "battuta-compiler",
name: "battuta-infer-modes",
enforce: "pre",
transform(r, e) {
return /\.[jt]sx$/.test(e) ? h(r, e) : null;
return /\.[jt]sx$/.test(e) ? S(r, e) : null;
}
};
}
function j(t) {
function I(t) {
return {
name: "battuta-jsx",
enforce: "pre",
transform(r, e) {
return /\.[jt]sx$/.test(e) ? $(r) : null;
}
};
}
function J(t) {
return {
name: "battuta-optimizer",
renderChunk: (r) => f(r, t)
renderChunk: (r) => z(r, t)
};
}
function H(t) {
function Y(t) {
return [
z(),
D(t == null ? void 0 : t.root),
b(t == null ? void 0 : t.macros),
T(t == null ? void 0 : t.compiler),
F(t == null ? void 0 : t.folders),
j(t == null ? void 0 : t.optimizer)
B(),
T(t == null ? void 0 : t.root),
H(t == null ? void 0 : t.modes),
F(t == null ? void 0 : t.macros),
I(t == null ? void 0 : t.jsx),
C(t == null ? void 0 : t.folders),
J(t == null ? void 0 : t.optimizer)
];
}
export {
T as battutaCompiler,
z as battutaConfig,
F as battutaFolders,
I as battutaMacros,
j as battutaOptimizer,
D as battutaVirtualRoot,
H as default
B as battutaConfig,
C as battutaFolders,
H as battutaInferModes,
I as battutaJSX,
A as battutaMacros,
J as battutaOptimizer,
T as battutaVirtualRoot,
Y as default
};
{
"name": "battuta",
"private": false,
"version": "0.0.15-modeless",
"version": "0.0.15-modeless10",
"type": "module",

@@ -20,11 +20,18 @@ "license": "MIT",

"./runtime": "./dist/runtime.js",
"./three": "./dist/three.js",
"./dom": "./dist/dom.js",
"./signals": "./dist/signals.js",
"./contexts": "./dist/contexts.js",
"./hooks": "./dist/hooks.js",
"./tweak": "./dist/tweak.js",
"./signals/screen": "./dist/signals/screen.js",
"./jsx-runtime": "./dist/jsx-runtime.js",
"./jsx-dev-runtime": "./dist/jsx-dev-runtime.js"
"./jsx-dev-runtime": "./dist/jsx-dev-runtime.js",
"./utils/animate": "./dist/utils.animate.js",
"./utils/dev": "./dist/utils.dev.js",
"./utils/lazy": "./dist/utils.lazy.js",
"./utils/screen": "./dist/utils.screen.js",
"./utils/signals": "./dist/utils.signals.js",
"./utils/structure": "./dist/utils.structure.js",
"./utils/three": "./dist/utils.three.js",
"./utils/tree": "./dist/utils.tree.js",
"./utils/tweak": "./dist/utils.tweak.js",
"./macros/css.macro": "./dist/macros.css.macro.js",
"./macros/glsl.macro": "./dist/macros.glsl.macro.js"
},

@@ -48,5 +55,2 @@ "typesVersions": {

],
"three": [
"dist/three.d.ts"
],
"dom": [

@@ -61,11 +65,2 @@ "dist/dom.d.ts"

],
"hooks": [
"dist/hooks.d.ts"
],
"tweak": [
"dist/tweak.d.ts"
],
"signals/screen": [
"dist/signals/screen.d.ts"
],
"jsx-runtime": [

@@ -76,2 +71,35 @@ "dist/jsx-runtime.d.ts"

"dist/jsx-dev-runtime.d.ts"
],
"utils/animate": [
"dist/utils.animate.d.ts"
],
"utils/dev": [
"dist/utils.dev.d.ts"
],
"utils/lazy": [
"dist/utils.lazy.d.ts"
],
"utils/screen": [
"dist/utils.screen.d.ts"
],
"utils/signals": [
"dist/utils.signals.d.ts"
],
"utils/structure": [
"dist/utils.structure.d.ts"
],
"utils/three": [
"dist/utils.three.d.ts"
],
"utils/tree": [
"dist/utils.tree.d.ts"
],
"utils/tweak": [
"dist/utils.tweak.d.ts"
],
"macros/css.macro": [
"dist/macros.css.macro.d.ts"
],
"macros/glsl.macro": [
"dist/macros.glsl.macro.d.ts"
]

@@ -83,6 +111,6 @@ }

"build:quick": "vite build --mode quick",
"build:quick-types": "vite build --mode quick-types",
"build:nocheck": "vite build"
},
"devDependencies": {
"@tweakpane/core": "^2.0.4",
"@types/babel__generator": "^7.6.8",

@@ -108,5 +136,6 @@ "@types/babel__traverse": "^7.20.6",

"tweakpane": "^4.0.4",
"unplugin-macros": "github:BobochD-Brew/unplugin-macros.git#6b6e4a810e781baf2b5778ad7276b8948713c6a3",
"@tweakpane/core": "^2.0.4",
"unplugin-macros": "github:BobochD-Brew/unplugin-macros.git#0d7dc8bfc26bcc86a0bf8e40929994eaa6ca339e",
"vite": "^5.4.1"
}
}

@@ -16,8 +16,7 @@ # Battuta

- [JSX](#jsx)
- [Default Mode](#default-mode---d)
- [Class Mode](#class-mode---c)
- [Function Mode](#function-mode---f)
- [Mixed Mode](#mixed-mode---n)
- [DOM](#dom)
- [Components](#components)
- [Constructors](#constructors)
- [Functions](#functions)
- [Contexts](#contexts)
- [Hooks](#some-hooks)
- [CLI](#cli)

@@ -36,73 +35,80 @@ - [Vite](#use-with-vite)

the JSX compiler use a mode system that change how jsx expressions are compiled.
to switch between modes you can use `$` utils like this:
JSX expressions are compiled differently based on the type of tag used
### DOM
This expression:
```tsx
// as a separate tag
<$f> {/* Function Mode */}
<Component>
<Child/> {/* affected */}
{() => <Child/>} {/* not affected */}
</Component>
</$f>
// inside a tag
<Component $f>
<Child/> {/* affected */}
{() => <Child/>} {/* not affected */}
</Component>
<div style:color={color()}>
{value()}
</div>
```
Transforms to:
```tsx
createElement("div")
[assign](() => color(), "style", "color")
[append](() => value())
```
> I hate to have to do it this way but it's the best I found yet
### Components
### Default Mode - $d
Given
```tsx
function Component(props) {
return <div>{props.value}</div>
}
```
This expression:
```tsx
<Component value={value()}>
```
Transforms to:
```tsx
Component({ get value() { return value() } })
```
the default mode compile JSX expressions to match the react component apis, as solid it use accesors for props
### Constructors
Given
```tsx
<Component key1={value()} key2="value">
<div/>
<div/>
</Component>
// turns into
const createElement = document.bind(document);
Component({
get key1() { return value() },
key2: "value",
children: () => [ createElement("div"), createElement("div") ]
})
class A {
prop = 0;
constructor(arg_2);
constructor(arg_1, arg_2, arg_3) {}
}
```
Those expressions:
```tsx
<A arg_2={value_2()} prop={value_3()}>
<A arg_2={value_2()} arg_3={value_4()} prop={value_3()}>
```
Transform to:
```tsx
A[create](value_2())
[assign](() => value_3(), "prop")
A[create](undefined, value_2(), value_4())
[assign](() => value_3(), "prop")
```
### Class Mode - $c
> The props names are matched with the args names
the class mode allow to use already existing classes in JSX and compose them
### Functions
Given
```tsx
import { create, appendMultiple, set, assign, call } from "battuta/runtime"
const group = <THREE.Group $c>
<THREE.PointLight
$c={[0xffff00, 2, 100]}
color:set={$call(color())}
position:y={positionY()}
position:x={1}
castShadow
/>
</THREE.Group>
// turns into
const group = THREE.Group[create]() // by default -> new THREE.Group()
[appendMultiple](
THREE.PointLight[create](0xffff00, 2, 100)
[call](() => color(), "color", "set") // calls light.color.set(color()) when color get updated
[assign](() => position(), "position", "y")
[set](1, "position", "x")
[set](true, "castShadow")
)
function F(first: string, second: number) {}
```
Those expressions:
```tsx
<F first={value_1()} second={value_2()}>
<F second={value_2()} prop={value_3()}>
```
Transform to:
```tsx
F(value_1(), value_2())
F(undefined, value_2())
[assign](() => value_3(), "prop")
```
for this to work some methods need to be implmented on the parent prototypes, by default Object instances define default implementations that can be overwriten, at least `empty`, `childrenIndex`, `insert` and `remove` need to be implemented, those last two should never be called directly, instead use the `useAppend` & `useRemove` hooks or the `append` and `cleanup` methods
for this to work some methods need to be implemented on the parent prototypes, by default Object instances define default implementations that can be overwriten, at least `insert` and `remove` need to be implemented

@@ -115,2 +121,3 @@ this is an example in the case of threejs

// required
Object3D.prototype[insert] = function(child: any, index?: number){

@@ -121,60 +128,48 @@ this.add(child);

// required
Object3D.prototype[remove] = function(){
return this.removeFromParent();
this.removeFromParent();
return this;
}
// not needed if the childrens order doesn't matter
Object3D.prototype[childrenIndex] = function(child){
return -1;
return this.children.indexOf(child);
}
// not needed if the childrens order doesn't matter
Object3D.prototype[empty] = function(){
return new Group();
}
```
### Function Mode - $f
// implemented by default, can be overwriten
Object3D.prototype[create] = function (...props) {
return Reflect.construct(this as any, props);
}
the function mode allow to compose functions with each other
// implemented by default, can be overwriten
Object3D.prototype[set] = function (value, ...keys) {
const key = keys.pop()!;
resolveObj(this, keys)[key] = value;
return this;
}
```tsx
const switchCase = <t.switchCase $f>
{value}
<array>
<t.returnStatement>
{result}
</t.returnStatement>
</array>
</t.switchCase>
// implemented by default, can be overwriten
Object3D.prototype[assign] = function (value, ...keys) {
const key = keys.pop()!;
const target = resolveObj(this, keys);
useEffect(() => target[key] = value());
return this;
}
// turns into
const switchStatment = t.switchCase(value, [ t.returnStatment(result) ])
// implemented by default, can be overwriten
Object3D.prototype[call] = function (value, ...keys) {
const key = keys.pop()!;
const target = resolveObj(this, keys);
const f = target[key].bind(target);
useEffect(() => f(...value()));
return this;
}
```
### Mixed Mode - $n
the mixed mode is a mix between the class mode and the function mode
```tsx
const boxMesh = <Mesh $n
castShadow
receiveShadow
>
<BoxGeometry/>
<MeshPhongMaterial
color:set={$call(color())}
/>
</Mesh>
// turns into
const boxMesh = Mesh[create](
BoxGeometry[create](), // this return new BoxGeometry()
MeshPhongMaterial[create]()
[call](() => color(), "color", "set")
)
[set](true, "castShadow")
[set](true, "receiveShadow")
```
## Contexts

@@ -206,11 +201,9 @@

const child1 = <Child/> // run outside the EventsProvider so can't access the context
const child2 = () => <Child/> // run inside the EventsProvider
const child1 = <Child/>
const child2 = () => <Child/>
doSomething(<Child/>) // run outside the doSomething function
return <EventsProvider>
<Child/>
{child1}
{child2}
<Child/> {/* run inside the EventsProvider */}
{child1} {/* run outside the EventsProvider */}
{child2} {/* run inside the EventsProvider */}
<EventsProvider>

@@ -221,111 +214,2 @@ }

## Some Hooks
quick examples of some builtin hooks
```tsx
function Component() {
const add = useAppend();
// append the child to the closest real element
// derivate from the current context
// (more on this bellow)
add(<Child />)
const remove = useRemove();
remove(); // remove this component & the elements bellow the current context
onCleanup(() => {
// component has been removed
// atm there's no way to unmount -> remount
})
// useEffect can be used outside of components and JSX
useEffect(() => {
reactive() + 1;
})
useDebounced(() => {
reactive() + 1;
}, 1000)
// for now only inside the Canvas helper in battuta/three
const { camera, scene } = useScene();
useFrame((delta) => {})
// TweakPanel wrappers
const [getValue, setValue] = createTweakSignal("#ffffff");
useMonitor(() => Date.now())
}
```
Even tho there's no virtual dom we still has virtual relations & contexts. For example in this situation
```tsx
const Component = () => () => () => () => () => {
return <h1>Hello</h1>
}
const div = <div/>
```
the real tree looks like
```
- div
|---- h1
```
tho in relatity the relations look like this
```
- div
|---- f1
| |---- f2
| |---- f3
| |---- f4
| |---- f5
|-------------------|---- h1
```
the real tree is still composed just of the div and the h1 elements but the intermediary contexts exist (if consumed) so here each element are bound to their parent.
one thing to keep in mind is the virtual element exist only if the real elements received an uncalled function, this happens by default to components in the normal mode as their children prop is a function but for other modes it is not the case, so for example here
```tsx
function Child() {
return <h1/>
}
function Parent() {
return <div>
<Child/>
</div>
}
```
here two uncommon things happen, first here's the relation map of this code
```
- Parent (virtual, assuming it was used in a default mode component)
|---- div
| |---- h1
|---- Child
```
You can see the the child function don't appear where it should, this happens because the compilation result here is
```ts
function Parent() {
return createElement(div)[append](Child())
}
```
the div only receive the result of the child which is the second div so it never knows about the Child context, this generally don't cause issues as the div don't hold any special context.
the second uncommon behavior is that if you have a `onCleanup` hook in your Child the Child is gonna consume from the parenting context, which in this case is the Parent element, this doesn't cause issues unless you're directly removing the div separatly using the `cleanup` method, in this case the div will be removed as well as the h1 but the `onCleanup` hook won't run for the child as it's bound to the Parent component
## CLI

@@ -362,2 +246,3 @@

macros: Options,
root: "src/main.tsx",
optimizer: {

@@ -380,6 +265,7 @@ strings: true,

import { battutaJSX } from "battuta/vite";
import { battutaJSX, battutaInferModes } from "battuta/vite";
export default defineConfig({
plugins: [
battutaInferModes(),
battutaJSX()

@@ -386,0 +272,0 @@ ]