@troyio/vite-file-router 0.3.2 → 0.4.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.
@@ -0,0 +1,9 @@
1
+ import { type Node } from "./scanner";
2
+ export declare const PACKAGE_NAME = "@troyio/vite-file-router";
3
+ /**
4
+ * Builds a declaration file that registers the discovered page patterns and
5
+ * loader modules with the package's `Register` interface. The package's
6
+ * public types read from that interface, so `routePath()` and the typed hooks
7
+ * only accept routes that exist.
8
+ */
9
+ export declare function createRouteDeclarations(tree: Node, projectRoot: string, declarationFile: string): string;
@@ -0,0 +1,59 @@
1
+ import { type RouteMatchResult } from "./devtools";
2
+ import type { RouteManifestNode } from "./scanner";
3
+ /** HMR events the dev-only client in `virtual:routes` sends to the server. */
4
+ export declare const APP_LOCATION_EVENT = "vite-file-router:location";
5
+ export declare const APP_DATA_EVENT = "vite-file-router:data";
6
+ /** An open browser tab running the app, and the route it's on. */
7
+ export type AppTab = {
8
+ id: string;
9
+ url: string;
10
+ title: string;
11
+ connectedAt: number;
12
+ updatedAt: number;
13
+ match: RouteMatchResult;
14
+ };
15
+ export type RouteDataOutcome = "data" | "response" | "redirect" | "error";
16
+ /** One loader, action, or `shouldRevalidate` call reported by the app. */
17
+ export type RouteDataEvent = {
18
+ /** Increasing number, unique for this dev-server session. */
19
+ id: number;
20
+ tabId: string;
21
+ type: "loader" | "action" | "revalidate";
22
+ /** React Router route ID, `file-route:` plus the route directory. */
23
+ routeId: string;
24
+ url?: string;
25
+ method?: string;
26
+ startedAt: number;
27
+ duration?: number;
28
+ outcome?: RouteDataOutcome;
29
+ status?: number;
30
+ location?: string;
31
+ message?: string;
32
+ /** A short JSON preview of returned data. */
33
+ preview?: string;
34
+ /** For `revalidate` events: whether the loader runs. */
35
+ decision?: boolean;
36
+ defaultShouldRevalidate?: boolean;
37
+ };
38
+ /**
39
+ * Validates an event from the browser. Anything a page sends over the HMR
40
+ * channel is untrusted, so only known fields of the expected types are kept.
41
+ */
42
+ export declare function sanitizeDataEvent(input: unknown, id: number): RouteDataEvent | undefined;
43
+ /**
44
+ * Tracks the app tabs connected to the dev server and their recent loader
45
+ * and action calls, and tells the panel when either changes.
46
+ */
47
+ export declare function createAppTracker(options: {
48
+ getManifest: () => RouteManifestNode;
49
+ onTabsChange: (tabs: AppTab[]) => void;
50
+ onActivity: (event: RouteDataEvent) => void;
51
+ }): {
52
+ tabs: () => AppTab[];
53
+ activity: () => RouteDataEvent[];
54
+ updateLocation(client: object, input: unknown): Promise<void>;
55
+ disconnect(client: object): void;
56
+ /** Re-matches every tab, for example after route files change. */
57
+ rematch(): Promise<void>;
58
+ record(input: unknown): void;
59
+ };
@@ -0,0 +1,50 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { RouteConflict } from "./generator";
3
+ import type { RouteFileKind, RouteManifestNode } from "./scanner";
4
+ export declare const ROUTE_INSPECTOR_PATH = "/__vite-file-router/";
5
+ export declare const ROUTE_INSPECTOR_DATA_PATH = "/__vite-file-router-data";
6
+ export declare const ROUTE_INSPECTOR_EVENTS_PATH = "/__vite-file-router-events";
7
+ export declare const ROUTE_INSPECTOR_MATCH_PATH = "/__vite-file-router-match";
8
+ export type RouteInspectorState = {
9
+ /** Absolute Vite project root, so the panel can open files in an editor. */
10
+ projectRoot: string;
11
+ /** The routes directory, relative to the project root with `/` separators. */
12
+ directory: string;
13
+ manifest: RouteManifestNode;
14
+ conflicts: RouteConflict[];
15
+ };
16
+ export type RouteMatchSegment = {
17
+ fullPath: string;
18
+ segment: string | null;
19
+ routeGroup: boolean;
20
+ files: Partial<Record<RouteFileKind, string>>;
21
+ };
22
+ export type RouteMatchResult = {
23
+ matched: false;
24
+ pathname: string;
25
+ } | {
26
+ matched: true;
27
+ pathname: string;
28
+ params: Record<string, string | undefined>;
29
+ /** Directory routes from the root down to the matched route. */
30
+ chain: RouteMatchSegment[];
31
+ page?: string;
32
+ notFound?: string;
33
+ layouts: string[];
34
+ loaders: string[];
35
+ loading?: string;
36
+ error?: string;
37
+ };
38
+ export declare function matchRouteManifest(manifest: RouteManifestNode, url: string): Promise<RouteMatchResult>;
39
+ /** Pushes route state to open DevTools panels over Server-Sent Events. */
40
+ export declare function createRouteEventStream(getState: () => RouteInspectorState,
41
+ /** Extra events sent to each panel when it connects. */
42
+ getSnapshot?: () => [event: string, data: unknown][]): {
43
+ clients: Set<ServerResponse<IncomingMessage>>;
44
+ connect(request: IncomingMessage, response: ServerResponse): void;
45
+ /** Coalesces bursts of file events (such as a folder rename) into one push. */
46
+ notify(): void;
47
+ /** Sends a named event to every connected panel right away. */
48
+ broadcast(event: string, data: unknown): void;
49
+ close(): void;
50
+ };
@@ -1,8 +1,20 @@
1
1
  import { type Node } from "./scanner";
