@troyio/vite-file-router 0.3.0 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +17 -0
  2. package/dist/index.js +17 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -178,6 +178,23 @@ when a descendant URL matches. An action runs only when its route is selected
178
178
  as the submission target; a parent action does not automatically handle
179
179
  submissions targeting child routes.
180
180
 
181
+ A loader module may also export `shouldRevalidate(args)` to control the route's
182
+ React Router `shouldRevalidate` option. It receives the same arguments as
183
+ `shouldRevalidate` and must synchronously return a boolean:
184
+
185
+ ```ts
186
+ import type { LoaderFunctionArgs, ShouldRevalidateFunctionArgs } from "react-router";
187
+
188
+ export function shouldRevalidate({ nextUrl, defaultShouldRevalidate }: ShouldRevalidateFunctionArgs) {
189
+ if (nextUrl.searchParams.get("refresh") === "never") return false;
190
+ return defaultShouldRevalidate;
191
+ }
192
+
193
+ export async function loader({ request }: LoaderFunctionArgs) {
194
+ return getDashboardData(request);
195
+ }
196
+ ```
197
+
181
198
  Use a loader to redirect users who should not enter a protected route subtree.
182
199
  For example, `src/pages/dashboard/loader.ts` can guard `/dashboard` and all of
183
200
  its nested pages:
package/dist/index.js CHANGED
@@ -132,9 +132,19 @@ function generateImport(file, projectRoot) {
132
132
  Component: (await import(${JSON.stringify(getImportPath(file, projectRoot))})).default
133
133
  })`;
134
134
  }
135
- function generateRouteLazy(node, projectRoot, includeLayout) {
135
+ function generateRouteLazy(node, projectRoot, includeLayout, includeLoader) {
136
136
  const properties = [];
137
137
  if (includeLayout && node.layout) properties.push(`Component: withOutlet((await import(${JSON.stringify(getImportPath(node.layout, projectRoot))})).default)`);
138
+ if (includeLoader && node.loader) return `async () => {
139
+ const loaderModule = await import(${JSON.stringify(getImportPath(node.loader, projectRoot))});
140
+ return {
141
+ loader: loaderModule.loader,
142
+ ...(typeof loaderModule.shouldRevalidate === "function"
143
+ ? { shouldRevalidate: loaderModule.shouldRevalidate }
144
+ : {}),
145
+ ${properties.join(",\n ")}
146
+ };
147
+ }`;
138
148
  return `async () => ({ ${properties.join(", ")} })`;
139
149
  }
140
150
  function generateLazyComponent(file, projectRoot) {
@@ -143,8 +153,8 @@ function generateLazyComponent(file, projectRoot) {
143
153
  function generateLazyLayout(file, projectRoot) {
144
154
  return `lazy(() => import(${JSON.stringify(getImportPath(file, projectRoot))}).then(({ default: Layout }) => ({ default: withOutlet(Layout) })))`;
145
155
  }
146
- function generateDataHandler(file, kind, projectRoot) {
147
- return `async (args) => (await import(${JSON.stringify(getImportPath(file, projectRoot))})).${kind}(args)`;
156
+ function generateDataHandler(file, projectRoot) {
157
+ return `async (args) => (await import(${JSON.stringify(getImportPath(file, projectRoot))})).action(args)`;
148
158
  }
149
159
  function getRouteId(directory, projectRoot) {
150
160
  return `file-route:${path.relative(projectRoot, directory).split(path.sep).join("/") || "."}`;
@@ -159,8 +169,7 @@ function generateNode(node, root, context, inheritedBoundary) {
159
169
  context.hasErrorBoundaries = true;
160
170
  route.ErrorBoundary = `createErrorBoundary(${generateLazyComponent(node.error, context.projectRoot)})`;
161
171
  }
162
- if (node.loader) route.loader = generateDataHandler(node.loader, "loader", context.projectRoot);
163
- if (node.action) route.action = generateDataHandler(node.action, "action", context.projectRoot);
172
+ if (node.action) route.action = generateDataHandler(node.action, context.projectRoot);
164
173
  let loadingComponent;
165
174
  if (node.loading) {
166
175
  loadingComponent = genSafeVariableName(`Loading${context.nextLoadingId++}`);
@@ -173,17 +182,17 @@ function generateNode(node, root, context, inheritedBoundary) {
173
182
  } else if (node.layout) {
174
183
  if (hasBoundary) route.Component = generateLazyLayout(node.layout, context.projectRoot);
175
184
  }
176
- if (node.layout && !hasBoundary) route.lazy = generateRouteLazy(node, context.projectRoot, true);
185
+ if (node.layout && !hasBoundary || node.loader) route.lazy = generateRouteLazy(node, context.projectRoot, Boolean(node.layout && !hasBoundary), Boolean(node.loader));
177
186
  const children = [];
178
187
  if (node.page) {
179
188
  const page = hasBoundary ? {
180
189
  index: "true",
181
190
  Component: generateLazyComponent(node.page, context.projectRoot),
182
- ...node.action ? { action: generateDataHandler(node.action, "action", context.projectRoot) } : {}
191
+ ...node.action ? { action: generateDataHandler(node.action, context.projectRoot) } : {}
183
192
  } : {
184
193
  index: "true",
185
194
  lazy: generateImport(node.page, context.projectRoot),
186
- ...node.action ? { action: generateDataHandler(node.action, "action", context.projectRoot) } : {}
195
+ ...node.action ? { action: generateDataHandler(node.action, context.projectRoot) } : {}
187
196
  };
188
197
  children.push(genObjectFromRaw(page));
189
198
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@troyio/vite-file-router",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "File-system routing plugin for Vite",
5
5
  "type": "module",
6
6
  "private": false,