feat: restructure project and update documentation

This commit is contained in:
2026-03-22 01:10:30 +01:00
parent 07d1fb0060
commit b95af97596
148 changed files with 3707 additions and 20260 deletions

View File

@@ -0,0 +1,275 @@
import {
useMediaQuery
} from "./chunk-RLEUDPPB.js";
import {
computed,
ref,
shallowRef,
watch
} from "./chunk-3S55Y3P7.js";
// node_modules/vitepress/dist/client/theme-default/index.js
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/fonts.css";
// node_modules/vitepress/dist/client/theme-default/without-fonts.js
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/vars.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/base.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/icons.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/utils.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css";
import "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css";
import VPBadge from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
import Layout from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/Layout.vue";
import { default as default2 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
import { default as default3 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue";
import { default as default4 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue";
import { default as default5 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPFeatures.vue";
import { default as default6 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPHomeContent.vue";
import { default as default7 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue";
import { default as default8 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue";
import { default as default9 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue";
import { default as default10 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue";
import { default as default11 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPLink.vue";
import { default as default12 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearch.vue";
import { default as default13 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPSocialLink.vue";
import { default as default14 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPSocialLinks.vue";
import { default as default15 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue";
import { default as default16 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue";
import { default as default17 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue";
import { default as default18 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue";
import { default as default19 } from "/config/workspace/sigpro/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue";
// node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
import { onContentUpdated } from "vitepress";
// node_modules/vitepress/dist/client/theme-default/composables/outline.js
import { getScrollOffset } from "vitepress";
// node_modules/vitepress/dist/client/theme-default/support/utils.js
import { withBase } from "vitepress";
// node_modules/vitepress/dist/client/theme-default/composables/data.js
import { useData as useData$ } from "vitepress";
var useData = useData$;
// node_modules/vitepress/dist/client/theme-default/support/utils.js
function ensureStartingSlash(path) {
return path.startsWith("/") ? path : `/${path}`;
}
// node_modules/vitepress/dist/client/theme-default/support/sidebar.js
function getSidebar(_sidebar, path) {
if (Array.isArray(_sidebar))
return addBase(_sidebar);
if (_sidebar == null)
return [];
path = ensureStartingSlash(path);
const dir = Object.keys(_sidebar).sort((a, b) => {
return b.split("/").length - a.split("/").length;
}).find((dir2) => {
return path.startsWith(ensureStartingSlash(dir2));
});
const sidebar = dir ? _sidebar[dir] : [];
return Array.isArray(sidebar) ? addBase(sidebar) : addBase(sidebar.items, sidebar.base);
}
function getSidebarGroups(sidebar) {
const groups = [];
let lastGroupIndex = 0;
for (const index in sidebar) {
const item = sidebar[index];
if (item.items) {
lastGroupIndex = groups.push(item);
continue;
}
if (!groups[lastGroupIndex]) {
groups.push({ items: [] });
}
groups[lastGroupIndex].items.push(item);
}
return groups;
}
function addBase(items, _base) {
return [...items].map((_item) => {
const item = { ..._item };
const base = item.base || _base;
if (base && item.link)
item.link = base + item.link;
if (item.items)
item.items = addBase(item.items, base);
return item;
});
}
// node_modules/vitepress/dist/client/theme-default/composables/sidebar.js
function useSidebar() {
const { frontmatter, page, theme: theme2 } = useData();
const is960 = useMediaQuery("(min-width: 960px)");
const isOpen = ref(false);
const _sidebar = computed(() => {
const sidebarConfig = theme2.value.sidebar;
const relativePath = page.value.relativePath;
return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : [];
});
const sidebar = ref(_sidebar.value);
watch(_sidebar, (next, prev) => {
if (JSON.stringify(next) !== JSON.stringify(prev))
sidebar.value = _sidebar.value;
});
const hasSidebar = computed(() => {
return frontmatter.value.sidebar !== false && sidebar.value.length > 0 && frontmatter.value.layout !== "home";
});
const leftAside = computed(() => {
if (hasAside)
return frontmatter.value.aside == null ? theme2.value.aside === "left" : frontmatter.value.aside === "left";
return false;
});
const hasAside = computed(() => {
if (frontmatter.value.layout === "home")
return false;
if (frontmatter.value.aside != null)
return !!frontmatter.value.aside;
return theme2.value.aside !== false;
});
const isSidebarEnabled = computed(() => hasSidebar.value && is960.value);
const sidebarGroups = computed(() => {
return hasSidebar.value ? getSidebarGroups(sidebar.value) : [];
});
function open() {
isOpen.value = true;
}
function close() {
isOpen.value = false;
}
function toggle() {
isOpen.value ? close() : open();
}
return {
isOpen,
sidebar,
sidebarGroups,
hasSidebar,
hasAside,
leftAside,
isSidebarEnabled,
open,
close,
toggle
};
}
// node_modules/vitepress/dist/client/theme-default/composables/outline.js
var ignoreRE = /\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/;
var resolvedHeaders = [];
function getHeaders(range) {
const headers = [
...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")
].filter((el) => el.id && el.hasChildNodes()).map((el) => {
const level = Number(el.tagName[1]);
return {
element: el,
title: serializeHeader(el),
link: "#" + el.id,
level
};
});
return resolveHeaders(headers, range);
}
function serializeHeader(h) {
let ret = "";
for (const node of h.childNodes) {
if (node.nodeType === 1) {
if (ignoreRE.test(node.className))
continue;
ret += node.textContent;
} else if (node.nodeType === 3) {
ret += node.textContent;
}
}
return ret.trim();
}
function resolveHeaders(headers, range) {
if (range === false) {
return [];
}
const levelsRange = (typeof range === "object" && !Array.isArray(range) ? range.level : range) || 2;
const [high, low] = typeof levelsRange === "number" ? [levelsRange, levelsRange] : levelsRange === "deep" ? [2, 6] : levelsRange;
return buildTree(headers, high, low);
}
function buildTree(data, min, max) {
resolvedHeaders.length = 0;
const result = [];
const stack = [];
data.forEach((item) => {
const node = { ...item, children: [] };
let parent = stack[stack.length - 1];
while (parent && parent.level >= node.level) {
stack.pop();
parent = stack[stack.length - 1];
}
if (node.element.classList.contains("ignore-header") || parent && "shouldIgnore" in parent) {
stack.push({ level: node.level, shouldIgnore: true });
return;
}
if (node.level > max || node.level < min)
return;
resolvedHeaders.push({ element: node.element, link: node.link });
if (parent)
parent.children.push(node);
else
result.push(node);
stack.push(node);
});
return result;
}
// node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
function useLocalNav() {
const { theme: theme2, frontmatter } = useData();
const headers = shallowRef([]);
const hasLocalNav = computed(() => {
return headers.value.length > 0;
});
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme2.value.outline);
});
return {
headers,
hasLocalNav
};
}
// node_modules/vitepress/dist/client/theme-default/without-fonts.js
var theme = {
Layout,
enhanceApp: ({ app }) => {
app.component("Badge", VPBadge);
}
};
var without_fonts_default = theme;
export {
default2 as VPBadge,
default3 as VPButton,
default4 as VPDocAsideSponsors,
default5 as VPFeatures,
default6 as VPHomeContent,
default7 as VPHomeFeatures,
default8 as VPHomeHero,
default9 as VPHomeSponsors,
default10 as VPImage,
default11 as VPLink,
default12 as VPNavBarSearch,
default13 as VPSocialLink,
default14 as VPSocialLinks,
default15 as VPSponsors,
default16 as VPTeamMembers,
default17 as VPTeamPage,
default18 as VPTeamPageSection,
default19 as VPTeamPageTitle,
without_fonts_default as default,
useLocalNav,
useSidebar
};
//# sourceMappingURL=@theme_index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,40 @@
{
"hash": "0412844f",
"configHash": "5a0057cf",
"lockfileHash": "e3b0c442",
"browserHash": "d3515516",
"optimized": {
"vue": {
"src": "../../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
"fileHash": "5e2bcecf",
"needsInterop": false
},
"vitepress > @vue/devtools-api": {
"src": "../../../../../node_modules/@vue/devtools-api/dist/index.js",
"file": "vitepress___@vue_devtools-api.js",
"fileHash": "604942f7",
"needsInterop": false
},
"vitepress > @vueuse/core": {
"src": "../../../../../node_modules/@vueuse/core/index.mjs",
"file": "vitepress___@vueuse_core.js",
"fileHash": "f08e5a15",
"needsInterop": false
},
"@theme/index": {
"src": "../../../../../node_modules/vitepress/dist/client/theme-default/index.js",
"file": "@theme_index.js",
"fileHash": "442c9e5b",
"needsInterop": false
}
},
"chunks": {
"chunk-RLEUDPPB": {
"file": "chunk-RLEUDPPB.js"
},
"chunk-3S55Y3P7": {
"file": "chunk-3S55Y3P7.js"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,583 @@
import {
DefaultMagicKeysAliasMap,
StorageSerializers,
TransitionPresets,
assert,
breakpointsAntDesign,
breakpointsBootstrapV5,
breakpointsElement,
breakpointsMasterCss,
breakpointsPrimeFlex,
breakpointsQuasar,
breakpointsSematic,
breakpointsTailwind,
breakpointsVuetify,
breakpointsVuetifyV2,
breakpointsVuetifyV3,
bypassFilter,
camelize,
clamp,
cloneFnJSON,
computedAsync,
computedEager,
computedInject,
computedWithControl,
containsProp,
controlledRef,
createEventHook,
createFetch,
createFilterWrapper,
createGlobalState,
createInjectionState,
createRef,
createReusableTemplate,
createSharedComposable,
createSingletonPromise,
createTemplatePromise,
createUnrefFn,
customStorageEventName,
debounceFilter,
defaultDocument,
defaultLocation,
defaultNavigator,
defaultWindow,
executeTransition,
extendRef,
formatDate,
formatTimeAgo,
get,
getLifeCycleTarget,
getSSRHandler,
hasOwn,
hyphenate,
identity,
increaseWithUnit,
injectLocal,
invoke,
isClient,
isDef,
isDefined,
isIOS,
isObject,
isWorker,
makeDestructurable,
mapGamepadToXbox360Controller,
noop,
normalizeDate,
notNullish,
now,
objectEntries,
objectOmit,
objectPick,
onClickOutside,
onElementRemoval,
onKeyDown,
onKeyPressed,
onKeyStroke,
onKeyUp,
onLongPress,
onStartTyping,
pausableFilter,
promiseTimeout,
provideLocal,
provideSSRWidth,
pxValue,
rand,
reactify,
reactifyObject,
reactiveComputed,
reactiveOmit,
reactivePick,
refAutoReset,
refDebounced,
refDefault,
refThrottled,
refWithControl,
resolveRef,
resolveUnref,
set,
setSSRHandler,
syncRef,
syncRefs,
templateRef,
throttleFilter,
timestamp,
toArray,
toReactive,
toRef,
toRefs,
toValue,
tryOnBeforeMount,
tryOnBeforeUnmount,
tryOnMounted,
tryOnScopeDispose,
tryOnUnmounted,
unrefElement,
until,
useActiveElement,
useAnimate,
useArrayDifference,
useArrayEvery,
useArrayFilter,
useArrayFind,
useArrayFindIndex,
useArrayFindLast,
useArrayIncludes,
useArrayJoin,
useArrayMap,
useArrayReduce,
useArraySome,
useArrayUnique,
useAsyncQueue,
useAsyncState,
useBase64,
useBattery,
useBluetooth,
useBreakpoints,
useBroadcastChannel,
useBrowserLocation,
useCached,
useClipboard,
useClipboardItems,
useCloned,
useColorMode,
useConfirmDialog,
useCountdown,
useCounter,
useCssVar,
useCurrentElement,
useCycleList,
useDark,
useDateFormat,
useDebounceFn,
useDebouncedRefHistory,
useDeviceMotion,
useDeviceOrientation,
useDevicePixelRatio,
useDevicesList,
useDisplayMedia,
useDocumentVisibility,
useDraggable,
useDropZone,
useElementBounding,
useElementByPoint,
useElementHover,
useElementSize,
useElementVisibility,
useEventBus,
useEventListener,
useEventSource,
useEyeDropper,
useFavicon,
useFetch,
useFileDialog,
useFileSystemAccess,
useFocus,
useFocusWithin,
useFps,
useFullscreen,
useGamepad,
useGeolocation,
useIdle,
useImage,
useInfiniteScroll,
useIntersectionObserver,
useInterval,
useIntervalFn,
useKeyModifier,
useLastChanged,
useLocalStorage,
useMagicKeys,
useManualRefHistory,
useMediaControls,
useMediaQuery,
useMemoize,
useMemory,
useMounted,
useMouse,
useMouseInElement,
useMousePressed,
useMutationObserver,
useNavigatorLanguage,
useNetwork,
useNow,
useObjectUrl,
useOffsetPagination,
useOnline,
usePageLeave,
useParallax,
useParentElement,
usePerformanceObserver,
usePermission,
usePointer,
usePointerLock,
usePointerSwipe,
usePreferredColorScheme,
usePreferredContrast,
usePreferredDark,
usePreferredLanguages,
usePreferredReducedMotion,
usePreferredReducedTransparency,
usePrevious,
useRafFn,
useRefHistory,
useResizeObserver,
useSSRWidth,
useScreenOrientation,
useScreenSafeArea,
useScriptTag,
useScroll,
useScrollLock,
useSessionStorage,
useShare,
useSorted,
useSpeechRecognition,
useSpeechSynthesis,
useStepper,
useStorage,
useStorageAsync,
useStyleTag,
useSupported,
useSwipe,
useTemplateRefsList,
useTextDirection,
useTextSelection,
useTextareaAutosize,
useThrottleFn,
useThrottledRefHistory,
useTimeAgo,
useTimeout,
useTimeoutFn,
useTimeoutPoll,
useTimestamp,
useTitle,
useToNumber,
useToString,
useToggle,
useTransition,
useUrlSearchParams,
useUserMedia,
useVModel,
useVModels,
useVibrate,
useVirtualList,
useWakeLock,
useWebNotification,
useWebSocket,
useWebWorker,
useWebWorkerFn,
useWindowFocus,
useWindowScroll,
useWindowSize,
watchArray,
watchAtMost,
watchDebounced,
watchDeep,
watchIgnorable,
watchImmediate,
watchOnce,
watchPausable,
watchThrottled,
watchTriggerable,
watchWithFilter,
whenever
} from "./chunk-RLEUDPPB.js";
import "./chunk-3S55Y3P7.js";
export {
DefaultMagicKeysAliasMap,
StorageSerializers,
TransitionPresets,
assert,
computedAsync as asyncComputed,
refAutoReset as autoResetRef,
breakpointsAntDesign,
breakpointsBootstrapV5,
breakpointsElement,
breakpointsMasterCss,
breakpointsPrimeFlex,
breakpointsQuasar,
breakpointsSematic,
breakpointsTailwind,
breakpointsVuetify,
breakpointsVuetifyV2,
breakpointsVuetifyV3,
bypassFilter,
camelize,
clamp,
cloneFnJSON,
computedAsync,
computedEager,
computedInject,
computedWithControl,
containsProp,
computedWithControl as controlledComputed,
controlledRef,
createEventHook,
createFetch,
createFilterWrapper,
createGlobalState,
createInjectionState,
reactify as createReactiveFn,
createRef,
createReusableTemplate,
createSharedComposable,
createSingletonPromise,
createTemplatePromise,
createUnrefFn,
customStorageEventName,
debounceFilter,
refDebounced as debouncedRef,
watchDebounced as debouncedWatch,
defaultDocument,
defaultLocation,
defaultNavigator,
defaultWindow,
computedEager as eagerComputed,
executeTransition,
extendRef,
formatDate,
formatTimeAgo,
get,
getLifeCycleTarget,
getSSRHandler,
hasOwn,
hyphenate,
identity,
watchIgnorable as ignorableWatch,
increaseWithUnit,
injectLocal,
invoke,
isClient,
isDef,
isDefined,
isIOS,
isObject,
isWorker,
makeDestructurable,
mapGamepadToXbox360Controller,
noop,
normalizeDate,
notNullish,
now,
objectEntries,
objectOmit,
objectPick,
onClickOutside,
onElementRemoval,
onKeyDown,
onKeyPressed,
onKeyStroke,
onKeyUp,
onLongPress,
onStartTyping,
pausableFilter,
watchPausable as pausableWatch,
promiseTimeout,
provideLocal,
provideSSRWidth,
pxValue,
rand,
reactify,
reactifyObject,
reactiveComputed,
reactiveOmit,
reactivePick,
refAutoReset,
refDebounced,
refDefault,
refThrottled,
refWithControl,
resolveRef,
resolveUnref,
set,
setSSRHandler,
syncRef,
syncRefs,
templateRef,
throttleFilter,
refThrottled as throttledRef,
watchThrottled as throttledWatch,
timestamp,
toArray,
toReactive,
toRef,
toRefs,
toValue,
tryOnBeforeMount,
tryOnBeforeUnmount,
tryOnMounted,
tryOnScopeDispose,
tryOnUnmounted,
unrefElement,
until,
useActiveElement,
useAnimate,
useArrayDifference,
useArrayEvery,
useArrayFilter,
useArrayFind,
useArrayFindIndex,
useArrayFindLast,
useArrayIncludes,
useArrayJoin,
useArrayMap,
useArrayReduce,
useArraySome,
useArrayUnique,
useAsyncQueue,
useAsyncState,
useBase64,
useBattery,
useBluetooth,
useBreakpoints,
useBroadcastChannel,
useBrowserLocation,
useCached,
useClipboard,
useClipboardItems,
useCloned,
useColorMode,
useConfirmDialog,
useCountdown,
useCounter,
useCssVar,
useCurrentElement,
useCycleList,
useDark,
useDateFormat,
refDebounced as useDebounce,
useDebounceFn,
useDebouncedRefHistory,
useDeviceMotion,
useDeviceOrientation,
useDevicePixelRatio,
useDevicesList,
useDisplayMedia,
useDocumentVisibility,
useDraggable,
useDropZone,
useElementBounding,
useElementByPoint,
useElementHover,
useElementSize,
useElementVisibility,
useEventBus,
useEventListener,
useEventSource,
useEyeDropper,
useFavicon,
useFetch,
useFileDialog,
useFileSystemAccess,
useFocus,
useFocusWithin,
useFps,
useFullscreen,
useGamepad,
useGeolocation,
useIdle,
useImage,
useInfiniteScroll,
useIntersectionObserver,
useInterval,
useIntervalFn,
useKeyModifier,
useLastChanged,
useLocalStorage,
useMagicKeys,
useManualRefHistory,
useMediaControls,
useMediaQuery,
useMemoize,
useMemory,
useMounted,
useMouse,
useMouseInElement,
useMousePressed,
useMutationObserver,
useNavigatorLanguage,
useNetwork,
useNow,
useObjectUrl,
useOffsetPagination,
useOnline,
usePageLeave,
useParallax,
useParentElement,
usePerformanceObserver,
usePermission,
usePointer,
usePointerLock,
usePointerSwipe,
usePreferredColorScheme,
usePreferredContrast,
usePreferredDark,
usePreferredLanguages,
usePreferredReducedMotion,
usePreferredReducedTransparency,
usePrevious,
useRafFn,
useRefHistory,
useResizeObserver,
useSSRWidth,
useScreenOrientation,
useScreenSafeArea,
useScriptTag,
useScroll,
useScrollLock,
useSessionStorage,
useShare,
useSorted,
useSpeechRecognition,
useSpeechSynthesis,
useStepper,
useStorage,
useStorageAsync,
useStyleTag,
useSupported,
useSwipe,
useTemplateRefsList,
useTextDirection,
useTextSelection,
useTextareaAutosize,
refThrottled as useThrottle,
useThrottleFn,
useThrottledRefHistory,
useTimeAgo,
useTimeout,
useTimeoutFn,
useTimeoutPoll,
useTimestamp,
useTitle,
useToNumber,
useToString,
useToggle,
useTransition,
useUrlSearchParams,
useUserMedia,
useVModel,
useVModels,
useVibrate,
useVirtualList,
useWakeLock,
useWebNotification,
useWebSocket,
useWebWorker,
useWebWorkerFn,
useWindowFocus,
useWindowScroll,
useWindowSize,
watchArray,
watchAtMost,
watchDebounced,
watchDeep,
watchIgnorable,
watchImmediate,
watchOnce,
watchPausable,
watchThrottled,
watchTriggerable,
watchWithFilter,
whenever
};
//# sourceMappingURL=vitepress___@vueuse_core.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

347
src/docs/.vitepress/cache/deps/vue.js vendored Normal file
View File

@@ -0,0 +1,347 @@
import {
BaseTransition,
BaseTransitionPropsValidators,
Comment,
DeprecationTypes,
EffectScope,
ErrorCodes,
ErrorTypeStrings,
Fragment,
KeepAlive,
ReactiveEffect,
Static,
Suspense,
Teleport,
Text,
TrackOpTypes,
Transition,
TransitionGroup,
TriggerOpTypes,
VueElement,
assertNumber,
callWithAsyncErrorHandling,
callWithErrorHandling,
camelize,
capitalize,
cloneVNode,
compatUtils,
compile,
computed,
createApp,
createBaseVNode,
createBlock,
createCommentVNode,
createElementBlock,
createHydrationRenderer,
createPropsRestProxy,
createRenderer,
createSSRApp,
createSlots,
createStaticVNode,
createTextVNode,
createVNode,
customRef,
defineAsyncComponent,
defineComponent,
defineCustomElement,
defineEmits,
defineExpose,
defineModel,
defineOptions,
defineProps,
defineSSRCustomElement,
defineSlots,
devtools,
effect,
effectScope,
getCurrentInstance,
getCurrentScope,
getCurrentWatcher,
getTransitionRawChildren,
guardReactiveProps,
h,
handleError,
hasInjectionContext,
hydrate,
hydrateOnIdle,
hydrateOnInteraction,
hydrateOnMediaQuery,
hydrateOnVisible,
initCustomFormatter,
initDirectivesForSSR,
inject,
isMemoSame,
isProxy,
isReactive,
isReadonly,
isRef,
isRuntimeOnly,
isShallow,
isVNode,
markRaw,
mergeDefaults,
mergeModels,
mergeProps,
nextTick,
nodeOps,
normalizeClass,
normalizeProps,
normalizeStyle,
onActivated,
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onDeactivated,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onScopeDispose,
onServerPrefetch,
onUnmounted,
onUpdated,
onWatcherCleanup,
openBlock,
patchProp,
popScopeId,
provide,
proxyRefs,
pushScopeId,
queuePostFlushCb,
reactive,
readonly,
ref,
registerRuntimeCompiler,
render,
renderList,
renderSlot,
resolveComponent,
resolveDirective,
resolveDynamicComponent,
resolveFilter,
resolveTransitionHooks,
setBlockTracking,
setDevtoolsHook,
setTransitionHooks,
shallowReactive,
shallowReadonly,
shallowRef,
ssrContextKey,
ssrUtils,
stop,
toDisplayString,
toHandlerKey,
toHandlers,
toRaw,
toRef,
toRefs,
toValue,
transformVNodeArgs,
triggerRef,
unref,
useAttrs,
useCssModule,
useCssVars,
useHost,
useId,
useModel,
useSSRContext,
useShadowRoot,
useSlots,
useTemplateRef,
useTransitionState,
vModelCheckbox,
vModelDynamic,
vModelRadio,
vModelSelect,
vModelText,
vShow,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
withAsyncContext,
withCtx,
withDefaults,
withDirectives,
withKeys,
withMemo,
withModifiers,
withScopeId
} from "./chunk-3S55Y3P7.js";
export {
BaseTransition,
BaseTransitionPropsValidators,
Comment,
DeprecationTypes,
EffectScope,
ErrorCodes,
ErrorTypeStrings,
Fragment,
KeepAlive,
ReactiveEffect,
Static,
Suspense,
Teleport,
Text,
TrackOpTypes,
Transition,
TransitionGroup,
TriggerOpTypes,
VueElement,
assertNumber,
callWithAsyncErrorHandling,
callWithErrorHandling,
camelize,
capitalize,
cloneVNode,
compatUtils,
compile,
computed,
createApp,
createBlock,
createCommentVNode,
createElementBlock,
createBaseVNode as createElementVNode,
createHydrationRenderer,
createPropsRestProxy,
createRenderer,
createSSRApp,
createSlots,
createStaticVNode,
createTextVNode,
createVNode,
customRef,
defineAsyncComponent,
defineComponent,
defineCustomElement,
defineEmits,
defineExpose,
defineModel,
defineOptions,
defineProps,
defineSSRCustomElement,
defineSlots,
devtools,
effect,
effectScope,
getCurrentInstance,
getCurrentScope,
getCurrentWatcher,
getTransitionRawChildren,
guardReactiveProps,
h,
handleError,
hasInjectionContext,
hydrate,
hydrateOnIdle,
hydrateOnInteraction,
hydrateOnMediaQuery,
hydrateOnVisible,
initCustomFormatter,
initDirectivesForSSR,
inject,
isMemoSame,
isProxy,
isReactive,
isReadonly,
isRef,
isRuntimeOnly,
isShallow,
isVNode,
markRaw,
mergeDefaults,
mergeModels,
mergeProps,
nextTick,
nodeOps,
normalizeClass,
normalizeProps,
normalizeStyle,
onActivated,
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onDeactivated,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onScopeDispose,
onServerPrefetch,
onUnmounted,
onUpdated,
onWatcherCleanup,
openBlock,
patchProp,
popScopeId,
provide,
proxyRefs,
pushScopeId,
queuePostFlushCb,
reactive,
readonly,
ref,
registerRuntimeCompiler,
render,
renderList,
renderSlot,
resolveComponent,
resolveDirective,
resolveDynamicComponent,
resolveFilter,
resolveTransitionHooks,
setBlockTracking,
setDevtoolsHook,
setTransitionHooks,
shallowReactive,
shallowReadonly,
shallowRef,
ssrContextKey,
ssrUtils,
stop,
toDisplayString,
toHandlerKey,
toHandlers,
toRaw,
toRef,
toRefs,
toValue,
transformVNodeArgs,
triggerRef,
unref,
useAttrs,
useCssModule,
useCssVars,
useHost,
useId,
useModel,
useSSRContext,
useShadowRoot,
useSlots,
useTemplateRef,
useTransitionState,
vModelCheckbox,
vModelDynamic,
vModelRadio,
vModelSelect,
vModelText,
vShow,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
withAsyncContext,
withCtx,
withDefaults,
withDirectives,
withKeys,
withMemo,
withModifiers,
withScopeId
};
//# sourceMappingURL=vue.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

View File

@@ -0,0 +1,70 @@
import { defineConfig } from 'vitepress'
const isDev = process.env.NODE_ENV === 'development'
export default defineConfig({
title: "SigPro",
description: "Minimalist Reactive Library",
outDir: '../../docs',
base: isDev ? '/absproxy/5174/sigpro/' : '/sigpro/',
// CONFIGURACIÓN DE VITE (Motor interno)
vite: {
outDir: '../../docs',
base: isDev ? '/absproxy/5174/sigpro/' : '/sigpro/',
server: {
allowedHosts: true,
port: 5174,
}
},
themeConfig: {
logo: '/logo.svg',
nav: [
{ text: 'Home', link: '/' },
{ text: 'Guide', link: '/guide/getting-started' },
{ text: 'Api', link: '/api/quick' },
],
sidebar: [
{
text: 'Introduction',
items: [
{ text: 'What is SigPro?', link: '/' },
{ text: 'Why', link: '/guide/why' },
{ text: 'Guide', link: '/guide/getting-started' },
]
},
{
text: 'API Reference',
items: [
{ text: 'Quick Start', link: '/api/quick' },
{ text: '$', link: '/api/$' },
{ text: '$.html', link: '/api/html' },
{ text: '$.mount', link: '/api/mount' },
{ text: 'Tags', link: '/api/tags' },
]
},
{
text: 'Plugins',
items: [
{ text: 'Quick Start', link: '/plugins/quick' },
{ text: '@core Router Plugin', link: '/plugins/core.router' },
{ text: '@core UI Plugin', link: '/plugins/core.ui' },
{ text: '@core UI Fetch', link: '/plugins/core.fetch' },
{ text: '@core UI Storage', link: '/plugins/core.storage' },
{ text: '@core UI Debug', link: '/plugins/core.debug' },
{ text: 'Custom', link: '/plugins/custom' },
]
},
{
text: 'Vite Router Plugin',
items: [
{ text: 'Vite Plugin', link: '/vite/plugin' },
]
}
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/natxocc/sigpro' }
]
}
})

101
src/docs/api/$.md Normal file
View File

@@ -0,0 +1,101 @@
# The Reactive Core: `$( )`
The `$` function is the heart of **SigPro**. It is a **Unified Reactive Constructor** that handles state, derivations, and side effects through a single, consistent interface.
## 1. The Constructor: `$( input )`
Depending on what you pass into `$( )`, SigPro creates a different type of reactive primitive:
| Input Type | Result | Internal Behavior |
| :--- | :--- | :--- |
| **Value** (String, Number, Object...) | **Signal** | Creates a piece of mutable state. |
| **Function** | **Computed / Effect** | Creates a derived value that tracks dependencies. |
---
## 2. Signal (State)
A **Signal** is a "box" that holds a value. It provides a getter/setter function to interact with that value.
* **When to use:** For data that changes over time (counters, user input, toggle states, API data).
* **Syntax:** `const $state = $(initialValue);`
### Example:
```javascript
const $name = $("Alice");
// Read the value (Getter)
console.log($name()); // "Alice"
// Update the value (Setter)
$name("Bob");
// Update based on previous value
$name(current => current + " Smith");
```
---
## 3. Computed (Derived State)
When you pass a **function** to `$( )` that **returns a value**, SigPro creates a **Computed Signal**. It automatically tracks which signals are used inside it and re-runs only when they change.
* **When to use:** For values that depend on other signals (totals, filtered lists, formatted strings).
* **Syntax:** `const $derived = $(() => logic);`
### Example:
```javascript
const $price = $(100);
const $qty = $(2);
// Automatically tracks $price and $qty
const $total = $(() => $price() * $qty());
console.log($total()); // 200
$qty(3); // $total updates to 300 automatically
```
---
## 4. Effects (Side Effects)
An **Effect** is a function passed to `$( )` that **does not return a value** (or returns `undefined`). SigPro treats this as a subscription that performs an action whenever its dependencies change.
* **When to use:** For DOM manipulations, logging, or syncing with external APIs (LocalStorage, Fetch).
* **Syntax:** `$(() => { action });`
### Example:
```javascript
const $theme = $("light");
// This effect runs every time $theme changes
$(() => {
document.body.className = $theme();
console.log("Theme updated to:", $theme());
});
$theme("dark"); // Logs: Theme updated to: dark
```
---
## 5. Summary Table: Usage Guide
| Primitive | Logic Type | Returns Value? | Typical Use Case |
| :--- | :--- | :--- | :--- |
| **Signal** | Static | Yes (Mutable) | `const $user = $("Guest")` |
| **Computed** | Read-only | Yes (Automatic) | `const $isLoggedIn = $(() => $user() !== "Guest")` |
| **Effect** | Imperative | No | `$(() => localStorage.setItem('user', $user()))` |
---
## 💡 Pro Tip: Naming Convention
In SigPro, we use the **`$` prefix** (e.g., `$count`) for variables that hold a reactive function. This makes it easy to distinguish between a standard variable and a reactive one at a glance:
```javascript
let count = 0; // Static
const $count = $(0); // Reactive (Function)
```

103
src/docs/api/html.md Normal file
View File

@@ -0,0 +1,103 @@
# Rendering Engine: `$.html`
The `$.html` function is the architect of your UI. It creates standard HTML elements and wires them directly to your signals without the need for a Virtual DOM.
## 1. Syntax: `$.html(tag, [props], [content])`
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **tag** | `string` | **Yes** | Any valid HTML5 tag (e.g., `'div'`, `'button'`, `'input'`). |
| **props** | `Object` | No | Attributes, event listeners, and reactive bindings. |
| **content** | `any` | No | Text, Nodes, Arrays, or Reactive Functions. |
### Example:
```javascript
const myButton = $.html('button', { class: 'btn-primary' }, 'Click me');
```
---
## 2. Global Tag Helpers
To avoid repetitive `$.html` calls, SigPro automatically exposes common tags to the global `window` object. This allows for a clean, declarative syntax.
```javascript
// Instead of $.html('div', ...), just use:
div({ id: 'wrapper' }, [
h1("Welcome"),
p("This is SigPro.")
]);
```
---
## 3. Handling Properties & Attributes
SigPro distinguishes between static attributes and reactive bindings using the **`$` prefix**.
### Static vs. Reactive Attributes
* **Static:** Applied once during creation.
* **Reactive (`$`):** Automatically updates the DOM when the signal changes.
| Property | Syntax | Result |
| :--- | :--- | :--- |
| **Attribute** | `{ id: 'main' }` | `id="main"` |
| **Event** | `{ onclick: fn }` | Adds an event listener. |
| **Reactive Attr** | `{ $class: $theme }` | Updates `class` whenever `$theme()` changes. |
| **Boolean Attr** | `{ $disabled: $isBusy }` | Toggles the `disabled` attribute automatically. |
---
## 4. Two-Way Data Binding
For form inputs, SigPro provides a powerful shortcut using `$value` or `$checked`. It automatically handles the event listening and the value synchronization.
```javascript
const $text = $("Type here...");
input({
type: 'text',
$value: $text // Syncs input -> signal and signal -> input
});
p(["You typed: ", $text]);
```
---
## 5. Reactive Content (Dynamic Children)
The `content` argument is incredibly flexible. If you pass a **function**, SigPro treats it as a reactive "portal" that re-renders only that specific part of the DOM.
### Text & Nodes
```javascript
const $count = $(0);
// Text node updates surgically
div(["Count: ", $count]);
// Conditional rendering with a function
div(() => {
return $count() > 10
? h1("High Score!")
: p("Keep going...");
});
```
### The "Guillotine" (Performance Tip)
When a reactive function in the content returns a **new Node**, SigPro uses `replaceWith()` to swap the old node for the new one. This ensures that:
1. The update is nearly instantaneous.
2. The old node is correctly garbage-collected.
---
## 6. Summary: Content Types
| Input | Behavior |
| :--- | :--- |
| **String / Number** | Appended as a TextNode. |
| **HTMLElement** | Appended directly to the parent. |
| **Array** | Each item is processed and appended in order. |
| **Function `() => ...`** | Creates a **live reactive zone** that updates automatically. |

108
src/docs/api/mount.md Normal file
View File

@@ -0,0 +1,108 @@
# Application Mounter: `$.mount`
The `$.mount` function is the entry point of your reactive world. It takes a **SigPro component** (or a plain DOM node) and injects it into the real document.
## 1. Syntax: `$.mount(node, [target])`
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| **node** | `HTMLElement` or `Function` | **Required** | The component or element to render. |
| **target** | `string` or `HTMLElement` | `document.body` | Where to mount the app (CSS selector or Element). |
---
## 2. Usage Scenarios
### A. The "Clean Slate" (Main Entry)
In a modern app (like our `main.js` example), you usually want to control the entire page. By default, `$.mount` clears the target's existing HTML before mounting.
```javascript
// src/main.js
import { $ } from 'SigPro';
import App from './App.js';
$.mount(App); // Mounts to <body> by default
```
### B. Targeting a Specific Container
If you have an existing HTML structure and only want **SigPro** to manage a specific part (like a `#root` div), pass a CSS selector or a reference.
```html
<div id="sidebar"></div>
<div id="app-root"></div>
```
```javascript
// Local mount to a specific ID
$.mount(MyComponent, '#app-root');
// Or using a direct DOM reference
const sidebar = document.getElementById('sidebar');
$.mount(SidebarComponent, sidebar);
```
---
## 3. Mounting with Pure HTML
One of SigPro's strengths is that it works perfectly alongside "Old School" HTML. You can create a reactive "island" inside a static page.
```javascript
// A small reactive widget in a static .js file
const CounterWidget = () => {
const $c = $(0);
return button({ onclick: () => $c(v => v + 1) }, [
"Clicks: ", $c
]);
};
// Mount it into an existing div in your HTML
$.mount(CounterWidget, '#counter-container');
```
---
## 4. How it Works (The "Wipe" Logic)
When `$.mount` is called, it performs two critical steps:
1. **Clearance:** It sets `target.innerHTML = ''`. This ensures no "zombie" HTML from previous renders or static placeholders interferes with your app.
2. **Injection:** It appends your component. If you passed a **Function**, it executes it first to get the DOM node.
---
## 5. Global vs. Local Scope
### Global (The "Framework" Way)
In a standard Vite/ESM project, you initialize SigPro globally in `main.js`. This makes the `$` and the tag helpers (`div`, `button`, etc.) available everywhere in your project.
```javascript
// main.js - Global Initialization
import 'SigPro';
// Now any other file can just use:
$.mount(() => h1("Global App"));
```
### Local (The "Library" Way)
If you are worried about polluting the global `window` object, you can import and use SigPro locally within a specific module.
```javascript
// widget.js - Local usage
import { $ } from 'SigPro';
const myNode = $.html('div', 'Local Widget');
$.mount(myNode, '#widget-target');
```
---
### Summary Cheat Sheet
| Goal | Code |
| :--- | :--- |
| **Mount to body** | `$.mount(App)` |
| **Mount to ID** | `$.mount(App, '#id')` |
| **Mount to Element** | `$.mount(App, myElement)` |
| **Reactive Widget** | `$.mount(() => div("Hi"), '#widget')` |

99
src/docs/api/quick.md Normal file
View File

@@ -0,0 +1,99 @@
# Quick API Reference ⚡
This is a high-level summary of the **SigPro** core API. For detailed guides and edge cases, please refer to the specific documentation for each module.
## 1. Core Reactivity: `$( )`
The `$` function is a polymorphic constructor. It creates **Signals** (state) or **Computed Effects** (logic) based on the input type.
| Usage | Input Type | Returns | Description |
| :--- | :--- | :--- | :--- |
| **Signal** | `any` | `Function` | A getter/setter for reactive state. |
| **Computed** | `Function` | `Function` | A read-only signal that auto-updates when its dependencies change. |
**Example:**
```javascript
const $count = $(0); // Signal
const $double = $(() => $count() * 2); // Computed
```
---
## 2. Rendering Engine: `$.html`
SigPro uses a hyperscript-style engine to create live DOM nodes.
| Argument | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **tag** | `string` | Yes | Standard HTML tag (e.g., 'div', 'button'). |
| **props** | `Object` | No | Attributes (`id`), Events (`onclick`), or Reactive Props (`$value`). |
| **content** | `any` | No | String, Node, Array, or Reactive Function. |
**Example:**
```javascript
$.html('button', { onclick: () => alert('Hi!') }, 'Click Me');
```
---
## 3. Global Helpers (Tag Proxies)
To keep your code clean, SigPro automatically exposes common HTML tags to the global scope.
| Category | Available Tags |
| :--- | :--- |
| **Layout** | `div`, `section`, `main`, `nav`, `header`, `footer`, `span` |
| **Typography** | `h1`, `h2`, `h3`, `p`, `label`, `a`, `li`, `ul`, `ol` |
| **Forms** | `input`, `button`, `form`, `select`, `option` |
| **Media** | `img`, `video`, `audio`, `canvas` |
**Example:**
```javascript
// No imports needed!
div([
h1("Title"),
button("Ok")
]);
```
---
## 4. Mounting & Plugins
Methods to initialize your application and extend the engine.
| Method | Signature | Description |
| :--- | :--- | :--- |
| **`$.mount`** | `(node, target)` | Wipes the target (default: `body`) and renders the component. |
| **`$.plugin`** | `(source)` | Registers a function or loads external `.js` scripts as plugins. |
**Example:**
```javascript
$.plugin([UI, Router]);
$.mount(App, '#root');
```
---
## 5. Reactive Syntax Cheat Sheet
| Feature | Syntax | Description |
| :--- | :--- | :--- |
| **Text Binding** | `p(["Value: ", $sig])` | Updates text content automatically. |
| **Attributes** | `div({ id: $sig })` | Static attribute assignment. |
| **Reactive Attr** | `div({ $class: $sig })` | Attribute updates when `$sig` changes. |
| **Two-way Binding**| `input({ $value: $sig })`| Syncs input value and signal automatically. |
| **Conditional** | `div(() => $sig() > 0 ? "Yes" : "No")` | Re-renders only the content when the condition changes. |
---
## Summary Table
| Feature | SigPro Approach | Benefit |
| :--- | :--- | :--- |
| **Update Logic** | Fine-grained (Surgical) | Blazing fast updates. |
| **DOM** | Native Nodes | Zero abstraction cost. |
| **Syntax** | Pure JavaScript | No build-tool lock-in. |
| **Footprint** | Modular | Load only what you use. |

160
src/docs/api/tags.md Normal file
View File

@@ -0,0 +1,160 @@
# Global Tag Helpers
In **SigPro**, you don't need to write `$.html('div', ...)` every time. To keep your code clean and readable, the engine automatically generates global helper functions for all standard HTML tags.
## 1. How it Works
When SigPro initializes, it runs a proxy loop that creates a function for every common HTML tag and attaches it to the `window` object.
* **Traditional:** `$.html('button', { onclick: ... }, 'Click')`
* **SigPro Style:** `button({ onclick: ... }, 'Click')`
This approach gives you a "DSL" (Domain Specific Language) that feels like HTML but is actually **pure JavaScript**.
---
## 2. The Global Registry
The following tags are available globally by default:
| Category | Available Functions |
| :--- | :--- |
| **Layout** | `div`, `span`, `section`, `main`, `nav`, `header`, `footer`, `article`, `aside` |
| **Typography** | `h1`, `h2`, `h3`, `p`, `ul`, `ol`, `li`, `a`, `label`, `strong`, `em` |
| **Forms** | `form`, `input`, `button`, `select`, `option`, `textarea` |
| **Table** | `table`, `thead`, `tbody`, `tr`, `th`, `td` |
| **Media** | `img`, `video`, `audio`, `canvas`, `svg` |
---
## 3. Usage Patterns
The tag functions are highly flexible and accept arguments in different orders to suit your coding style.
### A. Attributes + Content
The most common pattern.
```javascript
div({ class: 'card' }, [
h1("Title"),
p("Description")
]);
```
### B. Content Only
If you don't need attributes, you can skip the object entirely.
```javascript
div([
h1("Just Content"),
p("No attributes object needed here.")
]);
```
### C. Simple Text
For elements that only contain a string.
```javascript
button("Submit"); // Equivalent to <button>Submit</button>
```
---
## 4. Reactive Tags
Since these helpers are just wrappers around `$.html`, they support full reactivity out of the box.
```javascript
const $loading = $(true);
div([
$loading() ? span("Loading...") : h1("Data Ready!"),
button({
$disabled: $loading, // Reactive attribute
onclick: () => $loading(false)
}, "Stop Loading")
]);
```
---
## 5. Under the Hood
If you are curious about how this happens without a compiler, here is the logic inside the SigPro core:
```javascript
const tags = ['div', 'span', 'p', 'button', ...];
tags.forEach(tag => {
window[tag] = (props, content) => $.html(tag, props, content);
});
```
Because these are attached to `window`, they are available in any file in your project as soon as SigPro is loaded, making your components look like this:
```javascript
// No imports required for tags!
export default () =>
section({ id: 'hero' }, [
h1("Fast. Atomic. Simple."),
p("Built with SigPro.")
]);
```
---
## 6. Full Comparison: SigPro vs. Standard HTML
To better understand the translation, here is a complete example of a **User Card** component. Notice how **SigPro** attributes with the `$` prefix map to reactive behavior, while standard attributes remain static.
::: code-group
```javascript [SigPro (JS)]
const $online = $(true);
export const UserCard = () => (
div({ class: 'user-card' }, [
img({ src: 'avatar.png', alt: 'User' }),
div({ class: 'info' }, [
h2("John Doe"),
p({
$class: () => $online() ? 'status-on' : 'status-off'
}, [
"Status: ",
() => $online() ? "Online" : "Offline"
])
]),
button({
onclick: () => $online(!$online())
}, "Toggle Status")
])
);
```
```html [Equivalent HTML Structure]
<div class="user-card">
<img src="avatar.png" alt="User">
<div class="info">
<h2>John Doe</h2>
<p class="status-on">
Status: Online
</p>
</div>
<button>Toggle Status</button>
</div>
```
:::
### What is happening here?
1. **Structure:** The hierarchy is identical. `div([...])` in JS translates directly to nested tags in HTML.
2. **Attributes:** `class` is set once. `$class` is "live"; SigPro listens to the `$online` signal and updates the class name without re-rendering the whole card.
3. **Content:** The array `[...]` in SigPro is the equivalent of the children inside an HTML tag.
4. **Reactivity:** The function `() => $online() ? ...` creates a **TextNode** in the HTML that changes its text content surgically whenever the signal toggles.
---
## 💡 Best Practices
1. **Destructuring:** If you prefer not to rely on global variables, you can destructure them from `window` or `$` (though in SigPro, using them globally is the intended "clean" way).
2. **Custom Tags:** If you need a tag that isn't in the default list (like a Web Component), you can still use the base engine: `$.html('my-custom-element', { ... })`.

View File

@@ -0,0 +1,76 @@
# Getting Started
**SigPro** is a lightweight, atomic reactive engine designed to build modern web interfaces with zero overhead. It focuses on high performance through fine-grained reactivity.
## 1. Installation
You can install SigPro via your favorite package manager:
::: code-group
```bash [npm]
npm install SigPro
````
```bash [pnpm]
pnpm add SigPro
```
```bash [yarn]
yarn add SigPro
```
```bash [bun]
bun add SigPro
```
:::
## 2\. Basic Usage
The core of SigPro is the `$` function, which creates reactive state (Signals) and computed effects.
Create a `main.js` file and try this:
```javascript
import { $ } from 'SigPro';
// 1. Create a reactive signal
const $name = $("World");
// 2. Define a reactive component
const App = () => div({ class: 'container' }, [
h1(["Hello, ", $name, "!"]),
input({
type: 'text',
$value: $name, // Two-way binding
placeholder: 'Enter your name...'
}),
button({
onclick: () => $name("SigPro")
}, "Set to SigPro")
]);
// 3. Mount the application
$.mount(App, '#app');
```
## 3\. How it Works
SigPro doesn't use a Virtual DOM. Instead, it creates real DOM nodes and binds them directly to your data:
1. **Signals**: `$(value)` creates a getter/setter function.
2. **Reactivity**: When you pass a signal or a function to a DOM element, SigPro automatically creates a subscription.
3. **Fine-Grained Updates**: Only the specific text node or attribute linked to the signal updates when the value changes.
## 4\. Global Tags
By default, SigPro exports common HTML tags to the global scope (`window`) when initialized. This allows you to write clean, declarative UI without importing every single tag:
```javascript
// Instead of $.html('div', ...), just use:
div([
h1("Clean Syntax"),
p("No more boilerplate.")
]);
```

78
src/docs/guide/why.md Normal file
View File

@@ -0,0 +1,78 @@
# Why SigPro?
After years of building applications with React, Vue, and Svelte—investing countless hours mastering unique mental models, proprietary syntaxes, and complex build tools—we reached a realization: the web platform has evolved, but frameworks have become layers of abstraction that often move us further away from the browser.
**SigPro** is the answer to a simple question: **Why fight the platform when we can embrace it?**
## The Modern Web is Ready
SigPro bypasses the overhead of the Virtual DOM and heavy compilers by using modern browser primitives. It treats the DOM as a first-class citizen, not as a side effect of a state change.
| Browser Primitive | What It Enables |
| :--- | :--- |
| **Closures & Proxies** | Automatic dependency tracking without heavy overhead. |
| **ES Modules** | Native modularity and lazy loading without complex bundlers. |
| **Direct DOM APIs** | Surgical updates that are faster than any reconciliation algorithm. |
| **Microtask Queues** | Batching updates efficiently to ensure 60fps performance. |
---
## The SigPro Philosophy
SigPro strips away the complexity, delivering a reactive programming model that feels like a framework but stays remarkably close to Vanilla JS:
* **No JSX transformations** Pure JavaScript functions.
* **No Virtual DOM** Direct, fine-grained DOM manipulation.
* **No proprietary syntax** If you know JS, you know SigPro.
* **Zero Build Step Required** It can run directly in the browser via ESM.
```javascript
// Pure, Atomic, Reactive.
const $count = $(0);
const Counter = () => div([
p(["Count: ", $count]),
button({ onclick: () => $count(c => c + 1) }, "Increment")
]);
```
---
## Performance Comparison
SigPro isn't just lighter; it's architecturally faster because it skips the "diffing" phase entirely.
| Metric | SigPro | SolidJS | Svelte | Vue | React |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Bundle Size (gzip)** | 🥇 **< 2KB** | 🥈 7KB | 🥉 16KB | 20KB | 45KB |
| **Architecture** | **Atomic** | **Atomic** | **Compiled** | **V-DOM** | **V-DOM** |
| **Initial Render** | 🥇 **Fastest** | 🥈 Fast | 🥉 Fast | Average | Slow |
| **Update Perf** | 🥇 **Surgical** | 🥇 Surgical | 🥈 Fast | 🥉 Average | Slow |
| **Dependencies** | 🥇 **0** | 🥇 0 | 🥇 0 | 🥈 2 | 🥉 5+ |
| **Build Step** | 🥇 **Optional** | 🥈 Required | 🥈 Required | 🥇 Optional | 🥈 Required |
---
## 🔑 Core Principles
SigPro is built on four fundamental pillars:
### 📡 Atomic Reactivity
Automatic dependency tracking with no manual subscriptions. When a signal changes, only the **exact** text nodes or attributes that depend on it update—instantly and surgically.
### ⚡ Surgical DOM Updates
No Virtual DOM diffing. No tree reconciliation. We don't guess what changed; we know exactly where the update needs to happen. Performance scales with your data, not the size of your component tree.
### 🧩 Plugin-First Architecture
The core is a tiny, powerful engine. Need Routing? Fetching? Global UI? Just plug it in. This keeps your production bundles "pay-only-for-what-you-use."
### 🔬 Predictable & Transparent
There is no "magic" hidden in a black-box compiler. What you write is what the browser executes. Debugging is straightforward because there is no framework layer between your code and the DevTools.
---
> "SigPro returns the joy of web development by making the browser the hero again."

96
src/docs/index.md Normal file
View File

@@ -0,0 +1,96 @@
---
layout: home
hero:
name: SigPro
text: Atomic Unified Reactive Engine
tagline: Fine-grained reactivity, built-in routing, and modular plugins. All under 2KB.
image:
src: /logo.png
alt: SigPro Logo
actions:
- theme: brand
text: Get Started
link: /guide/getting-started
- theme: alt
text: View on GitHub
link: https://git.natxocc.com/sigpro/
features:
- title: Atomic Reactivity
details: Powered by Signals. Only updates what changes. No Virtual DOM overhead, no heavy re-renders.
- title: Zero Dependencies
details: Written in pure Vanilla JS. Maximum performance with the smallest footprint possible.
- title: Modular Ecosystem
details: Official plugins for UI components, dynamic Routing, Fetch, and Storage. Load only what you need.
---
## Why SigPro?
SigPro isn't just another framework; it's a high-performance engine. It strips away the complexity of massive bundles and returns to the essence of the web, enhanced with reactive superpowers.
### The Core in Action
```javascript
import { $ } from 'sigpro2';
// A reactive state Signal
const $count = $(0);
// A Computed signal that updates automatically
const $double = $(() => $count() * 2);
// UI that breathes with your data
const Counter = () => div([
h1(["Count: ", $count]),
p(["Double: ", $double]),
button({ onclick: () => $count(c => c + 1) }, "Increment")
]);
$.mount(Counter);
```
---
### Key Features
#### ⚡️ Fine-Grained Reactivity
Unlike frameworks that diff complex trees (V-DOM), SigPro binds your signals directly to real DOM text nodes and attributes. If the data changes, the node changes. Period.
#### 🔌 Polymorphic Plugin System
Extend core capabilities in a single line. Add global UI helpers, routing, or state persistence seamlessly.
```javascript
import { UI, Router } from 'sigpro/plugins';
$.plugin([UI, Router]);
```
#### 📂 File-Based Routing
With our dedicated Vite plugin, manage your routes simply by creating files in `src/pages/`. It supports native **Lazy Loading** out of the box for lightning-fast initial loads.
---
### Quick Install
::: code-group
```bash [npm]
npm install sigpro
```
```bash [pnpm]
pnpm add sigpro
```
```bash [yarn]
yarn add sigpro
```
```bash [bun]
bun add sigpro
```
:::
---
## Community & Support
SigPro is an open-source project. Whether you want to contribute, report a bug, or just talk about reactivity, join us on our official repository.
```
Built with ❤️ by NatxoCC
```

118
src/docs/logo.svg Normal file
View File

@@ -0,0 +1,118 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="600.000000pt" height="591.000000pt" viewBox="0 0 600.000000 591.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,591.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1130 3454 c-44 -9 -84 -27 -123 -57 -97 -76 -91 -242 12 -310 34
-23 60 -32 193 -71 58 -17 78 -36 78 -74 0 -28 -24 -44 -74 -49 -65 -8 -137
20 -181 68 l-36 40 -27 -33 c-15 -18 -37 -43 -50 -56 -26 -27 -20 -40 35 -86
65 -55 118 -71 233 -71 89 1 112 4 152 24 94 46 137 146 108 252 -20 71 -81
112 -224 152 -124 35 -150 64 -101 112 42 43 147 25 203 -35 18 -20 19 -19 70
30 47 45 51 53 40 69 -22 31 -71 67 -108 80 -39 13 -161 22 -200 15z m193 -36
c56 -23 97 -54 97 -73 0 -7 -17 -27 -37 -44 -36 -30 -37 -31 -57 -13 -12 10
-34 24 -51 31 -34 14 -148 24 -140 11 2 -4 -4 -10 -15 -13 -32 -8 -43 -52 -24
-93 9 -19 19 -32 22 -30 2 3 17 -1 33 -9 15 -8 39 -15 54 -15 14 0 25 -5 25
-11 0 -6 9 -8 20 -4 11 4 20 2 20 -4 0 -6 9 -11 21 -11 37 0 114 -59 133 -103
24 -55 15 -138 -18 -182 -28 -37 -101 -79 -123 -71 -9 4 -11 1 -7 -5 5 -8 -22
-10 -94 -7 -85 3 -106 7 -131 26 -17 12 -37 22 -46 22 -8 0 -15 3 -15 8 0 4
-10 12 -22 17 -41 19 -44 40 -12 77 17 19 37 32 45 30 27 -9 69 -44 64 -53 -4
-5 2 -6 11 -2 11 4 15 3 11 -4 -5 -7 1 -9 15 -5 12 3 19 1 15 -4 -3 -6 25 -11
68 -13 69 -2 77 0 100 23 14 14 31 26 38 27 9 0 9 2 0 6 -7 2 -13 16 -13 29 0
33 -38 66 -91 81 -24 6 -71 18 -104 27 -32 9 -63 23 -68 31 -4 8 -12 13 -17
10 -4 -3 -23 13 -40 36 -28 34 -33 48 -33 97 0 60 35 138 56 125 5 -3 7 -1 3
5 -8 13 2 20 69 49 68 30 168 31 238 1z"/>
<path d="M1031 3144 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M945 2900 c-6 -9 11 -50 21 -50 2 0 0 9 -6 20 -6 11 -8 25 -5 30 3 6
4 10 1 10 -3 0 -8 -4 -11 -10z"/>
<path d="M2428 3445 c-154 -39 -259 -173 -261 -333 -2 -111 21 -177 86 -248
77 -85 134 -108 267 -108 86 -1 113 3 151 20 114 53 169 139 177 276 l5 88
-167 0 -166 0 0 -66 0 -65 85 3 c74 3 85 1 85 -14 0 -27 -48 -76 -87 -89 -49
-16 -133 -6 -176 22 -40 27 -82 89 -91 137 -8 44 10 119 37 159 64 94 220 110
304 31 l23 -22 56 56 56 56 -43 32 c-44 32 -97 59 -131 65 -65 13 -159 13
-210 0z m202 -16 c8 -2 17 -7 20 -10 3 -3 21 -10 40 -15 19 -5 35 -15 35 -21
0 -6 4 -15 9 -20 5 -5 6 -3 2 5 -4 6 -3 12 3 12 6 0 15 -9 22 -21 9 -17 7 -24
-10 -40 -11 -10 -24 -27 -30 -36 -9 -17 -13 -16 -59 9 -62 34 -139 53 -157 38
-8 -6 -29 -12 -48 -13 -19 -1 -33 -5 -30 -9 2 -5 -3 -8 -12 -8 -9 0 -14 -4
-10 -9 3 -5 -4 -12 -15 -16 -11 -3 -20 -13 -20 -22 0 -14 -2 -14 -19 1 -13 12
-21 14 -26 6 -3 -6 -1 -9 6 -8 6 2 14 -3 17 -11 2 -8 0 -11 -6 -7 -6 4 -8 -1
-5 -13 3 -10 0 -22 -6 -25 -13 -9 -15 -129 -2 -173 12 -42 76 -107 125 -127
78 -32 198 -9 226 43 5 11 17 27 26 35 10 11 11 16 3 16 -7 0 -9 3 -6 7 4 3 2
12 -4 20 -8 8 -35 13 -79 13 l-68 0 -3 44 -4 44 124 1 c69 1 129 5 134 8 6 4
7 1 2 -7 -6 -9 -4 -12 6 -8 10 4 14 -4 14 -31 0 -20 -4 -42 -9 -50 -6 -10 -6
-12 3 -7 8 6 10 -4 5 -36 -7 -45 -72 -142 -110 -162 -10 -6 -21 -14 -24 -17
-21 -27 -213 -47 -265 -27 -75 28 -115 50 -110 58 3 6 0 7 -8 4 -14 -5 -87 72
-87 92 0 5 5 2 10 -6 7 -12 9 -10 8 7 -1 11 -7 19 -14 16 -12 -4 -27 34 -28
74 -1 12 -4 25 -8 29 -12 11 -10 64 2 64 6 0 10 5 10 11 0 5 -5 7 -11 3 -8 -5
-8 -1 0 14 6 11 11 34 11 51 0 17 4 31 9 31 8 0 24 35 23 50 0 3 19 28 44 55
25 29 42 41 38 30 l-6 -20 13 20 c6 11 13 21 15 23 1 2 32 13 68 26 62 20 174
28 226 15z"/>
<path d="M4670 3451 c-19 -4 -56 -18 -82 -31 -145 -72 -217 -236 -178 -409 14
-64 64 -147 106 -179 16 -12 34 -26 41 -32 6 -5 39 -18 72 -30 114 -38 243
-22 338 44 205 141 184 489 -37 606 -64 33 -178 47 -260 31z m177 -22 c23 -6
40 -16 37 -21 -4 -6 2 -7 15 -3 14 4 23 2 27 -9 3 -9 12 -12 21 -9 11 4 14 2
9 -5 -4 -7 -1 -12 8 -12 21 0 85 -89 86 -117 0 -13 4 -23 8 -23 16 0 30 -74
26 -130 -7 -100 -11 -119 -24 -135 -7 -8 -9 -15 -6 -15 10 0 -52 -85 -78 -107
-20 -16 -50 -32 -116 -61 -31 -14 -161 -10 -219 7 -24 7 -61 23 -81 36 -48 30
-114 110 -104 126 5 8 3 9 -6 4 -10 -6 -12 -3 -8 13 4 12 2 22 -2 22 -4 0 -11
27 -15 60 -8 71 2 143 18 134 8 -5 7 -2 0 7 -16 16 -17 33 -1 23 6 -4 8 -3 5
3 -10 16 13 74 26 66 6 -3 7 -1 3 6 -9 14 57 82 106 108 73 40 189 54 265 32z"/>
<path d="M4676 3307 c-22 -10 -47 -28 -57 -40 -10 -12 -18 -18 -19 -14 0 4 -6
2 -14 -5 -7 -7 -11 -19 -8 -27 3 -8 1 -12 -5 -8 -11 7 -16 -28 -16 -113 0 -74
6 -109 17 -102 5 3 7 -2 3 -11 -4 -10 -2 -16 6 -14 7 1 11 -4 9 -11 -1 -8 2
-11 8 -7 5 3 10 -1 10 -10 0 -8 16 -23 35 -32 19 -9 33 -19 31 -22 -2 -3 27
-6 64 -6 37 0 66 4 63 8 -3 5 1 7 8 6 23 -4 65 18 87 45 11 14 25 26 32 26 6
0 10 6 8 12 -3 7 1 18 7 25 15 15 16 195 2 186 -5 -3 -8 0 -5 7 5 15 -62 84
-102 105 -45 23 -118 24 -164 2z m164 -26 c19 -10 49 -37 65 -60 27 -39 30
-50 30 -119 0 -65 -4 -83 -25 -114 -36 -53 -85 -78 -156 -78 -68 0 -107 20
-149 74 -40 52 -46 146 -15 210 49 102 149 137 250 87z"/>
<path d="M1619 3443 c0 -2 0 -33 -1 -70 l0 -68 58 1 59 0 -2 -205 -2 -205 -58
3 -58 2 0 -70 0 -71 203 0 202 0 0 70 0 70 -77 -1 c-43 -1 -68 -4 -55 -6 12
-2 22 -7 22 -11 0 -4 19 -7 42 -7 l43 0 3 -48 3 -48 -165 3 c-92 2 -166 -1
-166 -5 0 -4 -9 -3 -21 3 -16 9 -19 19 -17 53 l3 41 47 1 c76 2 76 -1 76 223
1 109 -3 203 -7 211 -5 8 -29 14 -57 15 -32 1 -49 5 -48 14 1 6 2 28 3 47 l1
35 176 0 176 0 -4 -47 -3 -48 -42 -1 c-73 -1 -73 -2 -72 -220 1 -107 5 -194
10 -194 5 0 9 90 9 199 l0 199 60 -5 61 -6 -3 72 -3 72 -198 2 c-108 1 -197 1
-198 0z"/>
<path d="M3018 3102 l-3 -342 85 0 85 0 0 112 0 113 105 5 c113 6 145 17 192
67 57 60 76 188 39 261 -26 51 -77 99 -118 113 -19 6 -112 12 -208 12 l-175 2
-2 -343z m375 307 c20 -5 37 -14 37 -19 0 -6 6 -10 14 -10 8 0 18 -5 22 -12 5
-7 3 -8 -6 -3 -9 5 -11 4 -6 -3 4 -7 13 -12 19 -12 7 0 20 -20 30 -45 23 -54
19 -135 -8 -197 -4 -10 -11 -15 -16 -12 -5 3 -6 -2 -3 -10 4 -10 -10 -24 -43
-43 -53 -31 -55 -32 -167 -38 -107 -5 -112 -12 -106 -131 4 -83 3 -94 -12 -98
-10 -2 -18 -1 -18 3 0 3 -20 5 -45 3 l-45 -4 0 321 0 321 158 0 c86 0 174 -5
195 -11z"/>
<path d="M3187 3308 c-27 -20 -34 -173 -9 -183 26 -10 151 -11 144 -1 -3 5 5
7 16 4 12 -4 20 -3 18 1 -3 4 4 15 15 24 29 25 26 100 -5 134 -20 21 -35 26
-92 30 -50 3 -74 1 -87 -9z m157 -29 c32 -25 36 -84 7 -120 -16 -20 -30 -24
-93 -27 l-74 -4 0 86 1 86 66 0 c52 0 72 -4 93 -21z"/>
<path d="M3710 3103 l0 -343 83 0 82 0 -3 120 -3 120 45 0 c44 0 45 -1 79 -57
19 -32 49 -86 67 -120 l32 -62 95 -3 c52 -2 97 -1 99 1 7 7 -18 31 -27 25 -5
-3 -7 1 -4 8 3 7 -22 59 -55 116 -60 103 -68 122 -51 122 16 0 86 80 98 112
39 108 -9 228 -110 277 -37 18 -65 21 -235 23 l-192 3 0 -342z m385 313 c26
-5 74 -37 71 -49 -1 -6 -1 -9 1 -4 18 31 73 -77 73 -143 0 -56 -36 -127 -78
-155 -17 -11 -35 -30 -41 -42 -9 -19 -6 -27 14 -47 14 -14 25 -32 25 -41 0 -8
5 -15 11 -15 6 0 8 -9 4 -20 -4 -13 -2 -19 4 -18 12 3 68 -88 60 -96 -4 -4
-77 -7 -120 -5 -17 0 -54 64 -52 87 0 7 -1 11 -5 8 -6 -7 -32 41 -32 61 0 8
-4 12 -8 9 -4 -3 -17 11 -27 31 -21 38 -55 58 -67 39 -6 -8 -10 -8 -16 1 -6 9
-13 9 -32 0 -27 -14 -27 -12 -29 -150 l-1 -88 -57 2 -58 2 3 316 c2 235 6 317
15 323 10 6 301 1 342 -6z"/>
<path d="M3886 3328 c3 -4 -1 -8 -9 -8 -22 0 -37 -128 -21 -187 6 -22 11 -23
101 -23 91 0 96 1 124 29 41 41 43 113 5 146 -51 44 -67 55 -79 55 -8 0 -7 -4
3 -10 11 -7 -4 -10 -48 -10 -35 0 -61 4 -58 8 3 5 -1 9 -9 9 -8 0 -12 -4 -9
-9z m180 -49 c43 -43 31 -133 -19 -143 -12 -3 -57 -7 -99 -8 l-78 -3 0 93 0
94 85 -3 c75 -4 87 -7 111 -30z"/>
<path d="M4167 3099 c7 -7 15 -10 18 -7 3 3 -2 9 -12 12 -14 6 -15 5 -6 -5z"/>
<path d="M3986 3017 c3 -10 9 -15 12 -12 3 3 0 11 -7 18 -10 9 -11 8 -5 -6z"/>
<path d="M1643 2830 c0 -25 2 -35 4 -22 2 12 2 32 0 45 -2 12 -4 2 -4 -23z"/>
<path d="M2923 2373 c13 -4 17 -15 17 -59 0 -60 -16 -77 -51 -55 -11 6 -19 7
-19 2 0 -6 6 -13 13 -18 45 -28 81 10 75 82 -2 33 1 46 12 49 8 2 -3 4 -25 4
-22 0 -32 -2 -22 -5z"/>
<path d="M3072 2368 c-24 -24 -13 -49 28 -65 27 -11 40 -22 38 -32 -4 -20 -44
-27 -64 -10 -8 6 -17 9 -20 6 -3 -3 5 -12 18 -21 37 -24 87 -7 88 30 0 15 -19
29 -55 41 -34 11 -39 30 -13 47 13 8 23 8 38 -2 27 -16 35 -15 20 3 -15 18
-61 20 -78 3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -0,0 +1,107 @@
# Development Tool: `_debug`
The **Debug Plugin** is a lightweight reactive listener. Once attached to a signal or a computed function, it automatically monitors changes, compares values, and formats the output in the browser console.
## 1. Core Features
* **Reactive Tracking:** Automatically logs whenever the tracked signal updates.
* **Visual Grouping:** Uses styled console groups to keep your dev tools organized.
* **Object Inspection:** Automatically uses `console.table()` when the signal contains an object or array.
* **Efficient Comparison:** Uses `Object.is` to prevent redundant logging if the value hasn't actually changed.
---
## 2. Installation
To use `_debug`, you only need the SigPro core. Register the plugin in your `main.js`. You can conditionally load it so it only runs during development.
```javascript
import { $ } from 'sigpro';
import { Debug } from 'sigpro/plugins';
// Only load Debug in development mode
const plugins = [];
if (import.meta.env.DEV) plugins.push(Debug);
$.plugin(plugins).then(() => {
import('./App.js').then(app => $.mount(app.default));
});
```
::: code-group
```bash [NPM]
npm install sigpro
```
```bash [PNPM]
pnpm add sigpro
```
```bash [Yarn]
yarn add sigpro
```
```bash [Bun]
bun add sigpro
```
:::
---
## 3. Basic Usage
Call `_debug` anywhere in your component. It stays active in the background, watching the signal's lifecycle.
```javascript
export default () => {
const $count = $(0);
const $user = $({ name: "Guest", role: "Viewer" });
// Start tracking
_debug($count, "Main Counter");
_debug($user, "User Session");
return div([
button({ onclick: () => $count(c => c + 1) }, "Increment"),
button({ onclick: () => $user({ name: "Admin", role: "Super" }) }, "Promote")
]);
};
```
---
## 4. Console Output Breakdown
When a signal changes, the console displays a structured block:
1. **Header:** A styled badge with the name (e.g., `SigPro Debug: Main Counter`).
2. **Previous Value:** The value before the update (in red).
3. **Current Value:** The new value (in green).
4. **Table View:** If the value is an object, a formatted table appears automatically.
---
## 5. Debugging Computed Values
You can also debug **computed functions** to see exactly when derived state is recalculated.
```javascript
const $price = $(100);
const $tax = $(0.21);
const $total = $(() => $price() * (1 + $tax()));
// Monitor the result of the calculation
_debug($total, "Final Invoice Total");
```
---
## 6. Why use `_debug`?
1. **Clean Logic:** No need to scatter `console.log` inside your reactive functions.
2. **State History:** Instantly see the "Before" and "After" of any user action.
3. **No-Noise:** It only logs when a real change occurs, keeping the console clean.
4. **Deep Inspection:** The automatic `console.table` makes debugging large API responses much faster.

View File

@@ -0,0 +1,80 @@
# Data Fetching: `_fetch`
The **Fetch Plugin** provides a reactive wrapper around the native browser Fetch API. Instead of managing complex `async/await` flows within your UI, `_fetch` returns a "Reactive Tripod" (Data, Loading, and Error) that your components can listen to automatically.
## 1. Core Concept
When you call `_fetch`, it returns three signals immediately. Your UI declares how to react to these signals as they change from their initial state to the final response.
* **`$data`**: Initialized as `null`. Automatically holds the JSON response on success.
* **`$loading`**: Initialized as `true`. Flips to `false` once the request settles.
* **`$error`**: Initialized as `null`. Holds the error message if the request fails.
---
## 2. Installation
Register the `Fetch` plugin in your `main.js`. By convention, we load it alongside the UI and Router to have the full SigPro ecosystem ready.
```javascript
import { $ } from 'sigpro';
import { Fetch } from 'sigpro/plugins';
$.plugin([Fetch]).then(() => {
// Now _fetch() is available globally
import('./App.js').then(app => $.mount(app.default));
});
```
---
## 3. Basic Usage
Use `_fetch` inside your component to get live updates. The UI updates surgically whenever a signal changes.
```javascript
export default () => {
const { $data, $loading, $error } = _fetch('https://api.github.com/users/octocat');
return div({ class: 'p-6 flex flex-col gap-4' }, [
h1("Profile Details"),
// 1. Loading State (using SigPro UI button)
() => $loading() && _button({ $loading: true }, "Fetching..."),
// 2. Error State
() => $error() && div({ class: 'alert alert-error' }, $error()),
// 3. Success State
() => $data() && div({ class: 'card bg-base-200 p-4' }, [
img({ src: $data().avatar_url, class: 'w-16 rounded-full' }),
h2($data().name),
p($data().bio)
])
]);
};
```
---
## 4. Advanced Configuration
`_fetch` accepts the same `RequestInit` options as the standard `fetch()` (methods, headers, body, etc.).
```javascript
const { $data, $loading } = _fetch('/api/v1/update', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: 'active' })
});
```
---
## 5. Why use `_fetch` instead of native Fetch?
1. **Declarative UI**: You define the "Loading", "Error", and "Success" templates once, and they swap automatically.
2. **No `useEffect` required**: Since SigPro is natively reactive, you don't need lifecycle hooks to trigger re-renders; the signals handle it.
3. **Consistency**: It follows the same `_prefix` pattern as the rest of the official plugin ecosystem.
4. **Automatic JSON Parsing**: It assumes JSON by default and handles 404/500 errors by populating the `$error` signal.

View File

@@ -0,0 +1,110 @@
# Navigation Plugin: `Router`
The SigPro Router handles URL changes via hashes (`#`) and maps them to components. It supports dynamic parameters (like `:id`) and asynchronous loading for heavy pages.
## 1. Core Features
* **Hash-based:** Works everywhere without special server configuration.
* **Lazy Loading:** Pages are only downloaded when the user visits the route.
* **Reactive:** The view updates automatically when the hash changes.
* **Dynamic Routes:** Supports paths like `/user/:id`.
---
## 2. Installation
The Router is usually included in the official plugins package.
::: code-group
```bash [NPM]
npm install -D tailwindcss @tailwindcss/vite daisyui@next
```
```bash [PNPM]
pnpm add -D tailwindcss @tailwindcss/vite daisyui@next
```
```bash [Yarn]
yarn add -D tailwindcss @tailwindcss/vite daisyui@next
```
```bash [Bun]
bun add -d tailwindcss @tailwindcss/vite daisyui@next
```
:::
---
## 3. Setting Up Routes
In your `App.js` (or a dedicated routes file), define your navigation map.
```javascript
const routes = [
{ path: '/', component: () => h1("Home Page") },
{
path: '/admin',
// Lazy Loading: This file is only fetched when needed
component: () => import('./pages/Admin.js')
},
{ path: '/user/:id', component: (params) => h2(`User ID: ${params.id}`) },
{ path: '*', component: () => div("404 - Page Not Found") }
];
export default () => div([
_navbar({ title: "My App" }),
_router(routes) // The router is now a global tag
]);
```
---
## 4. Navigation (`_router.go`)
To move between pages programmatically (e.g., inside an `onclick` event), use the global `_router.go` helper.
```javascript
_button({
onclick: () => _router.go('/admin')
}, "Go to Admin")
```
---
## 5. How it Works (Under the Hood)
The router tracks the `window.location.hash` and uses a reactive signal to trigger a re-render of the specific area where `_router(routes)` is placed.
1. **Match:** It filters your route array to find the best fit.
2. **Resolve:** * If it's a standard function, it executes it immediately.
* If it's a **Promise** (via `import()`), it shows a loading state and swaps the content once the module arrives.
3. **Inject:** It replaces the previous DOM node with the new page content surgically.
---
## 6. Integration with UI Components
Since you are using the **UI Plugin**, you can easily create active states in your navigation menus by checking the current hash.
```javascript
// Example of a reactive sidebar menu
_menu({
items: [
{
label: 'Dashboard',
active: () => window.location.hash === '#/',
onclick: () => _router.go('/')
},
{
label: 'Settings',
active: () => window.location.hash === '#/settings',
onclick: () => _router.go('/settings')
}
]
})
```

View File

@@ -0,0 +1,106 @@
# Persistence Tool: `_storage`
The Storage plugin synchronizes a signal with a specific key in your browser's `localStorage`. It handles both the **initial hydration** (loading data when the app starts) and **automatic saving** whenever the signal's value changes.
## 1. Core Concept
When you "attach" a signal to `_storage`, two things happen:
1. **Hydration:** The plugin checks if the key already exists in `localStorage`. If it does, it parses the JSON and updates the signal immediately.
2. **Reactive Sync:** It creates a reactive watcher that stringifies and saves the signal's value to the disk every time it is updated.
---
## 2. Installation
Register the `Storage` plugin in your `main.js`. Since this is a logic-only plugin, it doesn't require any CSS or UI dependencies.
```javascript
import { $ } from 'sigpro';
import { Storage } from 'sigpro/plugins';
$.plugin(Storage).then(() => {
import('./App.js').then(app => $.mount(app.default));
});
```
::: code-group
```bash [NPM]
npm install sigpro
```
```bash [PNPM]
pnpm add sigpro
```
```bash [Yarn]
yarn add sigpro
```
```bash [Bun]
bun add sigpro
```
:::
---
## 3. Basic Usage
You can wrap any signal with `_storage`. It is common practice to do this right after creating the signal.
```javascript
export default () => {
// 1. Create a signal with a default value
const $theme = $( 'light' );
// 2. Persist it. If 'user_theme' exists in localStorage,
// $theme will be updated to that value instantly.
_storage($theme, 'user_theme');
return div({ class: () => `app-${$theme()}` }, [
h1(`Current Theme: ${$theme()}`),
button({
onclick: () => $theme(t => t === 'light' ? 'dark' : 'light')
}, "Toggle Theme")
]);
};
```
---
## 4. Complex Data (Objects & Arrays)
Since the plugin uses `JSON.parse` and `JSON.stringify` internally, it works perfectly with complex state structures.
```javascript
const $settings = $({
notifications: true,
fontSize: 16
});
// Automatically saves the whole object whenever any property changes
_storage($settings, 'app_settings');
```
---
## 5. Why use `_storage`?
1. **Zero Boilerplate:** You don't need to manually write `localStorage.getItem` or `setItem` logic inside your components.
2. **Chaining:** Because `_storage` returns the signal, you can persist it inline.
3. **Error Resilience:** It includes a built-in `try/catch` block to prevent your app from crashing if the stored JSON is corrupted.
4. **Surgical Persistence:** Only the signals you explicitly mark for storage are saved, keeping your `localStorage` clean.
---
## 6. Pro Tip: Combining with Debug
You can chain plugins to create a fully monitored and persistent state:
```javascript
const $score = _storage($(0), 'high_score');
// Now it's saved to disk AND logged to console on every change
_debug($score, "Game Score");
```

147
src/docs/plugins/core.ui.md Normal file
View File

@@ -0,0 +1,147 @@
# Official UI Plugin: `UI`
The **SigPro UI** plugin is a high-level component library built on top of the reactive core. It leverages **Tailwind CSS v4** for utility styling and **daisyUI v5** for semantic components.
## 1. Prerequisites & Installation
To use these components, you must install the styling engine. SigPro UI provides the logic, but Tailwind and daisyUI provide the visuals.
::: code-group
```bash [NPM]
npm install -D tailwindcss @tailwindcss/vite daisyui@next
```
```bash [PNPM]
pnpm add -D tailwindcss @tailwindcss/vite daisyui@next
```
```bash [Yarn]
yarn add -D tailwindcss @tailwindcss/vite daisyui@next
```
```bash [Bun]
bun add -d tailwindcss @tailwindcss/vite daisyui@next
```
:::
Would you like to continue with the **Router.md** documentation now?
### CSS Configuration (`app.css`)
In Tailwind v4, configuration is handled directly in your CSS. Create a `src/app.css` file:
```css
/* src/app.css */
@import "tailwindcss";
/* Import daisyUI v5 as a Tailwind v4 plugin */
@plugin "daisyui";
/* Optional: Configure themes */
@custom-variant dark (&:where(.dark, [data-theme="dark"], [data-theme="dark"] *)));
```
---
## 2. Initialization
You must import your CSS and register the `UI` plugin in your entry point. This populates the global scope with reactive component helpers (prefixed with `_`).
```javascript
// main.js
import './app.css';
import { $ } from 'sigpro';
import { UI } from 'sigpro/plugins';
$.plugin(UI).then(() => {
// Global components like _button and _input are now ready
import('./App.js').then(app => $.mount(app.default));
});
```
---
## 3. Core Component Tags (`_tags`)
SigPro UI components are more than just HTML; they are **Reactive Functional Components** that manage complex states (loading, errors, accessibility) automatically.
### A. Action Components (`_button`)
The `_button` automatically handles spinners and disabled states based on signals.
| Property | Type | Description |
| :--- | :--- | :--- |
| **`$loading`** | `signal` | If true, shows a spinner and disables the button. |
| **`$disabled`**| `signal` | Manually disables the button (logic-bound). |
| **`icon`** | `node/str`| Prepends an icon to the text. |
| **`badge`** | `string` | Appends a small badge to the button. |
```javascript
_button({
$loading: $isSaving,
icon: '💾',
class: 'btn-primary'
}, "Save Data")
```
### B. High-Density Forms (`_input`, `_select`, `_checkbox`)
These components wrap the raw input in a `fieldset` with integrated labels and tooltips.
* **`label`**: Field title displayed above the input.
* **`tip`**: Displays a `?` badge that shows a tooltip on hover.
* **`$error`**: A signal that, when populated, turns the input red and displays the message.
* **`$value`**: **Two-way binding**. Updates the signal on input and the input on signal change.
```javascript
_input({
label: "Username",
tip: "Choose a unique name",
$value: $name,
$error: $nameError
})
```
---
## 4. Complex UI Patterns
### Reactive Modals (`_modal`)
The `_modal` is surgically mounted. If the `$open` signal is `false`, the component is completely removed from the DOM, optimizing performance.
```javascript
const $showModal = $(false);
_modal({ $open: $showModal, title: "Alert" }, [
p("Are you sure you want to proceed?"),
_button({ onclick: () => doAction() }, "Confirm")
])
```
### Navigation & Layout (`_tabs`, `_drawer`, `_navbar`)
Designed to work seamlessly with the **Router**.
| Component | Key Logic |
| :--- | :--- |
| **`_tabs`** | Accepts an `active` property (signal or function) to highlight the current tab. |
| **`_drawer`** | A responsive sidebar that toggles via an ID or an `$open` signal. |
| **`_navbar`** | Standard top bar with shadow and glass effect support. |
| **`_menu`** | Vertical navigation list with active state support. |
---
## 5. Summary Table: UI Globals
Once `$.plugin(UI)` is active, these tags are available project-wide:
| Tag | Category | Use Case |
| :--- | :--- | :--- |
| `_fieldset` | Layout | Grouping related inputs with a `legend`. |
| `_accordion`| Content | Collapsible sections (FAQs). |
| `_badge` | Feedback | Status indicators (Success, Warning). |
| `_tooltip` | Feedback | Descriptive text on hover. |
| `_range` | Input | Reactive slider for numerical values. |
---
### What's next?
With the UI ready and styled via **Tailwind v4**, we can move to the **Router.md**. We will explain how to link `_tabs` and `_menu` to different URL paths for a full SPA experience.
**Would you like to start with the Router configuration?**

123
src/docs/plugins/custom.md Normal file
View File

@@ -0,0 +1,123 @@
# Creating Custom Plugins
There are two main ways to expose a plugin's functionality: **Static/Manual Imports** (cleaner for large projects) or **Global/Automatic Window Injection** (easier for quick scripts and global helpers).
## 1. The Anatomy of a Plugin
A plugin is a standard JavaScript function. By convention, if a plugin adds a global helper or component, it should be prefixed with an underscore (`_`).
```javascript
// plugins/my-utils.js
export const MyUtils = ($) => {
// 1. Attach to the SigPro instance
$.capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
// 2. Attach to the Window (Global access)
window._hello = (name) => div(`Hello, ${$.capitalize(name)}!`);
// 3. You can also return values if needed
return { version: '1.0.0' };
};
```
---
## 2. Integration Strategies
### Option A: Manual Import (Recommended)
This approach keeps your global namespace clean. You import the logic only where you need it, but the plugin still initializes the core `$` extensions.
```javascript
// main.js
import { $ } from 'sigpro';
import { MyUtils } from './plugins/my-utils.js';
$.plugin(MyUtils);
// App.js
export default () => {
const name = "sigpro";
// $.capitalize was added by the plugin
return h1($.capitalize(name));
};
```
### Option B: Automatic Window Injection
If your plugin defines global tags (like `_button` or `_hello`), you should attach them to the `window` object inside the plugin function. This makes them available everywhere without imports.
```javascript
// plugins/theme.js
export const Theme = ($) => {
const $dark = $(false);
window._themeToggle = () => button({
onclick: () => $dark(v => !v),
class: () => $dark() ? 'bg-black text-white' : 'bg-white text-black'
}, "Toggle Mode");
};
// main.js
$.plugin(Theme).then(() => {
// _themeToggle is now a global function
$.mount(App);
});
```
---
## 3. Asynchronous Plugins
If your plugin needs to load external data or scripts before the app starts, make it `async`. SigPro will wait for it.
```javascript
export const ConfigLoader = async ($) => {
const res = await fetch('/config.json');
const config = await res.json();
$.config = config; // Attach loaded config to SigPro
};
// Usage
$.plugin(ConfigLoader).then(() => {
console.log("Config loaded:", $.config);
$.mount(App);
});
```
---
## 4. Best Practices for Plugin Authors
| Rule | Description |
| :--- | :--- |
| **Prefixing** | Use `_` for UI components (`_modal`) and `$.` for logic (`$.fetch`). |
| **Idempotency** | Ensure calling `$.plugin(MyPlugin)` twice doesn't break the app. |
| **Encapsulation** | Use the `$` instance passed as an argument rather than importing it again inside the plugin. |
| **Reactivity** | Always use `$(...)` for internal state so the app stays reactive. |
---
## 5. Installation
Custom plugins don't require extra packages, but ensure your build tool (Vite/Bun) is configured to handle the module imports.
::: code-group
```bash [NPM]
npm install sigpro
```
```bash [PNPM]
pnpm add sigpro
```
```bash [Yarn]
yarn add sigpro
```
```bash [Bun]
bun add sigpro
```
:::

101
src/docs/plugins/quick.md Normal file
View File

@@ -0,0 +1,101 @@
# Extending SigPro: `$.plugin`
The plugin system is the engine's way of growing. It allows you to inject new functionality directly into the `$` object or load external resources.
## 1. How Plugins Work
A plugin in **SigPro** is simply a function that receives the core instance. When you run `$.plugin(MyPlugin)`, the engine hands over the `$` object so the plugin can attach new methods or register global tags (like `div()`, `span()`, etc.).
### Functional Plugin Example
```javascript
// A plugin that adds a simple logger to any signal
const Logger = ($) => {
$.watch = (target, label = "Log") => {
$(() => console.log(`[${label}]:`, target()));
};
};
// Activation
$.plugin(Logger);
const $count = $(0);
$.watch($count, "Counter"); // Now available globally via $
```
---
## 2. Initialization Patterns
Since plugins often set up global variables (like the HTML tags), the order of initialization is critical. Here are the two ways to start your app:
### Option A: The "Safe" Async Start (Recommended)
This is the most robust way. It ensures all global tags (`div`, `button`, etc.) are created **before** your App code is even read by the browser.
```javascript
// main.js
import { $ } from 'sigpro';
import { UI, Router } from 'sigpro/plugins';
// 1. Load plugins first
$.plugin([UI, Router]).then(() => {
// 2. Import your app only after the environment is ready
import('./App.js').then(appFile => {
const MyApp = appFile.default;
$.mount(MyApp, '#app');
});
});
```
### Option B: Static Start (No Global Tags)
Use this only if you prefer **not** to use global tags and want to use `$.html` directly in your components. This allows for standard static imports.
```javascript
// main.js
import { $ } from 'sigpro';
import { UI } from 'sigpro/plugins';
import MyApp from './App.js'; // Static import works here
$.plugin(UI);
$.mount(MyApp, '#app');
```
> **Warning:** In this mode, if `App.js` uses `div()` instead of `$.html('div')`, it will throw a `ReferenceError`.
---
## 3. Resource Plugins (External Scripts)
You can pass a **URL** or an **Array of URLs**. SigPro will inject them as `<script>` tags and return a Promise that resolves when the scripts are fully loaded and executed.
```javascript
// Loading external libraries as plugins
await $.plugin([
'https://cdn.jsdelivr.net/npm/chart.js',
'https://cdn.example.com/custom-ui-lib.js'
]);
console.log("External resources are ready to use!");
```
---
## 4. Polymorphic Loading Reference
The `$.plugin` method adapts to whatever you throw at it:
| Input Type | Action | Behavior |
| :--- | :--- | :--- |
| **Function** | Executes `fn($)` | Synchronous / Immediate |
| **String (URL)** | Injects `<script src="...">` | Asynchronous (Returns Promise) |
| **Array** | Processes each item in the list | Returns Promise if any item is Async |
---
## 💡 Pro Tip: Why the `.then()`?
Using `$.plugin([...]).then(...)` is like giving your app a "Pre-flight Check". It guarantees that:
1. All reactive methods are attached.
2. Global HTML tags are defined.
3. External libraries (like Chart.js) are loaded.
4. **The result:** Your components are cleaner, smaller, and error-free.

118
src/docs/public/logo.svg Normal file
View File

@@ -0,0 +1,118 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="600.000000pt" height="591.000000pt" viewBox="0 0 600.000000 591.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,591.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1130 3454 c-44 -9 -84 -27 -123 -57 -97 -76 -91 -242 12 -310 34
-23 60 -32 193 -71 58 -17 78 -36 78 -74 0 -28 -24 -44 -74 -49 -65 -8 -137
20 -181 68 l-36 40 -27 -33 c-15 -18 -37 -43 -50 -56 -26 -27 -20 -40 35 -86
65 -55 118 -71 233 -71 89 1 112 4 152 24 94 46 137 146 108 252 -20 71 -81
112 -224 152 -124 35 -150 64 -101 112 42 43 147 25 203 -35 18 -20 19 -19 70
30 47 45 51 53 40 69 -22 31 -71 67 -108 80 -39 13 -161 22 -200 15z m193 -36
c56 -23 97 -54 97 -73 0 -7 -17 -27 -37 -44 -36 -30 -37 -31 -57 -13 -12 10
-34 24 -51 31 -34 14 -148 24 -140 11 2 -4 -4 -10 -15 -13 -32 -8 -43 -52 -24
-93 9 -19 19 -32 22 -30 2 3 17 -1 33 -9 15 -8 39 -15 54 -15 14 0 25 -5 25
-11 0 -6 9 -8 20 -4 11 4 20 2 20 -4 0 -6 9 -11 21 -11 37 0 114 -59 133 -103
24 -55 15 -138 -18 -182 -28 -37 -101 -79 -123 -71 -9 4 -11 1 -7 -5 5 -8 -22
-10 -94 -7 -85 3 -106 7 -131 26 -17 12 -37 22 -46 22 -8 0 -15 3 -15 8 0 4
-10 12 -22 17 -41 19 -44 40 -12 77 17 19 37 32 45 30 27 -9 69 -44 64 -53 -4
-5 2 -6 11 -2 11 4 15 3 11 -4 -5 -7 1 -9 15 -5 12 3 19 1 15 -4 -3 -6 25 -11
68 -13 69 -2 77 0 100 23 14 14 31 26 38 27 9 0 9 2 0 6 -7 2 -13 16 -13 29 0
33 -38 66 -91 81 -24 6 -71 18 -104 27 -32 9 -63 23 -68 31 -4 8 -12 13 -17
10 -4 -3 -23 13 -40 36 -28 34 -33 48 -33 97 0 60 35 138 56 125 5 -3 7 -1 3
5 -8 13 2 20 69 49 68 30 168 31 238 1z"/>
<path d="M1031 3144 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
<path d="M945 2900 c-6 -9 11 -50 21 -50 2 0 0 9 -6 20 -6 11 -8 25 -5 30 3 6
4 10 1 10 -3 0 -8 -4 -11 -10z"/>
<path d="M2428 3445 c-154 -39 -259 -173 -261 -333 -2 -111 21 -177 86 -248
77 -85 134 -108 267 -108 86 -1 113 3 151 20 114 53 169 139 177 276 l5 88
-167 0 -166 0 0 -66 0 -65 85 3 c74 3 85 1 85 -14 0 -27 -48 -76 -87 -89 -49
-16 -133 -6 -176 22 -40 27 -82 89 -91 137 -8 44 10 119 37 159 64 94 220 110
304 31 l23 -22 56 56 56 56 -43 32 c-44 32 -97 59 -131 65 -65 13 -159 13
-210 0z m202 -16 c8 -2 17 -7 20 -10 3 -3 21 -10 40 -15 19 -5 35 -15 35 -21
0 -6 4 -15 9 -20 5 -5 6 -3 2 5 -4 6 -3 12 3 12 6 0 15 -9 22 -21 9 -17 7 -24
-10 -40 -11 -10 -24 -27 -30 -36 -9 -17 -13 -16 -59 9 -62 34 -139 53 -157 38
-8 -6 -29 -12 -48 -13 -19 -1 -33 -5 -30 -9 2 -5 -3 -8 -12 -8 -9 0 -14 -4
-10 -9 3 -5 -4 -12 -15 -16 -11 -3 -20 -13 -20 -22 0 -14 -2 -14 -19 1 -13 12
-21 14 -26 6 -3 -6 -1 -9 6 -8 6 2 14 -3 17 -11 2 -8 0 -11 -6 -7 -6 4 -8 -1
-5 -13 3 -10 0 -22 -6 -25 -13 -9 -15 -129 -2 -173 12 -42 76 -107 125 -127
78 -32 198 -9 226 43 5 11 17 27 26 35 10 11 11 16 3 16 -7 0 -9 3 -6 7 4 3 2
12 -4 20 -8 8 -35 13 -79 13 l-68 0 -3 44 -4 44 124 1 c69 1 129 5 134 8 6 4
7 1 2 -7 -6 -9 -4 -12 6 -8 10 4 14 -4 14 -31 0 -20 -4 -42 -9 -50 -6 -10 -6
-12 3 -7 8 6 10 -4 5 -36 -7 -45 -72 -142 -110 -162 -10 -6 -21 -14 -24 -17
-21 -27 -213 -47 -265 -27 -75 28 -115 50 -110 58 3 6 0 7 -8 4 -14 -5 -87 72
-87 92 0 5 5 2 10 -6 7 -12 9 -10 8 7 -1 11 -7 19 -14 16 -12 -4 -27 34 -28
74 -1 12 -4 25 -8 29 -12 11 -10 64 2 64 6 0 10 5 10 11 0 5 -5 7 -11 3 -8 -5
-8 -1 0 14 6 11 11 34 11 51 0 17 4 31 9 31 8 0 24 35 23 50 0 3 19 28 44 55
25 29 42 41 38 30 l-6 -20 13 20 c6 11 13 21 15 23 1 2 32 13 68 26 62 20 174
28 226 15z"/>
<path d="M4670 3451 c-19 -4 -56 -18 -82 -31 -145 -72 -217 -236 -178 -409 14
-64 64 -147 106 -179 16 -12 34 -26 41 -32 6 -5 39 -18 72 -30 114 -38 243
-22 338 44 205 141 184 489 -37 606 -64 33 -178 47 -260 31z m177 -22 c23 -6
40 -16 37 -21 -4 -6 2 -7 15 -3 14 4 23 2 27 -9 3 -9 12 -12 21 -9 11 4 14 2
9 -5 -4 -7 -1 -12 8 -12 21 0 85 -89 86 -117 0 -13 4 -23 8 -23 16 0 30 -74
26 -130 -7 -100 -11 -119 -24 -135 -7 -8 -9 -15 -6 -15 10 0 -52 -85 -78 -107
-20 -16 -50 -32 -116 -61 -31 -14 -161 -10 -219 7 -24 7 -61 23 -81 36 -48 30
-114 110 -104 126 5 8 3 9 -6 4 -10 -6 -12 -3 -8 13 4 12 2 22 -2 22 -4 0 -11
27 -15 60 -8 71 2 143 18 134 8 -5 7 -2 0 7 -16 16 -17 33 -1 23 6 -4 8 -3 5
3 -10 16 13 74 26 66 6 -3 7 -1 3 6 -9 14 57 82 106 108 73 40 189 54 265 32z"/>
<path d="M4676 3307 c-22 -10 -47 -28 -57 -40 -10 -12 -18 -18 -19 -14 0 4 -6
2 -14 -5 -7 -7 -11 -19 -8 -27 3 -8 1 -12 -5 -8 -11 7 -16 -28 -16 -113 0 -74
6 -109 17 -102 5 3 7 -2 3 -11 -4 -10 -2 -16 6 -14 7 1 11 -4 9 -11 -1 -8 2
-11 8 -7 5 3 10 -1 10 -10 0 -8 16 -23 35 -32 19 -9 33 -19 31 -22 -2 -3 27
-6 64 -6 37 0 66 4 63 8 -3 5 1 7 8 6 23 -4 65 18 87 45 11 14 25 26 32 26 6
0 10 6 8 12 -3 7 1 18 7 25 15 15 16 195 2 186 -5 -3 -8 0 -5 7 5 15 -62 84
-102 105 -45 23 -118 24 -164 2z m164 -26 c19 -10 49 -37 65 -60 27 -39 30
-50 30 -119 0 -65 -4 -83 -25 -114 -36 -53 -85 -78 -156 -78 -68 0 -107 20
-149 74 -40 52 -46 146 -15 210 49 102 149 137 250 87z"/>
<path d="M1619 3443 c0 -2 0 -33 -1 -70 l0 -68 58 1 59 0 -2 -205 -2 -205 -58
3 -58 2 0 -70 0 -71 203 0 202 0 0 70 0 70 -77 -1 c-43 -1 -68 -4 -55 -6 12
-2 22 -7 22 -11 0 -4 19 -7 42 -7 l43 0 3 -48 3 -48 -165 3 c-92 2 -166 -1
-166 -5 0 -4 -9 -3 -21 3 -16 9 -19 19 -17 53 l3 41 47 1 c76 2 76 -1 76 223
1 109 -3 203 -7 211 -5 8 -29 14 -57 15 -32 1 -49 5 -48 14 1 6 2 28 3 47 l1
35 176 0 176 0 -4 -47 -3 -48 -42 -1 c-73 -1 -73 -2 -72 -220 1 -107 5 -194
10 -194 5 0 9 90 9 199 l0 199 60 -5 61 -6 -3 72 -3 72 -198 2 c-108 1 -197 1
-198 0z"/>
<path d="M3018 3102 l-3 -342 85 0 85 0 0 112 0 113 105 5 c113 6 145 17 192
67 57 60 76 188 39 261 -26 51 -77 99 -118 113 -19 6 -112 12 -208 12 l-175 2
-2 -343z m375 307 c20 -5 37 -14 37 -19 0 -6 6 -10 14 -10 8 0 18 -5 22 -12 5
-7 3 -8 -6 -3 -9 5 -11 4 -6 -3 4 -7 13 -12 19 -12 7 0 20 -20 30 -45 23 -54
19 -135 -8 -197 -4 -10 -11 -15 -16 -12 -5 3 -6 -2 -3 -10 4 -10 -10 -24 -43
-43 -53 -31 -55 -32 -167 -38 -107 -5 -112 -12 -106 -131 4 -83 3 -94 -12 -98
-10 -2 -18 -1 -18 3 0 3 -20 5 -45 3 l-45 -4 0 321 0 321 158 0 c86 0 174 -5
195 -11z"/>
<path d="M3187 3308 c-27 -20 -34 -173 -9 -183 26 -10 151 -11 144 -1 -3 5 5
7 16 4 12 -4 20 -3 18 1 -3 4 4 15 15 24 29 25 26 100 -5 134 -20 21 -35 26
-92 30 -50 3 -74 1 -87 -9z m157 -29 c32 -25 36 -84 7 -120 -16 -20 -30 -24
-93 -27 l-74 -4 0 86 1 86 66 0 c52 0 72 -4 93 -21z"/>
<path d="M3710 3103 l0 -343 83 0 82 0 -3 120 -3 120 45 0 c44 0 45 -1 79 -57
19 -32 49 -86 67 -120 l32 -62 95 -3 c52 -2 97 -1 99 1 7 7 -18 31 -27 25 -5
-3 -7 1 -4 8 3 7 -22 59 -55 116 -60 103 -68 122 -51 122 16 0 86 80 98 112
39 108 -9 228 -110 277 -37 18 -65 21 -235 23 l-192 3 0 -342z m385 313 c26
-5 74 -37 71 -49 -1 -6 -1 -9 1 -4 18 31 73 -77 73 -143 0 -56 -36 -127 -78
-155 -17 -11 -35 -30 -41 -42 -9 -19 -6 -27 14 -47 14 -14 25 -32 25 -41 0 -8
5 -15 11 -15 6 0 8 -9 4 -20 -4 -13 -2 -19 4 -18 12 3 68 -88 60 -96 -4 -4
-77 -7 -120 -5 -17 0 -54 64 -52 87 0 7 -1 11 -5 8 -6 -7 -32 41 -32 61 0 8
-4 12 -8 9 -4 -3 -17 11 -27 31 -21 38 -55 58 -67 39 -6 -8 -10 -8 -16 1 -6 9
-13 9 -32 0 -27 -14 -27 -12 -29 -150 l-1 -88 -57 2 -58 2 3 316 c2 235 6 317
15 323 10 6 301 1 342 -6z"/>
<path d="M3886 3328 c3 -4 -1 -8 -9 -8 -22 0 -37 -128 -21 -187 6 -22 11 -23
101 -23 91 0 96 1 124 29 41 41 43 113 5 146 -51 44 -67 55 -79 55 -8 0 -7 -4
3 -10 11 -7 -4 -10 -48 -10 -35 0 -61 4 -58 8 3 5 -1 9 -9 9 -8 0 -12 -4 -9
-9z m180 -49 c43 -43 31 -133 -19 -143 -12 -3 -57 -7 -99 -8 l-78 -3 0 93 0
94 85 -3 c75 -4 87 -7 111 -30z"/>
<path d="M4167 3099 c7 -7 15 -10 18 -7 3 3 -2 9 -12 12 -14 6 -15 5 -6 -5z"/>
<path d="M3986 3017 c3 -10 9 -15 12 -12 3 3 0 11 -7 18 -10 9 -11 8 -5 -6z"/>
<path d="M1643 2830 c0 -25 2 -35 4 -22 2 12 2 32 0 45 -2 12 -4 2 -4 -23z"/>
<path d="M2923 2373 c13 -4 17 -15 17 -59 0 -60 -16 -77 -51 -55 -11 6 -19 7
-19 2 0 -6 6 -13 13 -18 45 -28 81 10 75 82 -2 33 1 46 12 49 8 2 -3 4 -25 4
-22 0 -32 -2 -22 -5z"/>
<path d="M3072 2368 c-24 -24 -13 -49 28 -65 27 -11 40 -22 38 -32 -4 -20 -44
-27 -64 -10 -8 6 -17 9 -20 6 -3 -3 5 -12 18 -21 37 -24 87 -7 88 30 0 15 -19
29 -55 41 -34 11 -39 30 -13 47 13 8 23 8 38 -2 27 -16 35 -15 20 3 -15 18
-61 20 -78 3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.8 KiB

124
src/docs/vite/plugin.md Normal file
View File

@@ -0,0 +1,124 @@
# Vite Plugin: File-based Routing
The `sigproRouter` plugin for Vite automates route generation by scanning your pages directory. It creates a **virtual module** that you can import directly into your code, eliminating the need to maintain a manual routes array.
## 1. Project Structure
To use the plugin, organize your files within the `src/pages` directory. The folder hierarchy directly determines your application's URL structure.
```text
my-sigpro-app/
├── src/
│ ├── pages/
│ │ ├── index.js → #/
│ │ ├── about.js → #/about
│ │ ├── users/
│ │ │ └── [id].js → #/users/:id
│ │ └── blog/
│ │ ├── index.js → #/blog
│ │ └── [slug].js → #/blog/:slug
│ ├── App.js (Optional App Shell)
│ └── main.js (Entry Point)
├── vite.config.js
└── package.json
```
---
## 2. Setup & Configuration
Add the plugin to your `vite.config.js`.
```javascript
// vite.config.js
import { defineConfig } from 'vite';
import { sigproRouter } from 'sigpro/vite';
export default defineConfig({
plugins: [sigproRouter()]
});
```
---
## 3. Implementation
You can implement the router either directly in your entry point or inside an App component to support persistent layouts (like a navbar that doesn't re-render).
### Option A: Direct in `main.js`
Best for simple apps where the router occupies the entire viewport.
```javascript
// src/main.js
import { $ } from 'sigpro';
import { Router } from 'sigpro/plugins';
import { routes } from 'virtual:sigpro-routes';
$.plugin(Router).then(() => {
$.mount(_router(routes), '#app');
});
```
### Option B: Inside `App.js` (With Layout)
Recommended for apps with a fixed Sidebar or Navbar.
```javascript
// src/main.js
import { $ } from 'sigpro';
import { Router } from 'sigpro/plugins';
$.plugin(Router).then(() => {
import('./App.js').then(app => $.mount(app.default, '#app'));
});
// src/App.js
import { routes } from 'virtual:sigpro-routes';
export default () => {
return div({ class: 'layout' }, [
header([
h1("SigPro App"),
nav([
a({ href: '#/' }, "Home"),
a({ href: '#/blog' }, "Blog")
])
]),
// The router only swaps the content inside this <main> tag
main(_router(routes))
]);
};
```
---
## 4. Route Mapping Reference
| File Path | Generated Route | Logic |
| :--- | :--- | :--- |
| `index.js` | `/` | Home page |
| `about.js` | `/about` | Static path |
| `[id].js` | `/:id` | Dynamic parameter |
| `blog/index.js` | `/blog` | Folder index |
| `_utils.js` | *Ignored* | Files starting with `_` are skipped |
---
## 5. Installation
::: code-group
```bash [NPM]
npm install sigpro
```
```bash [PNPM]
pnpm add sigpro
```
```bash [Yarn]
yarn add sigpro
```
```bash [Bun]
bun add sigpro
```
:::