2
+ export type GenerateOptions = {
3
+ /**
4
+ * Add a client that reports the app's location and its loader and action
5
+ * calls to the DevTools panel over Vite's HMR channel. Dev server only.
6
+ */
7
+ devClient?: boolean;
8
+ };
2
9
  export type GeneratedRoutes = {
3
10
  imports: string[];
4
11
  helpers: string[];
5
12
  routes: string;
13
+ /**
14
+ * A tree that mirrors `routes`: each node lists the modules a matched route
15
+ * needs to render, so `preloadRoute()` can import them ahead of navigation.
16
+ */
17
+ preloads: string;
6
18
  };
7
19
  export type RouteConflict = {
8
20
  routePath: string;
@@ -13,4 +25,5 @@ export declare class RouteConflictError extends Error {
13
25
  constructor(conflicts: RouteConflict[]);
14
26
  }
15
27
  export declare function findPageRouteConflicts(node: Node, pages?: Map<string, string[]>, segments?: string[], root?: boolean): RouteConflict[];
16
- export declare function generate(node: Node, root?: boolean, projectRoot?: string): GeneratedRoutes;
28
+ export declare function getRouteId(directory: string, projectRoot: string): string;
29
+ export declare function generate(node: Node, root?: boolean, projectRoot?: string, options?: GenerateOptions): GeneratedRoutes;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,18 @@ import { type RouteConventions } from "./scanner";
3
3
  export type RoutesOptions = {
4
4
  directory?: string;
5
5
  conventions?: RouteConventions;
6
+ /**
7
+ * Where to write the generated route type declarations, relative to the Vite
8
+ * project root.
9
+ *
10
+ * - `"auto"` writes `src/route-types.d.ts`, but only when the project root
11
+ * has a `tsconfig.json` or `jsconfig.json`, so JavaScript projects without
12
+ * one get no extra file.
13
+ * - A path ending in `.d.ts` always writes to that path.
14
+ * - `false` never writes the file.
15
+ * @default "auto"
16
+ */
17
+ dts?: "auto" | string | false;
6
18
  };
7
19
  export type { RouteConventions, RouteFileKind, RouteManifestNode, } from "./scanner";
8
20
  export declare function routes(input?: string | RoutesOptions): Plugin;