sibujs 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1630 -0
- package/dist/browser.cjs +815 -0
- package/dist/browser.d.cts +174 -0
- package/dist/browser.d.ts +174 -0
- package/dist/browser.js +458 -0
- package/dist/build.cjs +4970 -0
- package/dist/build.d.cts +630 -0
- package/dist/build.d.ts +630 -0
- package/dist/build.js +2478 -0
- package/dist/cdn.global.js +115 -0
- package/dist/chunk-27QC4FPL.js +67 -0
- package/dist/chunk-2ABBWCGC.js +65 -0
- package/dist/chunk-2MUNQYZ7.js +26 -0
- package/dist/chunk-2PSPKNUI.js +1711 -0
- package/dist/chunk-35CDLDX5.js +1758 -0
- package/dist/chunk-36MU4CFV.js +41 -0
- package/dist/chunk-3FIQOFI6.js +182 -0
- package/dist/chunk-3GHNC2BN.js +28 -0
- package/dist/chunk-3HLWWEPU.js +909 -0
- package/dist/chunk-3IVI3J54.js +252 -0
- package/dist/chunk-3KZ72WNW.js +944 -0
- package/dist/chunk-4AU64SQV.js +182 -0
- package/dist/chunk-4MOK7HAR.js +84 -0
- package/dist/chunk-4QK6FBDH.js +1429 -0
- package/dist/chunk-566Z7HXB.js +737 -0
- package/dist/chunk-5CRBB7XP.js +358 -0
- package/dist/chunk-5G67D3IZ.js +168 -0
- package/dist/chunk-5NCPAWBE.js +99 -0
- package/dist/chunk-5O2RKXR3.js +1444 -0
- package/dist/chunk-6BTBDO6A.js +633 -0
- package/dist/chunk-6IWEHW57.js +43 -0
- package/dist/chunk-6JGMNCD6.js +282 -0
- package/dist/chunk-6QRLJNXR.js +1425 -0
- package/dist/chunk-7HM5UE5T.js +270 -0
- package/dist/chunk-7JOLTGUH.js +58 -0
- package/dist/chunk-7MCWJCQK.js +909 -0
- package/dist/chunk-7RIIFP3E.js +1758 -0
- package/dist/chunk-7UASYN3G.js +254 -0
- package/dist/chunk-7W2WYHDI.js +741 -0
- package/dist/chunk-7Y35RDSJ.js +872 -0
- package/dist/chunk-A65GFJBL.js +65 -0
- package/dist/chunk-AD6ZIEDK.js +67 -0
- package/dist/chunk-AK5Y72F3.js +1426 -0
- package/dist/chunk-APOMMWH4.js +282 -0
- package/dist/chunk-ARZVTWIQ.js +1750 -0
- package/dist/chunk-AWWBM2BI.js +664 -0
- package/dist/chunk-AX5VEQTY.js +58 -0
- package/dist/chunk-AYTXVOW3.js +1708 -0
- package/dist/chunk-BG4A246G.js +1746 -0
- package/dist/chunk-BNFJJA2L.js +1425 -0
- package/dist/chunk-BPKPBVU5.js +59 -0
- package/dist/chunk-BPKPPSXC.js +282 -0
- package/dist/chunk-BPWKKK7F.js +1711 -0
- package/dist/chunk-CCKX6YTC.js +1735 -0
- package/dist/chunk-CIF5Z3MP.js +58 -0
- package/dist/chunk-CSXYU7IO.js +457 -0
- package/dist/chunk-D6JD4FDC.js +26 -0
- package/dist/chunk-E7NGA7X2.js +59 -0
- package/dist/chunk-EEPPJKAE.js +443 -0
- package/dist/chunk-EJMYGAGQ.js +717 -0
- package/dist/chunk-EL6Z5MDY.js +55 -0
- package/dist/chunk-EP7VRLEB.js +41 -0
- package/dist/chunk-ETMEC6FH.js +99 -0
- package/dist/chunk-EZ2WHYVL.js +65 -0
- package/dist/chunk-EZRVMSZK.js +67 -0
- package/dist/chunk-F2TRGINX.js +254 -0
- package/dist/chunk-F5JCIH3Q.js +642 -0
- package/dist/chunk-FGK3JKMN.js +909 -0
- package/dist/chunk-FQWPKSTD.js +1437 -0
- package/dist/chunk-FWHVLMCI.js +26 -0
- package/dist/chunk-GBEYQRO2.js +303 -0
- package/dist/chunk-GBLES3NK.js +248 -0
- package/dist/chunk-GQVGUQW6.js +1436 -0
- package/dist/chunk-HCV2T76T.js +457 -0
- package/dist/chunk-HS7ZKVPR.js +182 -0
- package/dist/chunk-HXDVV7HZ.js +909 -0
- package/dist/chunk-IB23VMO3.js +1746 -0
- package/dist/chunk-IEMZ7RTT.js +99 -0
- package/dist/chunk-IPGRSN42.js +1750 -0
- package/dist/chunk-IVMOK2QN.js +1750 -0
- package/dist/chunk-JCLGQO7T.js +443 -0
- package/dist/chunk-JDXL7KDB.js +1436 -0
- package/dist/chunk-JIIFW636.js +270 -0
- package/dist/chunk-JWGEEH7H.js +944 -0
- package/dist/chunk-K2BESAG7.js +1688 -0
- package/dist/chunk-K2U5YGF4.js +877 -0
- package/dist/chunk-K45FQ4Y4.js +175 -0
- package/dist/chunk-K7BPE427.js +1432 -0
- package/dist/chunk-KL3266RS.js +26 -0
- package/dist/chunk-KNN4P7DZ.js +84 -0
- package/dist/chunk-KP2DZH5Q.js +254 -0
- package/dist/chunk-KZHAJSQR.js +1636 -0
- package/dist/chunk-LBKGHMQV.js +1750 -0
- package/dist/chunk-LBTEPL7A.js +1731 -0
- package/dist/chunk-LEBBPTDB.js +1444 -0
- package/dist/chunk-LLH63WVQ.js +98 -0
- package/dist/chunk-LWVR2C4G.js +1711 -0
- package/dist/chunk-M3MDTVV2.js +896 -0
- package/dist/chunk-M5GNLDEO.js +303 -0
- package/dist/chunk-MFHVGKET.js +267 -0
- package/dist/chunk-MGWSG3PM.js +358 -0
- package/dist/chunk-MJNB47HB.js +19 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/chunk-MQWTY3JY.js +944 -0
- package/dist/chunk-MZZOQHNI.js +642 -0
- package/dist/chunk-NIHWGZS4.js +1426 -0
- package/dist/chunk-NSVVHQK5.js +41 -0
- package/dist/chunk-NVI2WE7D.js +443 -0
- package/dist/chunk-O7QBO3PH.js +58 -0
- package/dist/chunk-OAUPQBO2.js +270 -0
- package/dist/chunk-OB2LMD7C.js +297 -0
- package/dist/chunk-OHEYBWQU.js +58 -0
- package/dist/chunk-OI6OXUHJ.js +443 -0
- package/dist/chunk-OX2VMRMV.js +633 -0
- package/dist/chunk-P4FYE5TX.js +866 -0
- package/dist/chunk-P5KFWM4H.js +98 -0
- package/dist/chunk-PUMLE7RJ.js +1711 -0
- package/dist/chunk-Q4MFANBF.js +282 -0
- package/dist/chunk-QLEKZMMU.js +282 -0
- package/dist/chunk-RGGNGVO3.js +98 -0
- package/dist/chunk-RKJDRVV6.js +443 -0
- package/dist/chunk-S5BHU353.js +43 -0
- package/dist/chunk-SHQUSFH7.js +1426 -0
- package/dist/chunk-SMB4DBMD.js +182 -0
- package/dist/chunk-SNYHQP3D.js +743 -0
- package/dist/chunk-T24L3TBF.js +1717 -0
- package/dist/chunk-TAQNSOKT.js +692 -0
- package/dist/chunk-TDNY4SUA.js +41 -0
- package/dist/chunk-TNNF56IQ.js +1750 -0
- package/dist/chunk-TR7E6LYX.js +457 -0
- package/dist/chunk-URWUFH45.js +98 -0
- package/dist/chunk-UUSIH3XH.js +1429 -0
- package/dist/chunk-UYFNXLKR.js +1436 -0
- package/dist/chunk-V6F7KUWD.js +270 -0
- package/dist/chunk-VCZLXRMR.js +254 -0
- package/dist/chunk-VDHXSSBT.js +1426 -0
- package/dist/chunk-VM4QMKVK.js +254 -0
- package/dist/chunk-VWGYKYL2.js +737 -0
- package/dist/chunk-VX2OFBJN.js +1426 -0
- package/dist/chunk-VXVIE6DG.js +84 -0
- package/dist/chunk-W4OH7HG4.js +40 -0
- package/dist/chunk-WBVJX4GZ.js +98 -0
- package/dist/chunk-WDU2ZV4I.js +1426 -0
- package/dist/chunk-X6VUCICU.js +457 -0
- package/dist/chunk-XAY7FM7Y.js +618 -0
- package/dist/chunk-XJZ5Z2CM.js +642 -0
- package/dist/chunk-XKVFQTJJ.js +254 -0
- package/dist/chunk-XRLFASCY.js +22 -0
- package/dist/chunk-XYU6TZOW.js +182 -0
- package/dist/chunk-Y745CBVB.js +944 -0
- package/dist/chunk-YLBJSXYY.js +944 -0
- package/dist/chunk-YQJIKVPZ.js +1429 -0
- package/dist/chunk-YRM2VCZF.js +457 -0
- package/dist/chunk-YS33KBVJ.js +944 -0
- package/dist/chunk-Z27DZPDG.js +41 -0
- package/dist/chunk-ZXQ5NAEN.js +32 -0
- package/dist/contracts-B552GopR.d.cts +245 -0
- package/dist/contracts-B552GopR.d.ts +245 -0
- package/dist/contracts-Bg1ECISC.d.cts +245 -0
- package/dist/contracts-Bg1ECISC.d.ts +245 -0
- package/dist/contracts-CMriKJ6P.d.cts +245 -0
- package/dist/contracts-CMriKJ6P.d.ts +245 -0
- package/dist/contracts-DOrhwbke.d.cts +245 -0
- package/dist/contracts-DOrhwbke.d.ts +245 -0
- package/dist/data.cjs +1373 -0
- package/dist/data.d.cts +434 -0
- package/dist/data.d.ts +434 -0
- package/dist/data.js +945 -0
- package/dist/devtools.cjs +1357 -0
- package/dist/devtools.d.cts +473 -0
- package/dist/devtools.d.ts +473 -0
- package/dist/devtools.js +1084 -0
- package/dist/ecosystem.cjs +1046 -0
- package/dist/ecosystem.d.cts +247 -0
- package/dist/ecosystem.d.ts +247 -0
- package/dist/ecosystem.js +369 -0
- package/dist/extras.cjs +8457 -0
- package/dist/extras.d.cts +2356 -0
- package/dist/extras.d.ts +2356 -0
- package/dist/extras.js +5152 -0
- package/dist/index.cjs +2648 -0
- package/dist/index.d.cts +869 -0
- package/dist/index.d.ts +869 -0
- package/dist/index.js +386 -0
- package/dist/motion.cjs +604 -0
- package/dist/motion.d.cts +146 -0
- package/dist/motion.d.ts +146 -0
- package/dist/motion.js +346 -0
- package/dist/patterns.cjs +815 -0
- package/dist/patterns.d.cts +163 -0
- package/dist/patterns.d.ts +163 -0
- package/dist/patterns.js +296 -0
- package/dist/performance.cjs +927 -0
- package/dist/performance.d.cts +416 -0
- package/dist/performance.d.ts +416 -0
- package/dist/performance.js +654 -0
- package/dist/plugins.cjs +2487 -0
- package/dist/plugins.d.cts +393 -0
- package/dist/plugins.d.ts +393 -0
- package/dist/plugins.js +1504 -0
- package/dist/signal-BnWpq6WB.d.cts +5 -0
- package/dist/signal-BnWpq6WB.d.ts +5 -0
- package/dist/src/components/ErrorBoundary.d.ts +15 -0
- package/dist/src/components/ErrorBoundary.js +119 -0
- package/dist/src/core/catch.d.ts +11 -0
- package/dist/src/core/catch.js +28 -0
- package/dist/src/core/each.d.ts +13 -0
- package/dist/src/core/each.js +68 -0
- package/dist/src/core/for.d.ts +12 -0
- package/dist/src/core/for.js +67 -0
- package/dist/src/core/html.d.ts +137 -0
- package/dist/src/core/html.js +155 -0
- package/dist/src/core/htmlIf.d.ts +11 -0
- package/dist/src/core/htmlIf.js +18 -0
- package/dist/src/core/lazy.d.ts +7 -0
- package/dist/src/core/lazy.js +16 -0
- package/dist/src/core/mount.d.ts +7 -0
- package/dist/src/core/mount.js +12 -0
- package/dist/src/core/slots.d.ts +3 -0
- package/dist/src/core/slots.js +3 -0
- package/dist/src/core/suspense.d.ts +10 -0
- package/dist/src/core/suspense.js +33 -0
- package/dist/src/core/tagFactory.d.ts +13 -0
- package/dist/src/core/tagFactory.js +86 -0
- package/dist/src/core/test.d.ts +11 -0
- package/dist/src/core/test.js +28 -0
- package/dist/src/core/types.d.ts +2 -0
- package/dist/src/core/types.js +1 -0
- package/dist/src/core/useComputed.d.ts +6 -0
- package/dist/src/core/useComputed.js +30 -0
- package/dist/src/core/useEffect.d.ts +6 -0
- package/dist/src/core/useEffect.js +23 -0
- package/dist/src/core/useState.d.ts +10 -0
- package/dist/src/core/useState.js +34 -0
- package/dist/src/core/useStore.d.ts +19 -0
- package/dist/src/core/useStore.js +53 -0
- package/dist/src/core/useWatch.d.ts +8 -0
- package/dist/src/core/useWatch.js +23 -0
- package/dist/src/plugins/i18n.d.ts +6 -0
- package/dist/src/plugins/i18n.js +16 -0
- package/dist/src/plugins/router.d.ts +188 -0
- package/dist/src/plugins/router.js +1178 -0
- package/dist/src/reactivity/bindAttribute.d.ts +5 -0
- package/dist/src/reactivity/bindAttribute.js +31 -0
- package/dist/src/reactivity/bindChildNode.d.ts +10 -0
- package/dist/src/reactivity/bindChildNode.js +46 -0
- package/dist/src/reactivity/bindTextNode.d.ts +10 -0
- package/dist/src/reactivity/bindTextNode.js +27 -0
- package/dist/src/reactivity/signal.d.ts +3 -0
- package/dist/src/reactivity/signal.js +1 -0
- package/dist/src/reactivity/track.d.ts +18 -0
- package/dist/src/reactivity/track.js +73 -0
- package/dist/src/reactivity/useComputed.d.ts +6 -0
- package/dist/src/reactivity/useComputed.js +30 -0
- package/dist/src/reactivity/useEffect.d.ts +6 -0
- package/dist/src/reactivity/useEffect.js +23 -0
- package/dist/src/reactivity/useState.d.ts +10 -0
- package/dist/src/reactivity/useState.js +34 -0
- package/dist/src/reactivity/useStore.d.ts +19 -0
- package/dist/src/reactivity/useStore.js +53 -0
- package/dist/src/reactivity/useWatch.d.ts +8 -0
- package/dist/src/reactivity/useWatch.js +23 -0
- package/dist/src/utils/sanitize.d.ts +1 -0
- package/dist/src/utils/sanitize.js +8 -0
- package/dist/ssr-27FOM46T.js +35 -0
- package/dist/ssr-GFUTTSJD.js +22 -0
- package/dist/ssr-K7DCR6BZ.js +35 -0
- package/dist/ssr-O6LFMRFP.js +35 -0
- package/dist/ssr-QZEVGMMK.js +35 -0
- package/dist/ssr-SGVBCAGC.js +35 -0
- package/dist/ssr-UB2IXCYX.js +35 -0
- package/dist/ssr-XBZQNV4O.js +22 -0
- package/dist/ssr-Y76FSXDU.js +35 -0
- package/dist/ssr-YQJ4AYBD.js +35 -0
- package/dist/ssr.cjs +1757 -0
- package/dist/ssr.d.cts +478 -0
- package/dist/ssr.d.ts +478 -0
- package/dist/ssr.js +743 -0
- package/dist/tagFactory-CZPO4RXF.d.cts +34 -0
- package/dist/tagFactory-CZPO4RXF.d.ts +34 -0
- package/dist/tagFactory-CgImPVMY.d.cts +22 -0
- package/dist/tagFactory-CgImPVMY.d.ts +22 -0
- package/dist/tagFactory-Cw1iv5if.d.cts +22 -0
- package/dist/tagFactory-Cw1iv5if.d.ts +22 -0
- package/dist/tagFactory-DeAXq9ef.d.cts +30 -0
- package/dist/tagFactory-DeAXq9ef.d.ts +30 -0
- package/dist/tagFactory-SkY0a7L1.d.cts +22 -0
- package/dist/tagFactory-SkY0a7L1.d.ts +22 -0
- package/dist/testing.cjs +1919 -0
- package/dist/testing.d.cts +491 -0
- package/dist/testing.d.ts +491 -0
- package/dist/testing.js +1862 -0
- package/dist/ui.cjs +1497 -0
- package/dist/ui.d.cts +264 -0
- package/dist/ui.d.ts +264 -0
- package/dist/ui.js +900 -0
- package/dist/widgets.cjs +919 -0
- package/dist/widgets.d.cts +165 -0
- package/dist/widgets.d.ts +165 -0
- package/dist/widgets.js +545 -0
- package/package.json +134 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// src/core/htmlIf.ts
|
|
2
|
+
import { bindChildNode } from "../reactivity/bindChildNode";
|
|
3
|
+
/**
|
|
4
|
+
* Conditionally mounts a node subtree based on a reactive predicate.
|
|
5
|
+
* When the condition is true, the render function is invoked and its result is displayed.
|
|
6
|
+
* When false, the subtree is removed.
|
|
7
|
+
*
|
|
8
|
+
* @param condition - Reactive predicate that returns a boolean.
|
|
9
|
+
* @param render - Function that returns the NodeChild to mount.
|
|
10
|
+
* @returns A Comment node serving as the anchor point.
|
|
11
|
+
*/
|
|
12
|
+
export function htmlIf(condition, render) {
|
|
13
|
+
const anchor = document.createComment("htmlIf");
|
|
14
|
+
bindChildNode(anchor, () => {
|
|
15
|
+
return condition() ? render() : null;
|
|
16
|
+
});
|
|
17
|
+
return anchor;
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState } from "../reactivity/useState";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a lazy-loaded component.
|
|
4
|
+
*/
|
|
5
|
+
export function lazy(loader) {
|
|
6
|
+
const [ComponentSignal, setComponent] = useState(null);
|
|
7
|
+
let loading = false;
|
|
8
|
+
return function LazyComponent() {
|
|
9
|
+
if (!loading) {
|
|
10
|
+
loading = true;
|
|
11
|
+
loader().then(mod => setComponent(() => mod.default));
|
|
12
|
+
}
|
|
13
|
+
const Comp = ComponentSignal();
|
|
14
|
+
return Comp ? Comp() : null;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mounts a root component into a DOM element.
|
|
3
|
+
*
|
|
4
|
+
* @param component Function that returns an HTMLElement
|
|
5
|
+
* @param container Target DOM element to append the result
|
|
6
|
+
*/
|
|
7
|
+
export declare function mount(component: () => HTMLElement, container: HTMLElement | null): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mounts a root component into a DOM element.
|
|
3
|
+
*
|
|
4
|
+
* @param component Function that returns an HTMLElement
|
|
5
|
+
* @param container Target DOM element to append the result
|
|
6
|
+
*/
|
|
7
|
+
export function mount(component, container) {
|
|
8
|
+
if (!container) {
|
|
9
|
+
throw new Error("Mount target element not found.");
|
|
10
|
+
}
|
|
11
|
+
container.appendChild(component());
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NodeChild } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Suspense:
|
|
4
|
+
* - Uses a DocumentFragment with anchor and optional static node.
|
|
5
|
+
* - If fallback is function, schedules reactive updates via bindChildNode.
|
|
6
|
+
*/
|
|
7
|
+
export declare function Suspense(props: {
|
|
8
|
+
fallback: NodeChild | (() => NodeChild);
|
|
9
|
+
children: () => NodeChild | null;
|
|
10
|
+
}): DocumentFragment;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { bindChildNode } from "../reactivity/bindChildNode";
|
|
2
|
+
/**
|
|
3
|
+
* Suspense:
|
|
4
|
+
* - Uses a DocumentFragment with anchor and optional static node.
|
|
5
|
+
* - If fallback is function, schedules reactive updates via bindChildNode.
|
|
6
|
+
*/
|
|
7
|
+
export function Suspense(props) {
|
|
8
|
+
const anchor = document.createComment("suspense");
|
|
9
|
+
const frag = document.createDocumentFragment();
|
|
10
|
+
frag.appendChild(anchor);
|
|
11
|
+
const initial = props.children();
|
|
12
|
+
const hasStaticFallback = typeof props.fallback !== "function";
|
|
13
|
+
if (initial != null) {
|
|
14
|
+
const node = initial instanceof Node ? initial : document.createTextNode(String(initial));
|
|
15
|
+
frag.appendChild(node);
|
|
16
|
+
}
|
|
17
|
+
else if (hasStaticFallback) {
|
|
18
|
+
const fb = props.fallback;
|
|
19
|
+
const node = fb instanceof Node ? fb : document.createTextNode(String(fb));
|
|
20
|
+
frag.appendChild(node);
|
|
21
|
+
}
|
|
22
|
+
if (!hasStaticFallback) {
|
|
23
|
+
queueMicrotask(() => {
|
|
24
|
+
bindChildNode(anchor, () => {
|
|
25
|
+
const next = props.children();
|
|
26
|
+
if (next != null)
|
|
27
|
+
return next;
|
|
28
|
+
return props.fallback();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return frag;
|
|
33
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NodeChildren } from "./types";
|
|
2
|
+
export interface TagProps {
|
|
3
|
+
id?: string;
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: Record<string, string | number> | string;
|
|
6
|
+
children?: NodeChildren;
|
|
7
|
+
on?: Record<string, (ev: Event) => void>;
|
|
8
|
+
[attr: string]: any;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Factory for creating HTML elements with reactive props and children
|
|
12
|
+
*/
|
|
13
|
+
export declare const tagFactory: (tag: string) => (props?: TagProps) => HTMLElement;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { bindAttribute } from "../reactivity/bindAttribute";
|
|
2
|
+
import { bindChildNode } from "../reactivity/bindChildNode";
|
|
3
|
+
// Applies inline styles or style object
|
|
4
|
+
function applyStyle(el, style) {
|
|
5
|
+
if (!style)
|
|
6
|
+
return;
|
|
7
|
+
if (typeof style === "string") {
|
|
8
|
+
el.setAttribute("style", style);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
for (const [prop, val] of Object.entries(style)) {
|
|
12
|
+
const name = prop.replace(/[A-Z]/g, m => "-" + m.toLowerCase());
|
|
13
|
+
el.style.setProperty(name, String(val));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Renders a single child: static or reactive
|
|
18
|
+
function renderChild(child) {
|
|
19
|
+
if (child == null) {
|
|
20
|
+
return document.createTextNode("");
|
|
21
|
+
}
|
|
22
|
+
if (typeof child === "function") {
|
|
23
|
+
const placeholder = document.createComment("bind:child");
|
|
24
|
+
queueMicrotask(() => bindChildNode(placeholder, child));
|
|
25
|
+
return placeholder;
|
|
26
|
+
}
|
|
27
|
+
if (child instanceof Node) {
|
|
28
|
+
return child;
|
|
29
|
+
}
|
|
30
|
+
// string or number
|
|
31
|
+
return document.createTextNode(String(child));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Factory for creating HTML elements with reactive props and children
|
|
35
|
+
*/
|
|
36
|
+
export const tagFactory = (tag) => (props = {}) => {
|
|
37
|
+
const el = document.createElement(tag);
|
|
38
|
+
// Process props
|
|
39
|
+
for (const [key, value] of Object.entries(props)) {
|
|
40
|
+
if (value == null)
|
|
41
|
+
continue;
|
|
42
|
+
switch (key) {
|
|
43
|
+
case "id":
|
|
44
|
+
el.id = String(value);
|
|
45
|
+
break;
|
|
46
|
+
case "class":
|
|
47
|
+
el.className = String(value);
|
|
48
|
+
break;
|
|
49
|
+
case "style":
|
|
50
|
+
applyStyle(el, value);
|
|
51
|
+
break;
|
|
52
|
+
case "on":
|
|
53
|
+
{
|
|
54
|
+
const handlers = value;
|
|
55
|
+
for (const [ev, handler] of Object.entries(handlers || {})) {
|
|
56
|
+
el.addEventListener(ev, handler);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case "children":
|
|
61
|
+
{
|
|
62
|
+
const childs = Array.isArray(value) ? value : [value];
|
|
63
|
+
for (const c of childs) {
|
|
64
|
+
if (Array.isArray(c)) {
|
|
65
|
+
for (const nested of c) {
|
|
66
|
+
el.appendChild(renderChild(nested));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
el.appendChild(renderChild(c));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
// Other attributes
|
|
77
|
+
if (typeof value === "function") {
|
|
78
|
+
bindAttribute(el, key, value);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
el.setAttribute(key, String(value));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return el;
|
|
86
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type ErrorHandler = (error: unknown, context?: any) => void;
|
|
2
|
+
/**
|
|
3
|
+
* Wraps any function in a try/catch block and optionally passes error to a handler.
|
|
4
|
+
* This is used internally by components or boundaries.
|
|
5
|
+
*/
|
|
6
|
+
export declare function catchError(fn: () => any, onError?: ErrorHandler): any;
|
|
7
|
+
/**
|
|
8
|
+
* Sets a global error handler used by default if no onError is provided.
|
|
9
|
+
*/
|
|
10
|
+
export declare function setGlobalErrorHandler(handler: ErrorHandler): void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
let globalErrorHandler = null;
|
|
2
|
+
/**
|
|
3
|
+
* Wraps any function in a try/catch block and optionally passes error to a handler.
|
|
4
|
+
* This is used internally by components or boundaries.
|
|
5
|
+
*/
|
|
6
|
+
export function catchError(fn, onError) {
|
|
7
|
+
try {
|
|
8
|
+
return fn();
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
if (onError) {
|
|
12
|
+
onError(err);
|
|
13
|
+
}
|
|
14
|
+
else if (globalErrorHandler) {
|
|
15
|
+
globalErrorHandler(err);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.error("Unhandled error in Sibu.catch:", err);
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Sets a global error handler used by default if no onError is provided.
|
|
25
|
+
*/
|
|
26
|
+
export function setGlobalErrorHandler(handler) {
|
|
27
|
+
globalErrorHandler = handler;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useComputed creates a derived reactive signal whose value updates when dependencies change.
|
|
3
|
+
* @param getter Function returning computed value based on reactive signals.
|
|
4
|
+
* @returns Getter function for the computed value.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useComputed<T>(getter: () => T): () => T;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { track, recordDependency, notifySubscribers } from "../reactivity/track";
|
|
2
|
+
/**
|
|
3
|
+
* useComputed creates a derived reactive signal whose value updates when dependencies change.
|
|
4
|
+
* @param getter Function returning computed value based on reactive signals.
|
|
5
|
+
* @returns Getter function for the computed value.
|
|
6
|
+
*/
|
|
7
|
+
export function useComputed(getter) {
|
|
8
|
+
// Initial value computation
|
|
9
|
+
let value = getter();
|
|
10
|
+
// Signal object representing this computed's identity
|
|
11
|
+
const computedSignal = {};
|
|
12
|
+
// Recompute function subscribed to dependency changes
|
|
13
|
+
const recompute = () => {
|
|
14
|
+
const next = getter();
|
|
15
|
+
if (Object.is(next, value))
|
|
16
|
+
return;
|
|
17
|
+
value = next;
|
|
18
|
+
notifySubscribers(computedSignal);
|
|
19
|
+
};
|
|
20
|
+
// Track dependencies and register recompute callback
|
|
21
|
+
track(recompute, recompute);
|
|
22
|
+
/**
|
|
23
|
+
* Getter for the computed value.
|
|
24
|
+
* Registers a dependency on this computed signal and returns the current value.
|
|
25
|
+
*/
|
|
26
|
+
return function computedGetter() {
|
|
27
|
+
recordDependency(computedSignal);
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { track } from "../reactivity/track";
|
|
2
|
+
/**
|
|
3
|
+
* useEffect runs the provided effectFn immediately and re-runs it whenever
|
|
4
|
+
* any reactive dependency changes.
|
|
5
|
+
* Returns a cleanup function to stop further executions.
|
|
6
|
+
*/
|
|
7
|
+
export function useEffect(effectFn) {
|
|
8
|
+
// Internal cleanup handle for previous subscription
|
|
9
|
+
let cleanupHandle = () => { };
|
|
10
|
+
// Subscriber function that re-schedules the effect when dependencies notify
|
|
11
|
+
const subscriber = () => {
|
|
12
|
+
// Cleanup previous subscriptions before re-running
|
|
13
|
+
cleanupHandle();
|
|
14
|
+
// Track the effect and update cleanupHandle
|
|
15
|
+
cleanupHandle = track(effectFn, subscriber);
|
|
16
|
+
};
|
|
17
|
+
// Initial execution and subscription
|
|
18
|
+
cleanupHandle = track(effectFn, subscriber);
|
|
19
|
+
// Return a function to cleanup and stop any further effect runs
|
|
20
|
+
return () => {
|
|
21
|
+
cleanupHandle();
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type SetState<T> = (next: T | ((prev: T) => T)) => void;
|
|
2
|
+
type StateTuple<T> = [() => T, SetState<T>];
|
|
3
|
+
/**
|
|
4
|
+
* useState creates a reactive signal that holds a value of type T.
|
|
5
|
+
* Returns a tuple: [getter, setter].
|
|
6
|
+
* - getter(): registers dependency and returns the current state value.
|
|
7
|
+
* - setter(next): updates the state and notifies subscribers if changed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useState<T>(initial: T): StateTuple<T>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { recordDependency, notifySubscribers } from "../reactivity/track";
|
|
2
|
+
/**
|
|
3
|
+
* useState creates a reactive signal that holds a value of type T.
|
|
4
|
+
* Returns a tuple: [getter, setter].
|
|
5
|
+
* - getter(): registers dependency and returns the current state value.
|
|
6
|
+
* - setter(next): updates the state and notifies subscribers if changed.
|
|
7
|
+
*/
|
|
8
|
+
export function useState(initial) {
|
|
9
|
+
// Internal state container acts as the ReactiveSignal
|
|
10
|
+
const state = { value: initial };
|
|
11
|
+
/**
|
|
12
|
+
* Getter for the state value.
|
|
13
|
+
* Registers this call as a dependency on the current subscriber.
|
|
14
|
+
*/
|
|
15
|
+
function get() {
|
|
16
|
+
recordDependency(state);
|
|
17
|
+
return state.value;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Setter for the state value.
|
|
21
|
+
* Accepts a new value or an updater function.
|
|
22
|
+
* Notifies subscribers only if the new value is different (Object.is).
|
|
23
|
+
*/
|
|
24
|
+
function set(next) {
|
|
25
|
+
const newValue = typeof next === "function"
|
|
26
|
+
? next(state.value)
|
|
27
|
+
: next;
|
|
28
|
+
if (Object.is(newValue, state.value))
|
|
29
|
+
return;
|
|
30
|
+
state.value = newValue;
|
|
31
|
+
notifySubscribers(state);
|
|
32
|
+
}
|
|
33
|
+
return [get, set];
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a global store with reactive properties.
|
|
3
|
+
*
|
|
4
|
+
* @param initialState Initial state object
|
|
5
|
+
* @returns A tuple [store, actions]:
|
|
6
|
+
* - store: Proxy object with reactive getters for each state property
|
|
7
|
+
* - actions:
|
|
8
|
+
* - setState: apply a partial patch or updater function
|
|
9
|
+
* - reset: revert to initial state
|
|
10
|
+
*/
|
|
11
|
+
export declare function useStore<T extends object>(initialState: T): [
|
|
12
|
+
store: {
|
|
13
|
+
readonly [K in keyof T]: T[K];
|
|
14
|
+
},
|
|
15
|
+
actions: {
|
|
16
|
+
setState: (patch: Partial<T> | ((state: T) => T)) => void;
|
|
17
|
+
reset: () => void;
|
|
18
|
+
}
|
|
19
|
+
];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useState } from "./useState";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a global store with reactive properties.
|
|
4
|
+
*
|
|
5
|
+
* @param initialState Initial state object
|
|
6
|
+
* @returns A tuple [store, actions]:
|
|
7
|
+
* - store: Proxy object with reactive getters for each state property
|
|
8
|
+
* - actions:
|
|
9
|
+
* - setState: apply a partial patch or updater function
|
|
10
|
+
* - reset: revert to initial state
|
|
11
|
+
*/
|
|
12
|
+
export function useStore(initialState) {
|
|
13
|
+
// Create individual signals for each key
|
|
14
|
+
const signals = {};
|
|
15
|
+
// Initialize signals
|
|
16
|
+
Object.keys(initialState).forEach((key) => {
|
|
17
|
+
const [getter, setter] = useState(initialState[key]);
|
|
18
|
+
signals[key] = [getter, setter];
|
|
19
|
+
});
|
|
20
|
+
// Proxy to expose reactive getters
|
|
21
|
+
const store = new Proxy({}, {
|
|
22
|
+
get(_, prop) {
|
|
23
|
+
if (prop in signals) {
|
|
24
|
+
const getter = signals[prop][0];
|
|
25
|
+
return getter();
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
},
|
|
29
|
+
set() {
|
|
30
|
+
throw new Error("Direct mutation of store is not allowed. Use actions.setState.");
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
// Actions
|
|
34
|
+
const setState = (patch) => {
|
|
35
|
+
const current = {};
|
|
36
|
+
Object.keys(signals).forEach((key) => {
|
|
37
|
+
current[key] = signals[key][0]();
|
|
38
|
+
});
|
|
39
|
+
const nextState = typeof patch === "function" ? patch(current) : patch;
|
|
40
|
+
Object.entries(nextState).forEach(([key, value]) => {
|
|
41
|
+
if (key in signals) {
|
|
42
|
+
signals[key][1](value);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const reset = () => {
|
|
47
|
+
Object.keys(initialState).forEach((key) => {
|
|
48
|
+
const setter = signals[key][1];
|
|
49
|
+
setter(initialState[key]);
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
return [store, { setState, reset }];
|
|
53
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watches a reactive getter and calls callback with (newValue, oldValue) when it changes.
|
|
3
|
+
*
|
|
4
|
+
* @param getter Function that returns the value to watch (reads reactive signals).
|
|
5
|
+
* @param callback Function called when the watched value changes.
|
|
6
|
+
* @returns Teardown function to cancel the watcher.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useWatch<T>(getter: () => T, callback: (value: T, prev: T | undefined) => void): () => void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { track } from "../reactivity/track";
|
|
2
|
+
/**
|
|
3
|
+
* Watches a reactive getter and calls callback with (newValue, oldValue) when it changes.
|
|
4
|
+
*
|
|
5
|
+
* @param getter Function that returns the value to watch (reads reactive signals).
|
|
6
|
+
* @param callback Function called when the watched value changes.
|
|
7
|
+
* @returns Teardown function to cancel the watcher.
|
|
8
|
+
*/
|
|
9
|
+
export function useWatch(getter, callback) {
|
|
10
|
+
// Get initial value without registering dependencies
|
|
11
|
+
let oldValue = getter();
|
|
12
|
+
// Subscriber function for track
|
|
13
|
+
const subscriber = () => {
|
|
14
|
+
const newValue = getter();
|
|
15
|
+
if (newValue !== oldValue) {
|
|
16
|
+
callback(newValue, oldValue);
|
|
17
|
+
oldValue = newValue;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
// Track dependencies and return teardown for unsubscription
|
|
21
|
+
const teardown = track(subscriber, subscriber);
|
|
22
|
+
return teardown;
|
|
23
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type Translations = Record<string, string>;
|
|
2
|
+
type Params = Record<string, string | number>;
|
|
3
|
+
export declare function setLocale(locale: string): void;
|
|
4
|
+
export declare function registerTranslations(locale: string, messages: Translations): void;
|
|
5
|
+
export declare function t(key: string, params?: Params): string;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState } from "../core/useState";
|
|
2
|
+
const [currentLocale, setLocaleInternal] = useState("en");
|
|
3
|
+
const locales = {};
|
|
4
|
+
export function setLocale(locale) {
|
|
5
|
+
setLocaleInternal(locale);
|
|
6
|
+
}
|
|
7
|
+
export function registerTranslations(locale, messages) {
|
|
8
|
+
locales[locale] = messages;
|
|
9
|
+
}
|
|
10
|
+
export function t(key, params) {
|
|
11
|
+
const locale = currentLocale();
|
|
12
|
+
const message = locales[locale]?.[key] || key;
|
|
13
|
+
return params
|
|
14
|
+
? message.replace(/\{(\w+)\}/g, (_, p) => String(params[p] ?? ""))
|
|
15
|
+
: message;
|
|
16
|
+
}
|