@lovrozagar/flare 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/package.json +146 -0
- package/scripts/download-fonts.ts +136 -0
- package/scripts/populate-fonts.ts +721 -0
- package/src/await.ts +2 -0
- package/src/boundaries/index.ts +99 -0
- package/src/broadcast/channel.ts +65 -0
- package/src/broadcast/context.ts +12 -0
- package/src/broadcast/index.ts +75 -0
- package/src/broadcast/provider.tsx +7 -0
- package/src/build-location.ts +2 -0
- package/src/caches/index.ts +384 -0
- package/src/client/index.ts +75 -0
- package/src/client.tsx +2 -0
- package/src/codegen/index.ts +41 -0
- package/src/components/await.tsx +140 -0
- package/src/components/dev-error-overlay.tsx +154 -0
- package/src/components/direction-script.tsx +22 -0
- package/src/components/index.ts +150 -0
- package/src/components/locale-script.tsx +26 -0
- package/src/components/reset-css.tsx +14 -0
- package/src/components/ssr-context.tsx +37 -0
- package/src/components/theme-script.tsx +22 -0
- package/src/components/view-transition-css.tsx +21 -0
- package/src/config/index.ts +84 -0
- package/src/create-client-only-fn.ts +1 -0
- package/src/create-isomorphic-fn.ts +2 -0
- package/src/create-layout.ts +1 -0
- package/src/create-page.ts +1 -0
- package/src/create-path-segment.ts +1 -0
- package/src/create-query-client-getter.ts +2 -0
- package/src/create-root-layout.ts +1 -0
- package/src/create-router.ts +8 -0
- package/src/create-server-only-fn.ts +1 -0
- package/src/dedupe/index.ts +151 -0
- package/src/defer/index.ts +82 -0
- package/src/direction/index.tsx +163 -0
- package/src/direction.ts +3 -0
- package/src/duration/index.ts +18 -0
- package/src/env-fn/index.ts +101 -0
- package/src/env-fn.ts +2 -0
- package/src/errors/index.ts +166 -0
- package/src/fonts/abeezee.ts +50 -0
- package/src/fonts/abel.ts +26 -0
- package/src/fonts/abril-fatface.ts +34 -0
- package/src/fonts/acme.ts +26 -0
- package/src/fonts/advent-pro.ts +92 -0
- package/src/fonts/alegreya-sans.ts +228 -0
- package/src/fonts/alegreya.ts +228 -0
- package/src/fonts/alex-brush.ts +42 -0
- package/src/fonts/alfa-slab-one.ts +42 -0
- package/src/fonts/alice.ts +48 -0
- package/src/fonts/amatic-sc.ts +94 -0
- package/src/fonts/amiri.ts +114 -0
- package/src/fonts/antic-slab.ts +26 -0
- package/src/fonts/anton.ts +42 -0
- package/src/fonts/archivo-black.ts +34 -0
- package/src/fonts/archivo-narrow.ts +114 -0
- package/src/fonts/archivo.ts +66 -0
- package/src/fonts/arimo.ts +256 -0
- package/src/fonts/arvo.ts +50 -0
- package/src/fonts/asap.ts +66 -0
- package/src/fonts/assistant.ts +64 -0
- package/src/fonts/baloo-2.ts +82 -0
- package/src/fonts/barlow-condensed.ts +114 -0
- package/src/fonts/barlow-semi-condensed.ts +114 -0
- package/src/fonts/barlow.ts +114 -0
- package/src/fonts/be-vietnam-pro.ts +114 -0
- package/src/fonts/bebas-neue.ts +34 -0
- package/src/fonts/besley.ts +82 -0
- package/src/fonts/biorhyme.ts +50 -0
- package/src/fonts/bitter.ts +94 -0
- package/src/fonts/black-ops-one.ts +49 -0
- package/src/fonts/bree-serif.ts +34 -0
- package/src/fonts/bricolage-grotesque.ts +66 -0
- package/src/fonts/cabin.ts +114 -0
- package/src/fonts/cairo.ts +66 -0
- package/src/fonts/cardo.ts +193 -0
- package/src/fonts/catamaran.ts +41 -0
- package/src/fonts/caveat.ts +78 -0
- package/src/fonts/chakra-petch.ts +142 -0
- package/src/fonts/chivo.ts +66 -0
- package/src/fonts/cinzel.ts +50 -0
- package/src/fonts/comfortaa.ts +109 -0
- package/src/fonts/commissioner.ts +64 -0
- package/src/fonts/component.tsx +27 -0
- package/src/fonts/cormorant-garamond.ts +171 -0
- package/src/fonts/cormorant.ts +170 -0
- package/src/fonts/courgette.ts +34 -0
- package/src/fonts/courier-prime.ts +82 -0
- package/src/fonts/create-font.ts +47 -0
- package/src/fonts/create-registry-font.ts +40 -0
- package/src/fonts/crete-round.ts +50 -0
- package/src/fonts/crimson-text.ts +114 -0
- package/src/fonts/css.ts +86 -0
- package/src/fonts/dancing-script.ts +66 -0
- package/src/fonts/dm-mono.ts +50 -0
- package/src/fonts/dm-sans.ts +50 -0
- package/src/fonts/dm-serif-display.ts +50 -0
- package/src/fonts/domine.ts +50 -0
- package/src/fonts/dosis.ts +66 -0
- package/src/fonts/eb-garamond.ts +228 -0
- package/src/fonts/eczar.ts +94 -0
- package/src/fonts/encode-sans.ts +42 -0
- package/src/fonts/epilogue.ts +66 -0
- package/src/fonts/exo-2.ts +94 -0
- package/src/fonts/exo.ts +66 -0
- package/src/fonts/figtree.ts +82 -0
- package/src/fonts/fira-code.ts +121 -0
- package/src/fonts/fira-sans-condensed.ts +228 -0
- package/src/fonts/fira-sans.ts +228 -0
- package/src/fonts/fjalla-one.ts +49 -0
- package/src/fonts/font-urls.gen.json +1962 -0
- package/src/fonts/fraunces.ts +66 -0
- package/src/fonts/fredoka.ts +64 -0
- package/src/fonts/gelasio.ts +114 -0
- package/src/fonts/gloria-hallelujah.ts +34 -0
- package/src/fonts/gothic-a1.ts +124 -0
- package/src/fonts/great-vibes.ts +64 -0
- package/src/fonts/gudea.ts +66 -0
- package/src/fonts/heebo.ts +57 -0
- package/src/fonts/hind-siliguri.ts +66 -0
- package/src/fonts/hind.ts +66 -0
- package/src/fonts/ibm-plex-mono.ts +172 -0
- package/src/fonts/ibm-plex-sans-arabic.ts +80 -0
- package/src/fonts/ibm-plex-sans.ts +199 -0
- package/src/fonts/ibm-plex-serif.ts +171 -0
- package/src/fonts/inconsolata.ts +66 -0
- package/src/fonts/index.ts +4 -0
- package/src/fonts/indie-flower.ts +34 -0
- package/src/fonts/instrument-sans.ts +82 -0
- package/src/fonts/instrument-serif.ts +50 -0
- package/src/fonts/inter-display.ts +52 -0
- package/src/fonts/inter-tight.ts +124 -0
- package/src/fonts/inter.ts +123 -0
- package/src/fonts/jetbrains-mono.ts +199 -0
- package/src/fonts/josefin-sans.ts +114 -0
- package/src/fonts/josefin-slab.ts +50 -0
- package/src/fonts/jost.ts +64 -0
- package/src/fonts/kalam.ts +66 -0
- package/src/fonts/kanit.ts +142 -0
- package/src/fonts/karla.ts +82 -0
- package/src/fonts/khand.ts +66 -0
- package/src/fonts/lato.ts +82 -0
- package/src/fonts/league-spartan.ts +42 -0
- package/src/fonts/lexend-deca.ts +42 -0
- package/src/fonts/lexend.ts +42 -0
- package/src/fonts/libre-baskerville.ts +82 -0
- package/src/fonts/libre-franklin.ts +95 -0
- package/src/fonts/lilita-one.ts +34 -0
- package/src/fonts/lobster-two.ts +50 -0
- package/src/fonts/lobster.ts +56 -0
- package/src/fonts/lora.ts +235 -0
- package/src/fonts/m-plus-rounded-1c.ts +138 -0
- package/src/fonts/manrope.ts +109 -0
- package/src/fonts/maven-pro.ts +66 -0
- package/src/fonts/merriweather-sans.ts +142 -0
- package/src/fonts/merriweather.ts +171 -0
- package/src/fonts/montserrat-alternates.ts +171 -0
- package/src/fonts/montserrat.ts +94 -0
- package/src/fonts/mukta.ts +66 -0
- package/src/fonts/mulish.ts +170 -0
- package/src/fonts/nanum-gothic.ts +34 -0
- package/src/fonts/nanum-myeongjo.ts +34 -0
- package/src/fonts/neuton.ts +66 -0
- package/src/fonts/newsreader.ts +114 -0
- package/src/fonts/noticia-text.ts +114 -0
- package/src/fonts/noto-sans-arabic.ts +58 -0
- package/src/fonts/noto-sans-hk.ts +49 -0
- package/src/fonts/noto-sans-jp.ts +49 -0
- package/src/fonts/noto-sans-kr.ts +49 -0
- package/src/fonts/noto-sans-sc.ts +49 -0
- package/src/fonts/noto-sans-tc.ts +49 -0
- package/src/fonts/noto-sans.ts +140 -0
- package/src/fonts/noto-serif-jp.ts +80 -0
- package/src/fonts/noto-serif.ts +140 -0
- package/src/fonts/nunito-sans.ts +170 -0
- package/src/fonts/nunito.ts +170 -0
- package/src/fonts/old-standard-tt.ts +133 -0
- package/src/fonts/onest.ts +48 -0
- package/src/fonts/open-sans.ts +340 -0
- package/src/fonts/orbitron.ts +34 -0
- package/src/fonts/oswald.ts +94 -0
- package/src/fonts/outfit.ts +34 -0
- package/src/fonts/overpass.ts +94 -0
- package/src/fonts/oxygen.ts +50 -0
- package/src/fonts/pacifico.ts +56 -0
- package/src/fonts/passion-one.ts +50 -0
- package/src/fonts/pathway-gothic-one.ts +34 -0
- package/src/fonts/permanent-marker.ts +26 -0
- package/src/fonts/philosopher.ts +172 -0
- package/src/fonts/play.ts +109 -0
- package/src/fonts/playfair-display.ts +142 -0
- package/src/fonts/plus-jakarta-sans.ts +142 -0
- package/src/fonts/poppins.ts +114 -0
- package/src/fonts/prompt.ts +142 -0
- package/src/fonts/pt-sans-narrow.ts +78 -0
- package/src/fonts/pt-sans.ts +138 -0
- package/src/fonts/pt-serif.ts +138 -0
- package/src/fonts/public-sans.ts +66 -0
- package/src/fonts/questrial.ts +42 -0
- package/src/fonts/quicksand.ts +66 -0
- package/src/fonts/rajdhani.ts +66 -0
- package/src/fonts/raleway.ts +94 -0
- package/src/fonts/recursive.ts +80 -0
- package/src/fonts/red-hat-display.ts +82 -0
- package/src/fonts/red-rose.ts +66 -0
- package/src/fonts/registry.gen.ts +173 -0
- package/src/fonts/righteous.ts +34 -0
- package/src/fonts/roboto-condensed.ts +124 -0
- package/src/fonts/roboto-flex.ts +64 -0
- package/src/fonts/roboto-mono.ts +199 -0
- package/src/fonts/roboto-slab.ts +72 -0
- package/src/fonts/roboto.ts +156 -0
- package/src/fonts/rokkitt.ts +66 -0
- package/src/fonts/rubik.ts +199 -0
- package/src/fonts/sacramento.ts +34 -0
- package/src/fonts/saira.ts +66 -0
- package/src/fonts/sarabun.ts +142 -0
- package/src/fonts/satisfy.ts +26 -0
- package/src/fonts/sawarabi-mincho.ts +41 -0
- package/src/fonts/shadows-into-light.ts +34 -0
- package/src/fonts/signika-negative.ts +66 -0
- package/src/fonts/signika.ts +66 -0
- package/src/fonts/slabo-27px.ts +34 -0
- package/src/fonts/sora.ts +50 -0
- package/src/fonts/source-code-pro.ts +228 -0
- package/src/fonts/source-sans-3.ts +228 -0
- package/src/fonts/source-serif-4.ts +199 -0
- package/src/fonts/space-grotesk.ts +66 -0
- package/src/fonts/space-mono.ts +114 -0
- package/src/fonts/spectral.ts +170 -0
- package/src/fonts/tajawal.ts +50 -0
- package/src/fonts/teko.ts +66 -0
- package/src/fonts/tenor-sans.ts +41 -0
- package/src/fonts/tinos.ts +256 -0
- package/src/fonts/titillium-web.ts +82 -0
- package/src/fonts/types.ts +43 -0
- package/src/fonts/ubuntu-condensed.ts +63 -0
- package/src/fonts/ubuntu-mono.ts +195 -0
- package/src/fonts/ubuntu.ts +195 -0
- package/src/fonts/unbounded.ts +94 -0
- package/src/fonts/unicode-ranges.gen.ts +28 -0
- package/src/fonts/urbanist.ts +50 -0
- package/src/fonts/varela-round.ts +49 -0
- package/src/fonts/vollkorn.ts +199 -0
- package/src/fonts/work-sans.ts +66 -0
- package/src/fonts/yanone-kaffeesatz.ts +128 -0
- package/src/fonts/yantramanav.ts +66 -0
- package/src/fonts/yellowtail.ts +34 -0
- package/src/fonts/young-serif.ts +34 -0
- package/src/fonts/zen-kaku-gothic-new.ts +64 -0
- package/src/fonts/zilla-slab.ts +82 -0
- package/src/form/index.tsx +205 -0
- package/src/generators/index.ts +1589 -0
- package/src/head-client/index.ts +649 -0
- package/src/history/index.ts +210 -0
- package/src/hooks.ts +61 -0
- package/src/hydrate/index.tsx +381 -0
- package/src/hydration/index.ts +187 -0
- package/src/i18n/index.ts +250 -0
- package/src/i18n/jsx.tsx +42 -0
- package/src/i18n/message-format.ts +174 -0
- package/src/image/index.tsx +473 -0
- package/src/image.ts +12 -0
- package/src/intercept-outlet/index.tsx +18 -0
- package/src/intercept-outlet.ts +2 -0
- package/src/internal/index.ts +143 -0
- package/src/internal/once-idle.ts +24 -0
- package/src/internal.ts +12 -0
- package/src/lazy/index.tsx +205 -0
- package/src/link/index.tsx +367 -0
- package/src/loader-pipeline/index.ts +639 -0
- package/src/locale/index.tsx +137 -0
- package/src/locale.ts +3 -0
- package/src/logger.ts +22 -0
- package/src/middleware/builtins/api-proxy.ts +64 -0
- package/src/middleware/builtins/cdn-proxy.ts +58 -0
- package/src/middleware/builtins/i18n.ts +256 -0
- package/src/middleware/builtins/keepalive.ts +24 -0
- package/src/middleware/builtins/markdown-negotiation.ts +141 -0
- package/src/middleware/builtins/static-assets.ts +32 -0
- package/src/middleware/index.ts +223 -0
- package/src/module-graph/index.ts +181 -0
- package/src/mount/index.ts +146 -0
- package/src/navigate.ts +1 -0
- package/src/navigation/index.ts +1278 -0
- package/src/navigation/types.ts +59 -0
- package/src/navigation-progress/index.tsx +247 -0
- package/src/navigation-progress.ts +1 -0
- package/src/ndjson-client/index.ts +376 -0
- package/src/ndjson-server/index.ts +284 -0
- package/src/outlet/index.tsx +633 -0
- package/src/outlet/types.ts +243 -0
- package/src/plugins/css-transform.ts +70 -0
- package/src/plugins/dev-cdn-cache.ts +454 -0
- package/src/plugins/dev-dashboard/client.tsx +2603 -0
- package/src/plugins/dev-dashboard/match-route-tree.ts +159 -0
- package/src/plugins/dev-dashboard/plugin.ts +404 -0
- package/src/plugins/dev-prerender.ts +168 -0
- package/src/plugins/dev-server.ts +327 -0
- package/src/plugins/generate-watch.ts +32 -0
- package/src/plugins/image-plugin.ts +171 -0
- package/src/plugins/index.ts +445 -0
- package/src/plugins/options.ts +37 -0
- package/src/plugins/parse-utils.ts +59 -0
- package/src/plugins/prerender-plugin.ts +144 -0
- package/src/plugins/purge.ts +242 -0
- package/src/plugins/server-fn.ts +641 -0
- package/src/plugins/service-worker.ts +225 -0
- package/src/plugins/solid-jsx.d.ts +12 -0
- package/src/plugins/sx-ast/atomic.ts +166 -0
- package/src/plugins/sx-ast/evaluator.ts +235 -0
- package/src/plugins/sx-ast/index.ts +372 -0
- package/src/plugins/sx-ast/parser.ts +22 -0
- package/src/plugins/sx-ast/rewrite.ts +763 -0
- package/src/plugins/sx.d.ts +14 -0
- package/src/plugins/tw-compile.ts +240 -0
- package/src/plugins/types.ts +41 -0
- package/src/plugins/virtual.d.ts +110 -0
- package/src/plugins/virtual.ts +184 -0
- package/src/preload/index.ts +77 -0
- package/src/prerender/index.ts +431 -0
- package/src/query-client/index.tsx +168 -0
- package/src/registry/index.ts +88 -0
- package/src/reset-css.ts +1 -0
- package/src/revalidation/index.ts +84 -0
- package/src/rewrite/index.ts +83 -0
- package/src/route-builder/create-layout.ts +655 -0
- package/src/route-builder/create-page.ts +806 -0
- package/src/route-builder/create-path-segment.ts +34 -0
- package/src/route-builder/create-root-layout.ts +608 -0
- package/src/route-builder/index.ts +49 -0
- package/src/route-builder/register.ts +242 -0
- package/src/route-builder/types.ts +294 -0
- package/src/router-config/index.ts +91 -0
- package/src/router-primitives/index.ts +25 -0
- package/src/router-primitives/location.ts +29 -0
- package/src/router-primitives/match-id.ts +111 -0
- package/src/router-primitives/paths.ts +109 -0
- package/src/router-primitives/tree.ts +243 -0
- package/src/router-primitives/types.ts +74 -0
- package/src/router.ts +31 -0
- package/src/search-engine/bing.ts +32 -0
- package/src/search-engine/google-jwt.ts +95 -0
- package/src/search-engine/google.ts +139 -0
- package/src/search-engine/index-now.ts +64 -0
- package/src/search-engine/index.ts +12 -0
- package/src/security/index.ts +230 -0
- package/src/server/index.ts +286 -0
- package/src/server-context/browser.ts +113 -0
- package/src/server-context/index.ts +217 -0
- package/src/server-fn/index.ts +710 -0
- package/src/server-fn-query.ts +169 -0
- package/src/server-handler/etag.ts +51 -0
- package/src/server-handler/headers.ts +5 -0
- package/src/server-handler/index.ts +1664 -0
- package/src/server-handler/types.ts +24 -0
- package/src/server-handler/validate-static-params.ts +130 -0
- package/src/server.ts +2 -0
- package/src/service-worker/template.ts +153 -0
- package/src/service-worker-hook/index.ts +70 -0
- package/src/sitemap/index.ts +231 -0
- package/src/ssr/critical-css.ts +150 -0
- package/src/ssr/head-prefix.ts +65 -0
- package/src/ssr/head.ts +259 -0
- package/src/ssr/index.tsx +879 -0
- package/src/state-parser/index.ts +266 -0
- package/src/store/filesystem.ts +131 -0
- package/src/store/index.ts +29 -0
- package/src/styles/index.ts +1200 -0
- package/src/styles/sx-types.ts +11 -0
- package/src/testing/index.ts +251 -0
- package/src/testing.ts +2 -0
- package/src/theme/index.tsx +232 -0
- package/src/theme.ts +3 -0
- package/src/tracing/index.ts +4 -0
- package/src/tracing/noop.ts +13 -0
- package/src/tracing/otel.ts +37 -0
- package/src/tracing/timing.ts +34 -0
- package/src/tracing/types.ts +9 -0
- package/src/url/index.ts +140 -0
- package/src/use-router.ts +11 -0
- package/src/use-suspense-query.ts +2 -0
- package/src/validation/index.ts +57 -0
- package/src/view-transition-css.ts +1 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
export interface HistoryState {
|
|
2
|
+
historyIndex: number;
|
|
3
|
+
key: string;
|
|
4
|
+
params: Record<string, string | string[]>;
|
|
5
|
+
pathname: string;
|
|
6
|
+
scroll?: ScrollPosition;
|
|
7
|
+
search: string;
|
|
8
|
+
state?: unknown;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ScrollPosition {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface HistoryNavigateEvent {
|
|
17
|
+
historyIndex: number;
|
|
18
|
+
key: string;
|
|
19
|
+
params: Record<string, string | string[]>;
|
|
20
|
+
pathname: string;
|
|
21
|
+
scroll?: ScrollPosition;
|
|
22
|
+
search: string;
|
|
23
|
+
state?: unknown;
|
|
24
|
+
type: "popstate";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ScrollStore {
|
|
28
|
+
get(key: string): ScrollPosition | null;
|
|
29
|
+
save(key: string, position: ScrollPosition): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let keyCounter = 0;
|
|
33
|
+
|
|
34
|
+
function generateKey(): string {
|
|
35
|
+
keyCounter = (keyCounter + 1) % Number.MAX_SAFE_INTEGER;
|
|
36
|
+
return `${Date.now().toString(36)}-${keyCounter.toString(36)}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function createHistoryState(
|
|
40
|
+
pathname: string,
|
|
41
|
+
params: Record<string, string | string[]> = {},
|
|
42
|
+
search = "",
|
|
43
|
+
options?: { hash?: string; historyIndex?: number; state?: unknown },
|
|
44
|
+
): HistoryState {
|
|
45
|
+
return {
|
|
46
|
+
historyIndex: options?.historyIndex ?? 0,
|
|
47
|
+
key: generateKey(),
|
|
48
|
+
params,
|
|
49
|
+
pathname,
|
|
50
|
+
search,
|
|
51
|
+
state: options?.state,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function pushHistoryState(
|
|
56
|
+
pathname: string,
|
|
57
|
+
params: Record<string, string | string[]> = {},
|
|
58
|
+
search = "",
|
|
59
|
+
options?: { hash?: string; historyIndex?: number; state?: unknown },
|
|
60
|
+
): HistoryState {
|
|
61
|
+
const state = createHistoryState(pathname, params, search, options);
|
|
62
|
+
const url = `${pathname}${search}${options?.hash ?? ""}`;
|
|
63
|
+
if (typeof history !== "undefined" && history) {
|
|
64
|
+
history.pushState(state, "", url);
|
|
65
|
+
}
|
|
66
|
+
return state;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function replaceHistoryState(
|
|
70
|
+
pathname: string,
|
|
71
|
+
params: Record<string, string | string[]> = {},
|
|
72
|
+
search = "",
|
|
73
|
+
options?: { hash?: string; historyIndex?: number; state?: unknown },
|
|
74
|
+
): HistoryState {
|
|
75
|
+
const state = createHistoryState(pathname, params, search, options);
|
|
76
|
+
const url = `${pathname}${search}${options?.hash ?? ""}`;
|
|
77
|
+
if (typeof history !== "undefined" && history) {
|
|
78
|
+
history.replaceState(state, "", url);
|
|
79
|
+
}
|
|
80
|
+
return state;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function isScrollPosition(raw: unknown): raw is ScrollPosition {
|
|
84
|
+
if (typeof raw !== "object" || raw === null) return false;
|
|
85
|
+
const obj = raw as Record<string, unknown>;
|
|
86
|
+
return typeof obj.x === "number" && typeof obj.y === "number" && Number.isFinite(obj.x) && Number.isFinite(obj.y);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function parseHistoryState(raw: unknown): HistoryState | null {
|
|
90
|
+
if (raw === null || raw === undefined || typeof raw !== "object") return null;
|
|
91
|
+
if (Array.isArray(raw)) return null;
|
|
92
|
+
|
|
93
|
+
const obj = raw as Record<string, unknown>;
|
|
94
|
+
if (typeof obj.pathname !== "string") return null;
|
|
95
|
+
if (typeof obj.key !== "string") return null;
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
historyIndex: typeof obj.historyIndex === "number" ? obj.historyIndex : 0,
|
|
99
|
+
key: obj.key,
|
|
100
|
+
params: (typeof obj.params === "object" && obj.params !== null ? obj.params : {}) as Record<
|
|
101
|
+
string,
|
|
102
|
+
string | string[]
|
|
103
|
+
>,
|
|
104
|
+
pathname: obj.pathname,
|
|
105
|
+
scroll: isScrollPosition(obj.scroll) ? obj.scroll : undefined,
|
|
106
|
+
search: typeof obj.search === "string" ? obj.search : "",
|
|
107
|
+
state: obj.state,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function createHistoryListener(onNavigate: (event: HistoryNavigateEvent) => void): () => void {
|
|
112
|
+
if (typeof addEventListener !== "function") {
|
|
113
|
+
return () => {};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const handler = (event: { state?: unknown }) => {
|
|
117
|
+
const parsed = parseHistoryState(event.state);
|
|
118
|
+
if (!parsed) return;
|
|
119
|
+
onNavigate({
|
|
120
|
+
historyIndex: parsed.historyIndex,
|
|
121
|
+
key: parsed.key,
|
|
122
|
+
params: parsed.params,
|
|
123
|
+
pathname: parsed.pathname,
|
|
124
|
+
scroll: parsed.scroll,
|
|
125
|
+
search: parsed.search,
|
|
126
|
+
state: parsed.state,
|
|
127
|
+
type: "popstate",
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
addEventListener("popstate", handler as EventListener);
|
|
132
|
+
return () => removeEventListener("popstate", handler as EventListener);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const DEFAULT_SCROLL_TTL = 30 * 60 * 1000;
|
|
136
|
+
|
|
137
|
+
export function createScrollStore(maxSize = 200, ttl = DEFAULT_SCROLL_TTL): ScrollStore {
|
|
138
|
+
const store = new Map<string, ScrollPosition>();
|
|
139
|
+
const timestamps = new Map<string, number>();
|
|
140
|
+
|
|
141
|
+
function evictStale(): void {
|
|
142
|
+
const now = Date.now();
|
|
143
|
+
for (const [key, ts] of timestamps) {
|
|
144
|
+
if (now - ts > ttl) {
|
|
145
|
+
store.delete(key);
|
|
146
|
+
timestamps.delete(key);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
get(key: string): ScrollPosition | null {
|
|
153
|
+
return store.get(key) ?? null;
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
save(key: string, position: ScrollPosition): void {
|
|
157
|
+
evictStale();
|
|
158
|
+
if (store.has(key)) {
|
|
159
|
+
store.delete(key);
|
|
160
|
+
timestamps.delete(key);
|
|
161
|
+
}
|
|
162
|
+
store.set(key, position);
|
|
163
|
+
timestamps.set(key, Date.now());
|
|
164
|
+
if (store.size > maxSize) {
|
|
165
|
+
const firstKey = store.keys().next().value;
|
|
166
|
+
if (firstKey !== undefined) {
|
|
167
|
+
store.delete(firstKey);
|
|
168
|
+
timestamps.delete(firstKey);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function getCurrentScroll(): ScrollPosition {
|
|
176
|
+
return {
|
|
177
|
+
x: typeof scrollX === "number" ? scrollX : 0,
|
|
178
|
+
y: typeof scrollY === "number" ? scrollY : 0,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function restoreScroll(position: ScrollPosition, behavior?: ScrollBehavior): void {
|
|
183
|
+
if (typeof scrollTo === "function") {
|
|
184
|
+
scrollTo({ behavior: behavior ?? "auto", left: position.x, top: position.y });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function scrollToTop(): void {
|
|
189
|
+
if (typeof scrollTo === "function") {
|
|
190
|
+
scrollTo(0, 0);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let currentHistoryIndex = 0;
|
|
195
|
+
|
|
196
|
+
export function getHistoryIndex(): number {
|
|
197
|
+
return currentHistoryIndex;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function setHistoryIndex(index: number): void {
|
|
201
|
+
currentHistoryIndex = index;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function incrementHistoryIndex(): void {
|
|
205
|
+
currentHistoryIndex++;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function initHistoryIndex(index: number): void {
|
|
209
|
+
currentHistoryIndex = index;
|
|
210
|
+
}
|
package/src/hooks.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Accessor } from "solid-js";
|
|
2
|
+
import type { ExtractT, Translator } from "./i18n/index.ts";
|
|
3
|
+
import { useRouter } from "./outlet/index.tsx";
|
|
4
|
+
import type { BlockerState, ClientMatch, FlareRouter, ProviderLocation } from "./outlet/types.ts";
|
|
5
|
+
import type {
|
|
6
|
+
RouteLoaderData,
|
|
7
|
+
RoutePathParams,
|
|
8
|
+
RoutePreloaderContext,
|
|
9
|
+
RouteSearchParams,
|
|
10
|
+
RouteVirtualPaths,
|
|
11
|
+
} from "./route-builder/register.ts";
|
|
12
|
+
|
|
13
|
+
export function useBlocker(when: () => boolean): BlockerState {
|
|
14
|
+
return useRouter().useBlocker(when);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useLoaderData<TPath extends RouteVirtualPaths>(options: {
|
|
18
|
+
from: TPath;
|
|
19
|
+
}): Accessor<RouteLoaderData<TPath>> {
|
|
20
|
+
return useRouter().useLoaderData(options);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function useLoaderT<TPath extends RouteVirtualPaths>(options: {
|
|
24
|
+
from: TPath;
|
|
25
|
+
}): Translator<ExtractT<RouteLoaderData<TPath>>> {
|
|
26
|
+
return useRouter().useLoaderT(options);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useLocation(): Accessor<ProviderLocation> {
|
|
30
|
+
return useRouter().location;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function useMatch(options: { from: RouteVirtualPaths }): Accessor<ClientMatch | undefined> {
|
|
34
|
+
return useRouter().useMatch(options);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function useNavigate(): FlareRouter["navigate"] {
|
|
38
|
+
return useRouter().navigate;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function useParams<TPath extends RouteVirtualPaths>(options: { from: TPath }): Accessor<RoutePathParams<TPath>> {
|
|
42
|
+
return useRouter().useParams(options);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function usePreloaderContext<TPath extends RouteVirtualPaths>(options: {
|
|
46
|
+
from: TPath;
|
|
47
|
+
}): Accessor<RoutePreloaderContext<TPath>> {
|
|
48
|
+
return useRouter().usePreloaderContext(options);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function usePreloaderT<TPath extends RouteVirtualPaths>(options: {
|
|
52
|
+
from: TPath;
|
|
53
|
+
}): Translator<ExtractT<RoutePreloaderContext<TPath>>> {
|
|
54
|
+
return useRouter().usePreloaderT(options);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function useSearch<TPath extends RouteVirtualPaths>(options: {
|
|
58
|
+
from: TPath;
|
|
59
|
+
}): Accessor<RouteSearchParams<TPath>> {
|
|
60
|
+
return useRouter().useSearch(options);
|
|
61
|
+
}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/* @refresh skip */
|
|
2
|
+
import swConfig from "virtual:flare-sw-config";
|
|
3
|
+
|
|
4
|
+
declare const __FLARE_IS_DEV__: boolean | undefined;
|
|
5
|
+
const isDevDefault = typeof __FLARE_IS_DEV__ === "boolean" ? __FLARE_IS_DEV__ : false;
|
|
6
|
+
import type { JSX } from "solid-js";
|
|
7
|
+
import { createComponent, render, hydrate as solidHydrate } from "solid-js/web";
|
|
8
|
+
import { createChannel } from "../broadcast/channel.ts";
|
|
9
|
+
import { BroadcastProvider } from "../broadcast/provider.tsx";
|
|
10
|
+
import type { MatchCache } from "../caches/index.ts";
|
|
11
|
+
import { createMatchCache, createPrefetchCache } from "../caches/index.ts";
|
|
12
|
+
import { DirectionProvider } from "../direction.ts";
|
|
13
|
+
import { NotFoundError, UnauthenticatedError, UnauthorizedError } from "../errors/index.ts";
|
|
14
|
+
import { replaceHistoryState } from "../history/index.ts";
|
|
15
|
+
import {
|
|
16
|
+
buildInitialMatches,
|
|
17
|
+
extractRootBoundaries,
|
|
18
|
+
hydrateHeadState,
|
|
19
|
+
loadRouteModules,
|
|
20
|
+
populateMatchCache,
|
|
21
|
+
} from "../hydration/index.ts";
|
|
22
|
+
import { onceIdle } from "../internal/once-idle.ts";
|
|
23
|
+
import { setupNavigation } from "../navigation/index.ts";
|
|
24
|
+
import type { LoadedRouteModule } from "../navigation/types.ts";
|
|
25
|
+
import { FlareProvider, Outlet, useRouter } from "../outlet/index.tsx";
|
|
26
|
+
import type { FlareProviderContext, ProviderLocation, RenderProps } from "../outlet/types.ts";
|
|
27
|
+
import type { LocationRewrite } from "../rewrite/index.ts";
|
|
28
|
+
import { composeRewrites, executeRewriteInput, rewriteBasePath } from "../rewrite/index.ts";
|
|
29
|
+
import type { createRouter, MarkedRouterConfig } from "../router-config/index.ts";
|
|
30
|
+
import {
|
|
31
|
+
hydrateFlareState,
|
|
32
|
+
installDeferredResolver,
|
|
33
|
+
installQueryCacheResolver,
|
|
34
|
+
parseFlareState,
|
|
35
|
+
} from "../state-parser/index.ts";
|
|
36
|
+
import { enableDomInjection, finishHydration } from "../styles/index.ts";
|
|
37
|
+
import { ThemeProvider } from "../theme.ts";
|
|
38
|
+
import { parseSearchParams } from "../url/index.ts";
|
|
39
|
+
|
|
40
|
+
function reconstructError(name: string): Error {
|
|
41
|
+
if (name === "NotFoundError") return new NotFoundError();
|
|
42
|
+
if (name === "UnauthenticatedError") return new UnauthenticatedError();
|
|
43
|
+
if (name === "UnauthorizedError") return new UnauthorizedError();
|
|
44
|
+
const err = new Error();
|
|
45
|
+
err.name = name;
|
|
46
|
+
return err;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface HydrateOptions {
|
|
50
|
+
/** @internal override for testing — auto-resolved from virtual module */
|
|
51
|
+
devOverlay?: boolean;
|
|
52
|
+
onContextReady?: (ctx: FlareProviderContext) => void;
|
|
53
|
+
onHydrated?: () => void;
|
|
54
|
+
onIdle?: () => void;
|
|
55
|
+
onInteraction?: () => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Matches SSR's Hydration component depth.
|
|
60
|
+
* Hydration is a single-child-passthrough, Dummy matches its depth
|
|
61
|
+
* so hydration keys align between SSR and client.
|
|
62
|
+
*/
|
|
63
|
+
function Dummy(props: { children: JSX.Element }): JSX.Element {
|
|
64
|
+
return props.children;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function RootRenderer(props: {
|
|
68
|
+
data: unknown;
|
|
69
|
+
location: ProviderLocation;
|
|
70
|
+
preloaderContext: Record<string, unknown> | undefined;
|
|
71
|
+
renderFn: (p: RenderProps) => JSX.Element;
|
|
72
|
+
}): JSX.Element {
|
|
73
|
+
const router = useRouter();
|
|
74
|
+
return props.renderFn({
|
|
75
|
+
children: <Outlet />,
|
|
76
|
+
loaderData: props.data,
|
|
77
|
+
location: props.location,
|
|
78
|
+
preloaderContext: props.preloaderContext,
|
|
79
|
+
router,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function buildComposedRewrite(r: MarkedRouterConfig): LocationRewrite | undefined {
|
|
84
|
+
const rewrites: LocationRewrite[] = [];
|
|
85
|
+
if (r.basePath) {
|
|
86
|
+
rewrites.push(rewriteBasePath({ basePath: r.basePath, caseSensitive: r.caseSensitive }));
|
|
87
|
+
}
|
|
88
|
+
if (r.rewrite) {
|
|
89
|
+
rewrites.push(r.rewrite);
|
|
90
|
+
}
|
|
91
|
+
if (rewrites.length === 0) return undefined;
|
|
92
|
+
if (rewrites.length === 1) return rewrites[0];
|
|
93
|
+
return composeRewrites(rewrites);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
declare const self: { flare?: unknown };
|
|
97
|
+
|
|
98
|
+
export type RouterArg = MarkedRouterConfig | (() => MarkedRouterConfig | Promise<MarkedRouterConfig>);
|
|
99
|
+
|
|
100
|
+
export async function hydrate(router: RouterArg, options?: HydrateOptions): Promise<void> {
|
|
101
|
+
enableDomInjection();
|
|
102
|
+
const r = typeof router === "function" ? await router() : router;
|
|
103
|
+
const raw = parseFlareState(self.flare);
|
|
104
|
+
if (!raw) return;
|
|
105
|
+
|
|
106
|
+
const state = hydrateFlareState(raw);
|
|
107
|
+
installDeferredResolver(state.resolvers);
|
|
108
|
+
|
|
109
|
+
/* Forward SSR-captured server logs to browser console */
|
|
110
|
+
if (raw.g) {
|
|
111
|
+
const logPrefix = "%c[server]";
|
|
112
|
+
const logStyle = "color:#60a5fa;font-weight:bold";
|
|
113
|
+
const srcStyle = "color:#9ca3af";
|
|
114
|
+
for (const entry of raw.g) {
|
|
115
|
+
const args = Array.isArray(entry.a) ? entry.a : [];
|
|
116
|
+
const prefix = entry.s
|
|
117
|
+
? [logPrefix, logStyle, `%c ${entry.s}`, srcStyle, ...args]
|
|
118
|
+
: [logPrefix, logStyle, ...args];
|
|
119
|
+
switch (entry.l) {
|
|
120
|
+
case "warn":
|
|
121
|
+
console.warn(...prefix);
|
|
122
|
+
break;
|
|
123
|
+
case "error":
|
|
124
|
+
console.error(...prefix);
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
console.log(...prefix);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const matchCache: MatchCache = createMatchCache(r.routeCacheMaxEntries);
|
|
134
|
+
const prefetchCache = createPrefetchCache();
|
|
135
|
+
|
|
136
|
+
populateMatchCache(matchCache, state.matches, raw.ph);
|
|
137
|
+
|
|
138
|
+
if (raw.ph) {
|
|
139
|
+
hydrateHeadState({
|
|
140
|
+
ph: raw.ph.map((h) => ({
|
|
141
|
+
head: { ...h.head },
|
|
142
|
+
matchId: h.matchId,
|
|
143
|
+
})),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Hydrate TanStack Query cache from FlareState.q (spec 33) */
|
|
148
|
+
let QCP: ((props: { children: JSX.Element; client: unknown }) => JSX.Element) | undefined;
|
|
149
|
+
let queryClientInstance: unknown;
|
|
150
|
+
if (r.queryClientGetter) {
|
|
151
|
+
queryClientInstance = r.queryClientGetter();
|
|
152
|
+
const qEntries = raw.q;
|
|
153
|
+
if (qEntries && Array.isArray(qEntries) && qEntries.length > 0) {
|
|
154
|
+
const { hydrateQueryCache } = await import("../query-client");
|
|
155
|
+
hydrateQueryCache(queryClientInstance as Parameters<typeof hydrateQueryCache>[0], qEntries);
|
|
156
|
+
}
|
|
157
|
+
const { QueryClientProvider } = await import("../query-client");
|
|
158
|
+
QCP = QueryClientProvider as typeof QCP;
|
|
159
|
+
installQueryCacheResolver(queryClientInstance);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Build composed rewrite: basePath (if any) + user rewrite */
|
|
163
|
+
const composedRewrite = buildComposedRewrite(r);
|
|
164
|
+
|
|
165
|
+
const hydrateUrl = new URL(state.pathname, "http://localhost");
|
|
166
|
+
const hydratePathname = composedRewrite ? executeRewriteInput(composedRewrite, hydrateUrl).pathname : state.pathname;
|
|
167
|
+
let modules = await loadRouteModules(hydratePathname, r.routeTree, r.layouts, r.caseSensitive, r.locale);
|
|
168
|
+
/* Same fuzzy fallback as the server: unmatched URLs still hydrate the
|
|
169
|
+
root index so NotFoundError from FlareState maps onto `_root_/`
|
|
170
|
+
instead of a greedy `[locale]` param (which would render with no
|
|
171
|
+
loaderData and throw on `.t`). */
|
|
172
|
+
if (!modules && (r.notFoundMode ?? "fuzzy") !== "root") {
|
|
173
|
+
modules = await loadRouteModules("/", r.routeTree, r.layouts, r.caseSensitive, r.locale);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (modules) {
|
|
177
|
+
const search = parseSearchParams(new URL(window.location.href).searchParams);
|
|
178
|
+
const rootLayout = modules.layouts.find((m) => m._type === "root-layout");
|
|
179
|
+
const nonRootLayouts = modules.layouts.filter((m) => m._type !== "root-layout");
|
|
180
|
+
const allModules: LoadedRouteModule[] = [...nonRootLayouts, modules.page];
|
|
181
|
+
|
|
182
|
+
/* Build error map from per-match error names (survives serialization) */
|
|
183
|
+
const errorMap = new Map<string, Error>();
|
|
184
|
+
for (const hm of state.matches) {
|
|
185
|
+
if (hm.errorName) {
|
|
186
|
+
errorMap.set(hm.virtualPath, reconstructError(hm.errorName));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const rootBoundaries = extractRootBoundaries(rootLayout);
|
|
191
|
+
const initialMatches = buildInitialMatches(allModules, matchCache, modules.params, search, errorMap);
|
|
192
|
+
|
|
193
|
+
let resolveCtx: (ctx: FlareProviderContext) => void = () => {};
|
|
194
|
+
const ctxReady = new Promise<FlareProviderContext>((resolve) => {
|
|
195
|
+
resolveCtx = resolve;
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
/* Root layout data from FlareState (populated by SSR) */
|
|
199
|
+
const rootMatchState = rootLayout ? state.matches.find((m) => m.virtualPath === rootLayout.virtualPath) : undefined;
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* Full-document hydration: providers wrap root layout so components
|
|
203
|
+
* inside root layout (e.g. NavigationProgress) have RouterContext.
|
|
204
|
+
*
|
|
205
|
+
* SSR: Hydration > QCP? > Theme > Direction > Broadcast > FlareProvider > rootRenderFn({children: Outlet})
|
|
206
|
+
* Client: Dummy > QCP? > Theme > Direction > Broadcast > FlareProvider > rootRenderFn({children: Outlet})
|
|
207
|
+
*/
|
|
208
|
+
const channel = createChannel();
|
|
209
|
+
const renderInner = () => (
|
|
210
|
+
<ThemeProvider config={r.theme}>
|
|
211
|
+
<DirectionProvider config={r.direction}>
|
|
212
|
+
<BroadcastProvider value={channel}>
|
|
213
|
+
<FlareProvider
|
|
214
|
+
boundaries={rootBoundaries}
|
|
215
|
+
caseSensitive={r.caseSensitive}
|
|
216
|
+
layouts={r.layouts}
|
|
217
|
+
localeConfig={r.locale}
|
|
218
|
+
matchCache={matchCache}
|
|
219
|
+
matches={initialMatches}
|
|
220
|
+
onContextReady={(ctx) => {
|
|
221
|
+
resolveCtx(ctx);
|
|
222
|
+
}}
|
|
223
|
+
params={state.params}
|
|
224
|
+
prefetchCache={prefetchCache}
|
|
225
|
+
resolvers={state.resolvers}
|
|
226
|
+
routerCacheDefaults={r.cache?.client || undefined}
|
|
227
|
+
routeTree={r.routeTree}
|
|
228
|
+
search={search}
|
|
229
|
+
>
|
|
230
|
+
{rootLayout?.render ? (
|
|
231
|
+
<RootRenderer
|
|
232
|
+
data={rootMatchState?.loaderData}
|
|
233
|
+
location={{
|
|
234
|
+
hash: window.location.hash,
|
|
235
|
+
params: state.params,
|
|
236
|
+
pathname: state.pathname,
|
|
237
|
+
search,
|
|
238
|
+
url: new URL(window.location.href),
|
|
239
|
+
variablePath: "",
|
|
240
|
+
virtualPath: rootLayout.virtualPath,
|
|
241
|
+
}}
|
|
242
|
+
preloaderContext={rootMatchState?.preloaderContext}
|
|
243
|
+
renderFn={rootLayout.render}
|
|
244
|
+
/>
|
|
245
|
+
) : (
|
|
246
|
+
<Outlet />
|
|
247
|
+
)}
|
|
248
|
+
</FlareProvider>
|
|
249
|
+
</BroadcastProvider>
|
|
250
|
+
</DirectionProvider>
|
|
251
|
+
</ThemeProvider>
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
solidHydrate(
|
|
255
|
+
() => (
|
|
256
|
+
<Dummy>
|
|
257
|
+
{QCP && queryClientInstance
|
|
258
|
+
? createComponent(QCP, {
|
|
259
|
+
get children() {
|
|
260
|
+
return renderInner();
|
|
261
|
+
},
|
|
262
|
+
client: queryClientInstance,
|
|
263
|
+
})
|
|
264
|
+
: renderInner()}
|
|
265
|
+
</Dummy>
|
|
266
|
+
),
|
|
267
|
+
document,
|
|
268
|
+
);
|
|
269
|
+
finishHydration();
|
|
270
|
+
|
|
271
|
+
replaceHistoryState(window.location.pathname, state.params, window.location.search, {
|
|
272
|
+
hash: window.location.hash,
|
|
273
|
+
historyIndex: 0,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
if (options?.onHydrated) {
|
|
277
|
+
options.onHydrated();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (options?.onIdle) {
|
|
281
|
+
const cb = options.onIdle;
|
|
282
|
+
if (typeof requestIdleCallback === "function") {
|
|
283
|
+
requestIdleCallback(() => cb());
|
|
284
|
+
} else {
|
|
285
|
+
setTimeout(cb, 0);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (options?.onInteraction) {
|
|
290
|
+
const cb = options.onInteraction;
|
|
291
|
+
const events = ["mousemove", "touchstart", "scroll", "keydown"] as const;
|
|
292
|
+
const handler = () => {
|
|
293
|
+
for (const e of events) removeEventListener(e, handler, { capture: true });
|
|
294
|
+
cb();
|
|
295
|
+
};
|
|
296
|
+
for (const e of events) {
|
|
297
|
+
addEventListener(e, handler, { capture: true, once: true, passive: true });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const providerCtx = await ctxReady;
|
|
302
|
+
|
|
303
|
+
if (options?.onContextReady) {
|
|
304
|
+
options.onContextReady(providerCtx);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const initialRouteIds = allModules.map((mod) => mod.virtualPath);
|
|
308
|
+
if (rootLayout) initialRouteIds.push(rootLayout.virtualPath);
|
|
309
|
+
|
|
310
|
+
setupNavigation(
|
|
311
|
+
providerCtx,
|
|
312
|
+
async (pathname, tree, lyts) => {
|
|
313
|
+
const result = await loadRouteModules(
|
|
314
|
+
pathname,
|
|
315
|
+
tree as ReturnType<typeof createRouter>["routeTree"],
|
|
316
|
+
lyts,
|
|
317
|
+
r.caseSensitive,
|
|
318
|
+
r.locale,
|
|
319
|
+
);
|
|
320
|
+
if (!result)
|
|
321
|
+
throw new Error(
|
|
322
|
+
`No route modules found for "${pathname}". Verify the route file exists and the build completed successfully.`,
|
|
323
|
+
);
|
|
324
|
+
return result;
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
caseSensitive: r.caseSensitive,
|
|
328
|
+
direction: r.direction,
|
|
329
|
+
initialRouteIds,
|
|
330
|
+
keepalive: (raw.c.router as Record<string, unknown> | undefined)?.keepalive as false | number | undefined,
|
|
331
|
+
locale: r.locale,
|
|
332
|
+
notFoundMode: r.notFoundMode ?? "fuzzy",
|
|
333
|
+
queryClient: queryClientInstance,
|
|
334
|
+
rewrite: composedRewrite,
|
|
335
|
+
scrollRestoration: r.scrollRestoration,
|
|
336
|
+
scrollRestorationBehavior: r.scrollRestorationBehavior,
|
|
337
|
+
scrollRestorationMaxEntries: r.scrollRestorationMaxEntries,
|
|
338
|
+
viewTransitions: r.viewTransitions ?? false,
|
|
339
|
+
},
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const showDevOverlay = options?.devOverlay ?? isDevDefault;
|
|
343
|
+
if (showDevOverlay) {
|
|
344
|
+
const { DevErrorOverlay } = await import("../components/dev-error-overlay");
|
|
345
|
+
let overlayRoot = document.getElementById("flare-dev-overlay-root");
|
|
346
|
+
if (!overlayRoot) {
|
|
347
|
+
overlayRoot = document.createElement("div");
|
|
348
|
+
overlayRoot.id = "flare-dev-overlay-root";
|
|
349
|
+
document.body.appendChild(overlayRoot);
|
|
350
|
+
}
|
|
351
|
+
overlayRoot.textContent = "";
|
|
352
|
+
render(() => <DevErrorOverlay />, overlayRoot);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
document.documentElement.setAttribute("data-hydrated", "");
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/* Service worker registration / unregistration */
|
|
359
|
+
if ("serviceWorker" in navigator) {
|
|
360
|
+
if ((swConfig as { enabled: boolean }).enabled) {
|
|
361
|
+
const cfg = swConfig as { enabled: boolean; path: string; scope: string };
|
|
362
|
+
onceIdle(() => {
|
|
363
|
+
navigator.serviceWorker
|
|
364
|
+
.register(cfg.path, {
|
|
365
|
+
scope: cfg.scope,
|
|
366
|
+
updateViaCache: "none" as ServiceWorkerUpdateViaCache,
|
|
367
|
+
})
|
|
368
|
+
.catch(() => {});
|
|
369
|
+
});
|
|
370
|
+
} else {
|
|
371
|
+
onceIdle(() => {
|
|
372
|
+
navigator.serviceWorker
|
|
373
|
+
.getRegistrations()
|
|
374
|
+
.then((regs) => {
|
|
375
|
+
for (const reg of regs) reg.unregister();
|
|
376
|
+
})
|
|
377
|
+
.catch(() => {});
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|