Skip to content

Instantly share code, notes, and snippets.

@daliborgogic
Last active June 27, 2026 21:52
Show Gist options
  • Select an option

  • Save daliborgogic/e4df636d8d274b9cf2b1701acf38a50f to your computer and use it in GitHub Desktop.

Select an option

Save daliborgogic/e4df636d8d274b9cf2b1701acf38a50f to your computer and use it in GitHub Desktop.
<script setup vapor lang="ts">
import { useRouter } from '@dlbr/ui';
const { currentComponent } = useRouter();
</script>
<template>
<Component v-if="currentComponent" :is="currentComponent" />
</template>
import { createVaporApp, watch } from 'vue';
import { useRouter } from '@dlbr/ui';
import './style.css';
import App from './App.vue';
import PosRegisterView from './views/PosRegisterView.vue';
import PosSetupView from './views/PosSetupView.vue';
const routes = {
'/': PosRegisterView,
'/setup': PosSetupView
};
// Initialize the lightweight router
const { navigate, currentPath } = useRouter(routes);
let isConfigChecked = false;
let isConfigured = false;
// Navigation guard function
async function guard(path: string) {
if (path === '/setup') return;
if (path === '/') {
if (!isConfigChecked) {
try {
const res = await fetch("/api/config", {
headers: { "X-Compatibility-Date": "2026-06-25" }
});
if (res.ok) {
const config = await res.json();
if (config && config.lPfrUrl) {
isConfigured = true;
}
}
} catch (err) {
console.warn("Local hardware helper daemon config check failed, fallback to setup wizard.");
}
isConfigChecked = true;
}
if (!isConfigured) {
navigate('/setup');
}
}
}
// Reactively run guards when path changes
watch(() => currentPath.value, (newPath) => {
guard(newPath);
}, { immediate: true });
const app = createVaporApp(App);
app.mount('#app');
import { ref, shallowRef, readonly, type Component } from 'vue';
export interface RouteConfig {
path: string;
component?: any; // Component or () => Promise<{ default: Component }>
redirect?: string;
}
const routes = ref<RouteConfig[]>([]);
const currentPath = ref(window.location.pathname);
const currentComponent = shallowRef<Component | null>(null);
const routeParams = ref<Record<string, string>>({});
function matchRoute(path: string) {
for (const route of routes.value) {
if (route.path === path) return { route, params: {} };
const paramNames: string[] = [];
let regexPath = route.path.replace(/:([^/]+)/g, (_, paramName) => {
paramNames.push(paramName);
return '([^/]+)';
});
// Support wildcard catch-all for 404 (e.g. '*')
if (regexPath === '*') {
regexPath = '.*';
} else if (regexPath.includes('*')) {
regexPath = regexPath.replace(/\*/g, '.*');
}
const regex = new RegExp(`^${regexPath}$`);
const match = path.match(regex);
if (match) {
const params: Record<string, string> = {};
paramNames.forEach((name, idx) => {
params[name] = match[idx + 1];
});
return { route, params };
}
}
return null;
}
async function resolveRoute(path: string) {
const match = matchRoute(path);
if (!match) {
const fallback = matchRoute('/404') || matchRoute('*');
if (fallback && fallback.route.component) {
let comp = fallback.route.component;
if (typeof comp === 'function' && !comp.render && !comp.setup) {
comp = (await comp()).default || comp;
}
currentComponent.value = comp;
} else {
currentComponent.value = null;
}
routeParams.value = {};
return;
}
if (match.route.redirect) {
navigate(match.route.redirect);
return;
}
routeParams.value = match.params;
if (match.route.component) {
let comp = match.route.component;
if (typeof comp === 'function' && !comp.render && !comp.setup) {
comp = (await comp()).default || comp;
}
currentComponent.value = comp;
}
}
export function navigate(path: string) {
window.history.pushState({}, '', path);
currentPath.value = path;
resolveRoute(path);
}
export function useRouter(routeConfig?: RouteConfig[]) {
if (routeConfig && routeConfig.length > 0) {
routes.value = routeConfig;
resolveRoute(currentPath.value);
if (!(window as any)._routerMounted) {
window.addEventListener('popstate', () => {
currentPath.value = window.location.pathname;
resolveRoute(currentPath.value);
});
(window as any)._routerMounted = true;
}
}
return {
navigate,
currentComponent: readonly(currentComponent),
currentPath: readonly(currentPath),
routeParams: readonly(routeParams)
};
}
import type { Plugin } from 'vite';
export function vaporOnly(): Plugin {
return {
name: 'dlbr-vapor-only',
enforce: 'pre',
transform(source: string, id: string) {
if (!id.endsWith('.vue')) return null;
if (!/<script\s+setup\s+vapor(?:\s|>)/.test(source)) {
throw new Error(`${id} must use <script setup vapor>; VDOM fallback is disabled. 💅`);
}
return null;
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment