UNPKG

@furystack/shades

Version:

Google Authentication Provider for FuryStack

61 lines 2.8 kB
import { ObservableAlreadyDisposedError } from '@furystack/utils'; import { match } from 'path-to-regexp'; import { Lock } from 'semaphore-async-await'; import { LocationService } from '../services/location-service.js'; import { createComponent } from '../shade-component.js'; import { Shade } from '../shade.js'; export const Router = Shade({ shadowDomName: 'shade-router', render: (options) => { const { useState, useObservable, injector } = options; const [lock] = useState('lock', new Lock()); const [state, setState] = useState('routerState', { jsx: createComponent("div", null), }); const updateUrl = async (currentUrl) => { const [lastState] = useState('routerState', state); const { activeRoute: lastRoute, activeRouteParams: lastRouteParams, jsx: lastJsx } = lastState; try { await lock.acquire(); for (const route of options.props.routes) { const matchFn = match(route.url, route.routingOptions); const matchResult = matchFn(currentUrl); if (matchResult) { if (route !== lastRoute || JSON.stringify(lastRouteParams) !== JSON.stringify(matchResult.params)) { await lastRoute?.onLeave?.({ ...options, element: lastState.jsx }); const newJsx = route.component({ currentUrl, match: matchResult }); setState({ jsx: newJsx, activeRoute: route, activeRouteParams: matchResult.params }); await route.onVisit?.({ ...options, element: newJsx }); } return; } } if (lastRoute !== null) { await lastRoute?.onLeave?.({ ...options, element: lastJsx }); setState({ jsx: options.props.notFound || createComponent("div", null), activeRoute: null, activeRouteParams: null, }); } } catch (e) { // path updates can be async, this can be ignored if (!(e instanceof ObservableAlreadyDisposedError)) { throw e; } } finally { lock?.release(); } }; const [locationPath] = useObservable('locationPathChanged', injector.getInstance(LocationService).onLocationPathChanged, { onChange: (newValue) => { void updateUrl(newValue); }, }); void updateUrl(locationPath); return state.jsx; }, }); //# sourceMappingURL=router.js.map