@netrojs/fnetro 0.2.20 → 0.3.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/types.ts ADDED
@@ -0,0 +1,125 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // FNetro · types.ts
3
+ // All shared TypeScript types and runtime constants
4
+ // ─────────────────────────────────────────────────────────────────────────────
5
+
6
+ import type { Component } from 'vue'
7
+ import type { Context, MiddlewareHandler, Hono } from 'hono'
8
+
9
+ export type HonoMiddleware = MiddlewareHandler
10
+ export type LoaderCtx = Context
11
+
12
+ // ── SEO ───────────────────────────────────────────────────────────────────────
13
+
14
+ export interface SEOMeta {
15
+ title?: string
16
+ description?: string
17
+ keywords?: string
18
+ author?: string
19
+ robots?: string
20
+ canonical?: string
21
+ themeColor?: string
22
+ ogTitle?: string
23
+ ogDescription?: string
24
+ ogImage?: string
25
+ ogImageAlt?: string
26
+ ogUrl?: string
27
+ ogType?: string
28
+ ogSiteName?: string
29
+ twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player'
30
+ twitterSite?: string
31
+ twitterTitle?: string
32
+ twitterDescription?: string
33
+ twitterImage?: string
34
+ /** Structured data injected as <script type="application/ld+json">. */
35
+ jsonLd?: Record<string, unknown> | Record<string, unknown>[]
36
+ }
37
+
38
+ // ── Async component loader — enables automatic code splitting ─────────────────
39
+ //
40
+ // Pass () => import('./Page.vue') as `component` for lazy loading + splitting.
41
+ // The server resolves the import before rendering; the client wraps it in
42
+ // defineAsyncComponent() so the page chunk is lazy-loaded after hydration.
43
+
44
+ export type AsyncLoader = () => Promise<{ default: Component } | Component>
45
+
46
+ // ── Route definition types ────────────────────────────────────────────────────
47
+
48
+ export interface PageDef<TData extends object = Record<string, never>> {
49
+ readonly __type: 'page'
50
+ path: string
51
+ middleware?: HonoMiddleware[]
52
+ loader?: (c: LoaderCtx) => TData | Promise<TData>
53
+ seo?: SEOMeta | ((data: TData, params: Record<string, string>) => SEOMeta)
54
+ /** Override or disable the app-level layout for this route. */
55
+ layout?: LayoutDef | false
56
+ /**
57
+ * The Vue component to render for this route.
58
+ * Use () => import('./Page.vue') for automatic code splitting.
59
+ */
60
+ component: Component | AsyncLoader
61
+ }
62
+
63
+ export interface GroupDef {
64
+ readonly __type: 'group'
65
+ prefix: string
66
+ layout?: LayoutDef | false
67
+ middleware?: HonoMiddleware[]
68
+ routes: Route[]
69
+ }
70
+
71
+ export interface LayoutDef {
72
+ readonly __type: 'layout'
73
+ /** Vue layout component — must contain <slot /> for page content. */
74
+ component: Component
75
+ }
76
+
77
+ export interface ApiRouteDef {
78
+ readonly __type: 'api'
79
+ path: string
80
+ register: (app: Hono, globalMiddleware: HonoMiddleware[]) => void
81
+ }
82
+
83
+ export type Route = PageDef<any> | GroupDef | ApiRouteDef
84
+
85
+ export interface AppConfig {
86
+ layout?: LayoutDef
87
+ seo?: SEOMeta
88
+ middleware?: HonoMiddleware[]
89
+ routes: Route[]
90
+ notFound?: Component
91
+ htmlAttrs?: Record<string, string>
92
+ /** Extra HTML injected into <head> (e.g. font preloads). */
93
+ head?: string
94
+ }
95
+
96
+ export interface ResolvedRoute {
97
+ fullPath: string
98
+ page: PageDef<any>
99
+ layout: LayoutDef | false | undefined
100
+ middleware: HonoMiddleware[]
101
+ }
102
+
103
+ export interface CompiledPath {
104
+ re: RegExp
105
+ keys: string[]
106
+ }
107
+
108
+ export type ClientMiddleware = (url: string, next: () => Promise<void>) => Promise<void>
109
+
110
+ // ── Shared runtime constants ──────────────────────────────────────────────────
111
+
112
+ /** Custom request header that identifies an SPA navigation (JSON payload). */
113
+ export const SPA_HEADER = 'x-fnetro-spa'
114
+ /** window key for SSR-injected per-page loader data. */
115
+ export const STATE_KEY = '__FNETRO_STATE__'
116
+ /** window key for SSR-injected URL params. */
117
+ export const PARAMS_KEY = '__FNETRO_PARAMS__'
118
+ /** window key for SSR-injected SEO meta. */
119
+ export const SEO_KEY = '__FNETRO_SEO__'
120
+
121
+ /**
122
+ * Vue provide/inject key for the reactive page-data object.
123
+ * Symbol.for() ensures the same reference across module instances (SSR safe).
124
+ */
125
+ export const DATA_KEY = Symbol.for('fnetro:data')