@netrojs/fnetro 0.1.6 → 0.2.1

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/dist/server.d.ts CHANGED
@@ -1,231 +1,172 @@
1
1
  import { Hono, MiddlewareHandler, Context } from 'hono';
2
+ import { Component, JSX } from 'solid-js';
2
3
  import { Plugin } from 'vite';
3
4
 
4
- type EffectFn = () => void | (() => void);
5
- declare const IS_REF: unique symbol;
6
- declare class ReactiveEffect {
7
- fn: () => any;
8
- scheduler?: (() => void) | undefined;
9
- scope?: EffectScope | undefined;
10
- deps: Set<ReactiveEffect>[];
11
- active: boolean;
12
- cleanup?: () => void;
13
- computed: boolean;
14
- constructor(fn: () => any, scheduler?: (() => void) | undefined, scope?: EffectScope | undefined);
15
- run(): any;
16
- stop(): void;
17
- }
18
- declare class EffectScope {
19
- effects: ReactiveEffect[];
20
- cleanups: (() => void)[];
21
- active: boolean;
22
- run<T>(fn: () => T): T;
23
- stop(): void;
24
- onCleanup(fn: () => void): void;
25
- }
26
- declare function effectScope(): EffectScope;
27
- declare function effect(fn: EffectFn): () => void;
28
- interface WatchEffectOptions {
29
- flush?: 'sync' | 'post';
30
- onTrack?: (e: any) => void;
31
- onTrigger?: (e: any) => void;
32
- }
33
- declare function watchEffect(fn: EffectFn, opts?: WatchEffectOptions): () => void;
34
- interface Ref<T = unknown> {
35
- value: T;
36
- readonly [IS_REF]: true;
37
- }
38
- declare function ref<T>(value: T): Ref<T>;
39
- declare function shallowRef<T>(value: T): Ref<T>;
40
- declare function triggerRef(r: Ref): void;
41
- declare function isRef<T = unknown>(r: unknown): r is Ref<T>;
42
- declare function unref<T>(r: T | Ref<T>): T;
43
- declare function toRef<T extends object, K extends keyof T>(obj: T, key: K): Ref<T[K]>;
44
- declare function toRefs<T extends object>(obj: T): {
45
- [K in keyof T]: Ref<T[K]>;
46
- };
47
- interface WritableComputedRef<T> extends Ref<T> {
48
- readonly effect: ReactiveEffect;
49
- }
50
- interface ComputedRef<T> extends WritableComputedRef<T> {
51
- readonly value: T;
52
- }
53
- declare function computed<T>(getter: () => T): ComputedRef<T>;
54
- declare function computed<T>(opts: {
55
- get: () => T;
56
- set: (v: T) => void;
57
- }): WritableComputedRef<T>;
58
- declare function reactive<T extends object>(target: T): T;
59
- declare function shallowReactive<T extends object>(target: T): T;
60
- declare function readonly<T extends object>(target: T): Readonly<T>;
61
- declare function markRaw<T extends object>(value: T): T;
62
- declare function toRaw<T>(observed: T): T;
63
- declare function isReactive(value: unknown): boolean;
64
- declare function isReadonly(value: unknown): boolean;
65
- type WatchSource<T = unknown> = Ref<T> | ComputedRef<T> | (() => T);
66
- type MultiSource = WatchSource[] | readonly WatchSource[];
67
- type MapSources<T, Immediate = false> = {
68
- [K in keyof T]: T[K] extends WatchSource<infer V> ? Immediate extends true ? V | undefined : V : T[K] extends object ? T[K] : never;
5
+ type HonoMiddleware = MiddlewareHandler;
6
+ type LoaderCtx = Context;
7
+ interface SEOMeta {
8
+ title?: string;
9
+ description?: string;
10
+ keywords?: string;
11
+ author?: string;
12
+ robots?: string;
13
+ canonical?: string;
14
+ themeColor?: string;
15
+ ogTitle?: string;
16
+ ogDescription?: string;
17
+ ogImage?: string;
18
+ ogImageAlt?: string;
19
+ ogImageWidth?: string;
20
+ ogImageHeight?: string;
21
+ ogUrl?: string;
22
+ ogType?: string;
23
+ ogSiteName?: string;
24
+ ogLocale?: string;
25
+ twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player';
26
+ twitterSite?: string;
27
+ twitterCreator?: string;
28
+ twitterTitle?: string;
29
+ twitterDescription?: string;
30
+ twitterImage?: string;
31
+ twitterImageAlt?: string;
32
+ jsonLd?: Record<string, unknown> | Record<string, unknown>[];
33
+ extra?: Array<{
34
+ name?: string;
35
+ property?: string;
36
+ httpEquiv?: string;
37
+ content: string;
38
+ }>;
39
+ }
40
+ type PageProps<TData extends object = {}> = TData & {
41
+ url: string;
42
+ params: Record<string, string>;
69
43
  };
70
- interface WatchOptions<Immediate = boolean> {
71
- immediate?: Immediate;
72
- deep?: boolean;
73
- once?: boolean;
44
+ interface LayoutProps {
45
+ children: JSX.Element;
46
+ url: string;
47
+ params: Record<string, string>;
74
48
  }
75
- type StopHandle = () => void;
76
- type CleanupFn = (fn: () => void) => void;
77
- declare function watch<T>(source: WatchSource<T>, cb: (val: T, old: T | undefined, cleanup: CleanupFn) => void, opts?: WatchOptions): StopHandle;
78
- declare function watch<T extends MultiSource>(source: T, cb: (val: MapSources<T>, old: MapSources<T, true>, cleanup: CleanupFn) => void, opts?: WatchOptions): StopHandle;
79
- /**
80
- * Subscribe to a Ref or computed getter inside a JSX component.
81
- * On the server, returns the current value (no reactivity needed).
82
- * On the client, re-renders the component whenever the value changes.
83
- *
84
- * @example
85
- * const count = ref(0)
86
- * function Counter() {
87
- * const n = use(count)
88
- * return <button onClick={() => count.value++}>{n}</button>
89
- * }
90
- */
91
- declare function use<T>(source: Ref<T> | (() => T)): T;
92
- /**
93
- * Create a component-local reactive Ref.
94
- * Unlike module-level `ref()`, this is scoped to the component lifecycle.
95
- *
96
- * @example
97
- * function Input() {
98
- * const text = useLocalRef('')
99
- * return <input value={use(text)} onInput={e => text.value = e.target.value} />
100
- * }
101
- */
102
- declare function useLocalRef<T>(init: T): Ref<T>;
103
- /**
104
- * Create a component-local reactive object.
105
- * @example
106
- * function Form() {
107
- * const form = useLocalReactive({ name: '', email: '' })
108
- * return <input value={form.name} onInput={e => form.name = e.target.value} />
109
- * }
110
- */
111
- declare function useLocalReactive<T extends object>(init: T): T;
112
- type LoaderCtx = Context;
113
- type FNetroMiddleware = MiddlewareHandler;
114
- type AnyJSX = any;
115
49
  interface PageDef<TData extends object = {}> {
116
50
  readonly __type: 'page';
117
51
  path: string;
118
- /** Middleware applied only to this route */
119
- middleware?: FNetroMiddleware[];
120
- /** Server-side data loader. Return value becomes Page props. */
52
+ middleware?: HonoMiddleware[];
121
53
  loader?: (c: LoaderCtx) => TData | Promise<TData>;
122
- /** Override the group/app layout for this page. Pass `false` to use no layout. */
54
+ seo?: SEOMeta | ((data: TData, params: Record<string, string>) => SEOMeta);
123
55
  layout?: LayoutDef | false;
124
- /** The JSX page component */
125
- Page: (props: TData & {
126
- url: string;
127
- params: Record<string, string>;
128
- }) => AnyJSX;
56
+ Page: Component<PageProps<TData>>;
129
57
  }
130
58
  interface GroupDef {
131
59
  readonly __type: 'group';
132
- /** URL prefix — e.g. '/admin' */
133
60
  prefix: string;
134
- /** Layout override for all pages in this group */
135
61
  layout?: LayoutDef | false;
136
- /** Middleware applied to every route in the group */
137
- middleware?: FNetroMiddleware[];
138
- /** Pages and nested groups */
139
- routes: (PageDef<any> | GroupDef | ApiRouteDef)[];
62
+ middleware?: HonoMiddleware[];
63
+ routes: Route[];
140
64
  }
141
65
  interface LayoutDef {
142
66
  readonly __type: 'layout';
143
- Component: (props: {
144
- children: AnyJSX;
145
- url: string;
146
- params: Record<string, string>;
147
- }) => AnyJSX;
67
+ Component: Component<LayoutProps>;
148
68
  }
149
69
  interface ApiRouteDef {
150
70
  readonly __type: 'api';
151
- /** Mount path — e.g. '/api' or '/api/admin' */
152
71
  path: string;
153
- /** Register raw Hono routes on the provided sub-app */
154
- register: (app: Hono, middleware: FNetroMiddleware[]) => void;
155
- }
156
- interface MiddlewareDef {
157
- readonly __type: 'middleware';
158
- handler: FNetroMiddleware;
72
+ register: (app: Hono, globalMiddleware: HonoMiddleware[]) => void;
159
73
  }
74
+ type Route = PageDef<any> | GroupDef | ApiRouteDef;
160
75
  interface AppConfig {
161
- /** Default layout for all pages */
162
76
  layout?: LayoutDef;
163
- /** Global middleware applied before every route */
164
- middleware?: FNetroMiddleware[];
165
- /** Top-level routes, groups, and API routes */
166
- routes: (PageDef<any> | GroupDef | ApiRouteDef)[];
167
- /** 404 page */
168
- notFound?: () => AnyJSX;
169
- }
77
+ seo?: SEOMeta;
78
+ middleware?: HonoMiddleware[];
79
+ routes: Route[];
80
+ notFound?: Component;
81
+ htmlAttrs?: Record<string, string>;
82
+ head?: string;
83
+ }
84
+ type ClientMiddleware = (url: string, next: () => Promise<void>) => Promise<void>;
170
85
  declare function definePage<TData extends object = {}>(def: Omit<PageDef<TData>, '__type'>): PageDef<TData>;
171
86
  declare function defineGroup(def: Omit<GroupDef, '__type'>): GroupDef;
172
- declare function defineLayout(Component: LayoutDef['Component']): LayoutDef;
173
- declare function defineMiddleware(handler: FNetroMiddleware): MiddlewareDef;
87
+ declare function defineLayout(Component: Component<LayoutProps>): LayoutDef;
174
88
  declare function defineApiRoute(path: string, register: ApiRouteDef['register']): ApiRouteDef;
89
+ interface ResolvedRoute {
90
+ fullPath: string;
91
+ page: PageDef<any>;
92
+ layout: LayoutDef | false | undefined;
93
+ middleware: HonoMiddleware[];
94
+ }
95
+ declare function resolveRoutes(routes: Route[], options?: {
96
+ prefix?: string;
97
+ middleware?: HonoMiddleware[];
98
+ layout?: LayoutDef | false;
99
+ }): {
100
+ pages: ResolvedRoute[];
101
+ apis: ApiRouteDef[];
102
+ };
103
+ interface CompiledPath {
104
+ re: RegExp;
105
+ keys: string[];
106
+ }
107
+ declare function compilePath(path: string): CompiledPath;
108
+ declare function matchPath(compiled: CompiledPath, pathname: string): Record<string, string> | null;
175
109
  declare const SPA_HEADER = "x-fnetro-spa";
176
110
  declare const STATE_KEY = "__FNETRO_STATE__";
111
+ declare const PARAMS_KEY = "__FNETRO_PARAMS__";
112
+ declare const SEO_KEY = "__FNETRO_SEO__";
177
113
 
114
+ interface AssetConfig {
115
+ /** Explicit script URLs injected into every HTML page. */
116
+ scripts?: string[];
117
+ /** Explicit stylesheet URLs injected into every HTML page. */
118
+ styles?: string[];
119
+ /**
120
+ * Directory that contains the Vite-generated `manifest.json`.
121
+ * When provided, asset URLs are resolved from the manifest so hashed
122
+ * filenames work correctly. Typically equals `clientOutDir`.
123
+ */
124
+ manifestDir?: string;
125
+ /**
126
+ * Key in the manifest corresponding to the client entry file.
127
+ * @default `'client.ts'`
128
+ */
129
+ manifestEntry?: string;
130
+ }
131
+ interface FNetroOptions extends AppConfig {
132
+ /**
133
+ * Production asset configuration.
134
+ * In dev mode `@hono/vite-dev-server` injects assets automatically — ignored.
135
+ */
136
+ assets?: AssetConfig;
137
+ }
178
138
  interface FNetroApp {
179
- /** The underlying Hono instance — add raw routes, custom error handlers, etc. */
139
+ /** The underlying Hono instance — attach custom routes, error handlers, etc. */
180
140
  app: Hono;
181
- /** Hono fetch handler — export this as default for edge runtimes */
182
- handler: Hono['fetch'];
141
+ /** Fetch handler for edge runtimes */
142
+ handler: typeof Hono.prototype.fetch;
183
143
  }
184
- declare function createFNetro(config: AppConfig): FNetroApp;
185
- type Runtime = 'node' | 'bun' | 'deno' | 'edge' | 'unknown';
144
+ declare function createFNetro(config: FNetroOptions): FNetroApp;
145
+ type Runtime = 'node' | 'bun' | 'deno' | 'edge';
186
146
  declare function detectRuntime(): Runtime;
187
147
  interface ServeOptions {
188
148
  app: FNetroApp;
189
149
  port?: number;
190
150
  hostname?: string;
191
- /** Override auto-detected runtime. */
192
151
  runtime?: Runtime;
193
- /** Static assets root directory (served at /assets/*). @default './dist' */
152
+ /** Root directory for static file serving. @default `'./dist'` */
194
153
  staticDir?: string;
195
154
  }
196
155
  declare function serve(opts: ServeOptions): Promise<void>;
197
156
  interface FNetroPluginOptions {
198
- /**
199
- * Server entry file (exports the Hono app / calls serve()).
200
- * @default 'app/server.ts'
201
- */
157
+ /** Server entry file. @default `'server.ts'` */
202
158
  serverEntry?: string;
203
- /**
204
- * Client entry file (calls boot()).
205
- * @default 'app/client.ts'
206
- */
159
+ /** Client entry file. @default `'client.ts'` */
207
160
  clientEntry?: string;
208
- /**
209
- * Output directory for the server bundle.
210
- * @default 'dist/server'
211
- */
161
+ /** Server bundle output directory. @default `'dist/server'` */
212
162
  serverOutDir?: string;
213
- /**
214
- * Output directory for client assets (JS, CSS).
215
- * @default 'dist/assets'
216
- */
163
+ /** Client assets output directory. @default `'dist/assets'` */
217
164
  clientOutDir?: string;
218
- /**
219
- * External packages for the server bundle.
220
- * Node built-ins are always external.
221
- */
165
+ /** Extra packages to mark external in the server bundle. */
222
166
  serverExternal?: string[];
223
- /**
224
- * Emit type declarations for framework types.
225
- * @default false
226
- */
227
- dts?: boolean;
167
+ /** Extra options forwarded to `vite-plugin-solid`. */
168
+ solidOptions?: Record<string, unknown>;
228
169
  }
229
170
  declare function fnetroVitePlugin(opts?: FNetroPluginOptions): Plugin[];
230
171
 
231
- export { type AnyJSX, type ApiRouteDef, type AppConfig, type ComputedRef, type FNetroApp, type FNetroMiddleware, type FNetroPluginOptions, type GroupDef, type LayoutDef, type LoaderCtx, type MiddlewareDef, type PageDef, type Ref, type Runtime, SPA_HEADER, STATE_KEY, type ServeOptions, type WatchOptions, type WatchSource, type WritableComputedRef, computed, createFNetro, defineApiRoute, defineGroup, defineLayout, defineMiddleware, definePage, detectRuntime, effect, effectScope, fnetroVitePlugin, isReactive, isReadonly, isRef, markRaw, reactive, readonly, ref, serve, shallowReactive, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, use, useLocalReactive, useLocalRef, watch, watchEffect };
172
+ export { type ApiRouteDef, type AppConfig, type AssetConfig, type ClientMiddleware, type CompiledPath, type FNetroApp, type FNetroOptions, type FNetroPluginOptions, type GroupDef, type HonoMiddleware, type LayoutDef, type LayoutProps, type LoaderCtx, PARAMS_KEY, type PageDef, type PageProps, type ResolvedRoute, type Route, type Runtime, type SEOMeta, SEO_KEY, SPA_HEADER, STATE_KEY, type ServeOptions, compilePath, createFNetro, defineApiRoute, defineGroup, defineLayout, definePage, detectRuntime, fnetroVitePlugin, matchPath, resolveRoutes, serve };