@rangojs/router 0.22.1 → 0.24.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/dist/bin/rango.js +10 -4
- package/dist/testing/vitest.js +31 -1
- package/dist/types/browser/defer.d.ts +48 -0
- package/dist/types/browser/document-revealed.d.ts +17 -0
- package/dist/types/browser/event-controller.d.ts +7 -1
- package/dist/types/browser/merge-segment-loaders.d.ts +5 -2
- package/dist/types/browser/navigation-transaction.d.ts +21 -7
- package/dist/types/browser/partial-update.d.ts +39 -8
- package/dist/types/browser/react/NavigationProvider.d.ts +19 -5
- package/dist/types/browser/react/context.d.ts +3 -2
- package/dist/types/browser/react/filter-segment-order.d.ts +7 -0
- package/dist/types/browser/response-adapter.d.ts +7 -0
- package/dist/types/browser/types.d.ts +24 -10
- package/dist/types/browser/validate-redirect-origin.d.ts +11 -0
- package/dist/types/build/generate-route-types.d.ts +1 -1
- package/dist/types/build/route-types/router-processing.d.ts +1 -1
- package/dist/types/build/route-types/scan-filter.d.ts +22 -2
- package/dist/types/cache/cf/cf-cache-store.d.ts +16 -1
- package/dist/types/cache/cf/cf-cache-types.d.ts +23 -2
- package/dist/types/cache/document-cache-policy.d.ts +24 -0
- package/dist/types/cache/document-cache.d.ts +2 -10
- package/dist/types/client-urls/client-urls.d.ts +1 -1
- package/dist/types/client-urls/hoisted-revalidate.d.ts +13 -0
- package/dist/types/client-urls/navigation.d.ts +0 -37
- package/dist/types/client-urls/revalidate-registry.d.ts +4 -0
- package/dist/types/client-urls/server-projection.d.ts +29 -1
- package/dist/types/client-urls/types.d.ts +34 -69
- package/dist/types/client.d.ts +0 -1
- package/dist/types/context-var.d.ts +12 -0
- package/dist/types/errors.d.ts +15 -0
- package/dist/types/handles/deferred-resolution.d.ts +2 -1
- package/dist/types/handles/pushed-by.d.ts +31 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.rsc.d.ts +2 -0
- package/dist/types/loader-store.d.ts +8 -0
- package/dist/types/prefetch-markers.d.ts +11 -0
- package/dist/types/response-utils.d.ts +7 -0
- package/dist/types/reverse.d.ts +8 -8
- package/dist/types/route-definition/helpers-types.d.ts +27 -0
- package/dist/types/route-definition/rewrite.d.ts +56 -0
- package/dist/types/route-map-builder.d.ts +7 -2
- package/dist/types/router/basename.d.ts +7 -0
- package/dist/types/router/handler-context.d.ts +1 -5
- package/dist/types/router/internal-params.d.ts +8 -0
- package/dist/types/router/is-action.d.ts +2 -1
- package/dist/types/router/middleware-types.d.ts +15 -0
- package/dist/types/router/revalidation.d.ts +1 -2
- package/dist/types/router/route-trie-builder.d.ts +10 -0
- package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -2
- package/dist/types/router/segment-resolution/mask-nested.d.ts +4 -2
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +264 -0
- package/dist/types/rsc/full-payload.d.ts +11 -0
- package/dist/types/rsc/handler.d.ts +33 -0
- package/dist/types/rsc/helpers.d.ts +8 -0
- package/dist/types/rsc/loader-fetch.d.ts +16 -0
- package/dist/types/rsc/rewrite-passes.d.ts +74 -0
- package/dist/types/rsc/ssr-setup.d.ts +3 -1
- package/dist/types/server/context.d.ts +21 -1
- package/dist/types/server/handle-store.d.ts +9 -1
- package/dist/types/server/request-context.d.ts +52 -2
- package/dist/types/server/rewrite-trail.d.ts +49 -0
- package/dist/types/server/slot-accessors.d.ts +29 -0
- package/dist/types/server.d.ts +1 -0
- package/dist/types/testing/flight.entry.d.ts +1 -1
- package/dist/types/testing/index.d.ts +4 -4
- package/dist/types/testing/internal/action-id.d.ts +10 -1
- package/dist/types/testing/internal/client-urls-projection.d.ts +16 -0
- package/dist/types/testing/internal/test-action.d.ts +8 -0
- package/dist/types/testing/render-route.d.ts +8 -0
- package/dist/types/testing/run-loader.d.ts +2 -1
- package/dist/types/testing/run-middleware.d.ts +20 -0
- package/dist/types/testing/run-revalidate.d.ts +74 -0
- package/dist/types/testing/run-transition-when.d.ts +2 -3
- package/dist/types/testing/serve-shell-request.d.ts +40 -1
- package/dist/types/testing/vitest.d.ts +11 -0
- package/dist/types/thenable-status.d.ts +6 -0
- package/dist/types/types/boundaries.d.ts +9 -0
- package/dist/types/types/handler-context.d.ts +14 -0
- package/dist/types/types/loader-types.d.ts +30 -0
- package/dist/types/types/request-scope.d.ts +7 -0
- package/dist/types/types/segments.d.ts +21 -4
- package/dist/types/urls/path-helper-types.d.ts +25 -4
- package/dist/types/urls/type-extraction.d.ts +6 -2
- package/dist/types/vite/discovery/discover-routers.d.ts +9 -0
- package/dist/types/vite/discovery/state.d.ts +14 -4
- package/dist/types/vite/plugins/client-urls-revalidate-hoist.d.ts +54 -0
- package/dist/types/vite/plugins/hoist/literal.d.ts +83 -0
- package/dist/types/vite/plugins/hoist/scope.d.ts +40 -0
- package/dist/types/vite/plugins/hoist/source.d.ts +41 -0
- package/dist/types/vite/plugins/transition-when-hoist.d.ts +8 -11
- package/dist/types/vite/router-discovery.d.ts +10 -0
- package/dist/vite/index.js +974 -379
- package/package.json +1 -1
- package/skills/caching/SKILL.md +54 -5
- package/skills/catalog.json +3 -3
- package/skills/client-urls/SKILL.md +197 -24
- package/skills/cloudflare/SKILL.md +14 -9
- package/skills/hooks/SKILL.md +16 -3
- package/skills/hooks/data.md +3 -1
- package/skills/links/SKILL.md +24 -0
- package/skills/loader/SKILL.md +199 -2
- package/skills/middleware/SKILL.md +183 -2
- package/skills/migrate-nextjs/SKILL.md +2 -2
- package/skills/migrate-react-router/SKILL.md +10 -7
- package/skills/migrate-react-router/data-and-actions.md +1 -1
- package/skills/ppr/SKILL.md +22 -0
- package/skills/prerender/SKILL.md +22 -8
- package/skills/rango/SKILL.md +13 -7
- package/skills/route/SKILL.md +139 -0
- package/skills/server-actions/SKILL.md +27 -0
- package/skills/testing/SKILL.md +3 -2
- package/skills/testing/client-components.md +2 -1
- package/skills/testing/middleware.md +31 -10
- package/skills/testing/predicates.md +67 -32
- package/skills/testing/response-routes.md +1 -0
- package/skills/testing/serve-shell-request.md +107 -19
- package/skills/testing/setup.md +2 -2
- package/skills/typesafety/route-types.md +2 -2
- package/skills/use-cache/SKILL.md +4 -2
- package/skills/view-transitions/SKILL.md +26 -0
- package/src/__augment-tests__/augmented.check.ts +20 -0
- package/src/browser/defer.ts +82 -0
- package/src/browser/document-revealed.ts +52 -0
- package/src/browser/event-controller.ts +46 -32
- package/src/browser/merge-segment-loaders.ts +31 -18
- package/src/browser/navigation-bridge.ts +82 -16
- package/src/browser/navigation-client.ts +48 -36
- package/src/browser/navigation-store.ts +13 -0
- package/src/browser/navigation-transaction.ts +25 -8
- package/src/browser/partial-update.ts +554 -146
- package/src/browser/prefetch/fetch.ts +2 -1
- package/src/browser/react/Link.tsx +7 -9
- package/src/browser/react/NavigationProvider.tsx +88 -49
- package/src/browser/react/context.ts +3 -2
- package/src/browser/react/filter-segment-order.ts +13 -2
- package/src/browser/react/use-router.ts +2 -4
- package/src/browser/response-adapter.ts +20 -0
- package/src/browser/rsc-router.tsx +17 -45
- package/src/browser/server-action-bridge.ts +25 -63
- package/src/browser/types.ts +24 -10
- package/src/browser/validate-redirect-origin.ts +16 -0
- package/src/build/generate-route-types.ts +1 -0
- package/src/build/route-types/router-processing.ts +3 -6
- package/src/build/route-types/scan-filter.ts +45 -11
- package/src/cache/cf/cf-cache-store.ts +59 -21
- package/src/cache/cf/cf-cache-types.ts +24 -2
- package/src/cache/document-cache-policy.ts +131 -0
- package/src/cache/document-cache.ts +21 -107
- package/src/client-urls/client-urls.ts +22 -6
- package/src/client-urls/hoisted-revalidate.ts +25 -0
- package/src/client-urls/navigation.ts +0 -96
- package/src/client-urls/revalidate-registry.ts +30 -0
- package/src/client-urls/server-projection.ts +151 -65
- package/src/client-urls/types.ts +39 -71
- package/src/client.tsx +9 -5
- package/src/context-var.ts +32 -2
- package/src/errors.ts +34 -0
- package/src/handles/deferred-resolution.ts +28 -5
- package/src/handles/pushed-by.ts +148 -0
- package/src/index.rsc.ts +8 -0
- package/src/index.ts +7 -0
- package/src/loader-store.ts +18 -7
- package/src/prefetch-markers.ts +13 -0
- package/src/response-utils.ts +19 -0
- package/src/reverse.ts +17 -14
- package/src/route-content-wrapper.tsx +18 -4
- package/src/route-definition/dsl-helpers.ts +27 -4
- package/src/route-definition/helpers-types.ts +27 -1
- package/src/route-definition/redirect.ts +2 -15
- package/src/route-definition/rewrite.ts +146 -0
- package/src/route-map-builder.ts +14 -11
- package/src/router/basename.ts +20 -0
- package/src/router/handler-context.ts +3 -13
- package/src/router/intercept-resolution.ts +35 -16
- package/src/router/internal-params.ts +16 -0
- package/src/router/is-action.ts +2 -1
- package/src/router/loader-resolution.ts +85 -4
- package/src/router/match-api.ts +36 -1
- package/src/router/match-middleware/background-revalidation.ts +16 -4
- package/src/router/match-middleware/cache-lookup.ts +35 -7
- package/src/router/match-middleware/cache-store.ts +15 -1
- package/src/router/match-middleware/intercept-resolution.ts +4 -2
- package/src/router/match-result.ts +14 -2
- package/src/router/middleware-types.ts +16 -0
- package/src/router/middleware.ts +127 -49
- package/src/router/navigation-snapshot.ts +2 -1
- package/src/router/revalidation.ts +1 -1
- package/src/router/route-trie-builder.ts +28 -1
- package/src/router/segment-resolution/fresh.ts +22 -18
- package/src/router/segment-resolution/loader-cache.ts +2 -1
- package/src/router/segment-resolution/loader-mask.ts +5 -3
- package/src/router/segment-resolution/loader-snapshot.ts +18 -4
- package/src/router/segment-resolution/mask-nested.ts +8 -4
- package/src/router/segment-resolution/prefetch-deferral.ts +583 -0
- package/src/router/segment-resolution/revalidation.ts +215 -82
- package/src/rsc/full-payload.ts +37 -5
- package/src/rsc/handler.ts +82 -55
- package/src/rsc/helpers.ts +24 -0
- package/src/rsc/loader-fetch.ts +79 -24
- package/src/rsc/response-cache-serve.ts +18 -2
- package/src/rsc/response-route-handler.ts +4 -7
- package/src/rsc/rewrite-passes.ts +203 -0
- package/src/rsc/rsc-rendering.ts +54 -9
- package/src/rsc/shell-capture.ts +2 -1
- package/src/rsc/ssr-setup.ts +11 -5
- package/src/segment-loader-promise.ts +23 -20
- package/src/segment-system.tsx +60 -26
- package/src/server/context.ts +39 -5
- package/src/server/cookie-parse.ts +36 -12
- package/src/server/cookie-store.ts +7 -3
- package/src/server/handle-store.ts +152 -25
- package/src/server/request-context.ts +175 -64
- package/src/server/request-headers.ts +4 -14
- package/src/server/rewrite-trail.ts +190 -0
- package/src/server/slot-accessors.ts +57 -0
- package/src/server.ts +4 -0
- package/src/ssr/index.tsx +118 -16
- package/src/testing/action-form.ts +2 -11
- package/src/testing/dispatch.ts +138 -67
- package/src/testing/e2e/page-helpers.ts +3 -1
- package/src/testing/flight.entry.ts +1 -0
- package/src/testing/index.ts +7 -3
- package/src/testing/internal/action-id.ts +16 -1
- package/src/testing/internal/client-urls-projection.ts +70 -0
- package/src/testing/internal/test-action.ts +25 -0
- package/src/testing/render-route.tsx +16 -3
- package/src/testing/run-loader.ts +4 -1
- package/src/testing/run-middleware.ts +56 -11
- package/src/testing/run-revalidate.ts +142 -0
- package/src/testing/run-transition-when.ts +7 -8
- package/src/testing/serve-shell-request.ts +131 -8
- package/src/testing/vitest.ts +67 -1
- package/src/thenable-status.ts +11 -0
- package/src/types/boundaries.ts +12 -0
- package/src/types/handler-context.ts +14 -0
- package/src/types/loader-types.ts +30 -0
- package/src/types/request-scope.ts +8 -0
- package/src/types/segments.ts +26 -4
- package/src/urls/path-helper-types.ts +27 -5
- package/src/urls/type-extraction.ts +30 -10
- package/src/use-loader.tsx +18 -13
- package/src/vite/discovery/client-urls-projection.ts +20 -21
- package/src/vite/discovery/discover-routers.ts +94 -26
- package/src/vite/discovery/state.ts +28 -4
- package/src/vite/discovery/virtual-module-codegen.ts +22 -17
- package/src/vite/plugins/client-urls-revalidate-hoist.ts +564 -0
- package/src/vite/plugins/expose-internal-ids.ts +2 -3
- package/src/vite/plugins/hoist/literal.ts +417 -0
- package/src/vite/plugins/hoist/scope.ts +370 -0
- package/src/vite/plugins/hoist/source.ts +84 -0
- package/src/vite/plugins/transition-when-hoist.ts +113 -779
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +116 -53
- package/dist/types/client-urls/revalidate-chain.d.ts +0 -33
- package/dist/types/client-urls/revalidation-protocol.d.ts +0 -25
- package/dist/types/testing/run-client-revalidate.d.ts +0 -43
- package/src/client-urls/revalidate-chain.ts +0 -83
- package/src/client-urls/revalidation-protocol.ts +0 -56
- package/src/testing/run-client-revalidate.ts +0 -92
|
@@ -158,6 +158,15 @@ export interface ResolvedSegment {
|
|
|
158
158
|
*/
|
|
159
159
|
awaitBeforeFlush?: true;
|
|
160
160
|
parallelLoading?: ReactNode;
|
|
161
|
+
/**
|
|
162
|
+
* A prefetch skipped this segment's work (`prefetch: false`): a loader
|
|
163
|
+
* carries no `loaderData`, a layout/route/parallel unit carries
|
|
164
|
+
* `component: null` and its fallback. The browser shows the fallback and
|
|
165
|
+
* sends a fill request for it (browser/partial-update.ts); until that
|
|
166
|
+
* lands the segment is a placeholder, never a held copy. Only ever on a
|
|
167
|
+
* prefetch response: see docs/design/prefetch-false.md.
|
|
168
|
+
*/
|
|
169
|
+
deferred?: true;
|
|
161
170
|
loaderDataPromise?: Promise<any[]> | any[];
|
|
162
171
|
loaderIds?: string[];
|
|
163
172
|
/**
|
|
@@ -228,10 +237,12 @@ export interface MatchResult {
|
|
|
228
237
|
/**
|
|
229
238
|
* Every segment id whose handler actually ran on the server this request,
|
|
230
239
|
* including ones with `component === null` that get filtered out of
|
|
231
|
-
* `segments`/`diff` to avoid wasted bytes
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
240
|
+
* `segments`/`diff` to avoid wasted bytes, and every loader segment that
|
|
241
|
+
* ran. Drives the client's handle merge (handles/pushed-by.ts) — a slot
|
|
242
|
+
* that re-resolves and pushes nothing must clear its previous handle
|
|
243
|
+
* bucket, but `diff` doesn't carry it because the segment payload doesn't
|
|
244
|
+
* either; a loader that ran replaces its pushes, one that did not keeps
|
|
245
|
+
* them. A superset of `diff`.
|
|
235
246
|
*/
|
|
236
247
|
resolvedIds: string[];
|
|
237
248
|
/**
|
|
@@ -279,3 +290,9 @@ export interface MatchResult {
|
|
|
279
290
|
params: Record<string, string>;
|
|
280
291
|
}>;
|
|
281
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* A `prefetch: false` placeholder (ResolvedSegment.deferred): a segment whose
|
|
295
|
+
* work a prefetch skipped, waiting for its fill. Never a held copy of the
|
|
296
|
+
* segment it stands for.
|
|
297
|
+
*/
|
|
298
|
+
export declare function isPlaceholder(segment: Pick<ResolvedSegment, "deferred">): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { ErrorBoundaryHandler, ExtractParams, Handler, HandlerContext, LoaderDefinition, LoaderOptions, MiddlewareFn, NotFoundBoundaryHandler, PartialCacheOptions, ShouldRevalidateFn, TransitionConfig } from "../types.js";
|
|
3
|
-
import type { AllUseItems, TypedLayoutItem, ParallelItem, InterceptItem, MiddlewareItem, RevalidateItem, LoaderItem, LoadingItem, ErrorBoundaryItem, NotFoundBoundaryItem, LayoutUseItem, RouteUseItem, ResponseRouteUseItem, ParallelUseItem, InterceptUseItem, LoaderUseItem, TypedCacheItem,
|
|
3
|
+
import type { AllUseItems, TypedLayoutItem, ParallelItem, InterceptItem, MiddlewareItem, RevalidateItem, LoaderItem, LoadingItem, ErrorBoundaryItem, NotFoundBoundaryItem, LayoutUseItem, RouteUseItem, ResponseRouteUseItem, ParallelUseItem, InterceptUseItem, LoaderUseItem, TypedCacheItem, TypedTransitionItem, TypedRouteItem, TypedIncludeItem, UseItems } from "../route-types.js";
|
|
4
4
|
import type { SearchSchema } from "../search-params.js";
|
|
5
5
|
import type { PrerenderHandlerDefinition, PassthroughHandlerDefinition } from "../prerender.js";
|
|
6
6
|
import type { StaticHandlerDefinition, StaticHandlerRef } from "../static-handler.js";
|
|
@@ -158,13 +158,34 @@ export type PathHelpers<TEnv> = {
|
|
|
158
158
|
* flag BAKES: the loader executes at shell capture and its settled return
|
|
159
159
|
* freezes into the shell (nested promises stay live holes) — the pre-flush
|
|
160
160
|
* promise applied to the prelude.
|
|
161
|
+
*
|
|
162
|
+
* Pass `{ prefetch: false }` to keep the loader out of prefetches: a
|
|
163
|
+
* prefetch skips it and the click that adopts the prefetch fetches it in
|
|
164
|
+
* one follow-up request (see {@link LoaderOptions}). Only on a segment the
|
|
165
|
+
* client does not have yet: a loader the client already holds runs in the
|
|
166
|
+
* prefetch when it revalidates.
|
|
161
167
|
*/
|
|
162
168
|
loader: <TData>(loaderDef: LoaderDefinition<TData>, optionsOrUse?: LoaderOptions | (() => LoaderUseItem[]), use?: () => LoaderUseItem[]) => LoaderItem;
|
|
163
169
|
/**
|
|
164
|
-
* Attach a loading component to the current route/layout
|
|
170
|
+
* Attach a loading component to the current route/layout.
|
|
171
|
+
*
|
|
172
|
+
* `{ ssr: false }` skips the fallback on document requests. `{ prefetch:
|
|
173
|
+
* false }` keeps what the fallback covers out of prefetches, when this
|
|
174
|
+
* entry's segment is new to the client: the entry's handler, its loaders,
|
|
175
|
+
* its orphan layouts and parallel slots and, for a layout, every deeper
|
|
176
|
+
* entry. The click that adopts the prefetch shows the fallback and fetches
|
|
177
|
+
* them in one follow-up request, which reads cache() and "use cache" as
|
|
178
|
+
* any request does (a prefetch reads neither for skipped work). A segment
|
|
179
|
+
* the client already holds is never deferred: a prefetch renders it as
|
|
180
|
+
* usual when it revalidates, and what is below it follows its own flags.
|
|
181
|
+
* To keep a child out of prefetches while moving inside a section, flag
|
|
182
|
+
* the child's own loading(). An entry whose handler output is stored
|
|
183
|
+
* (cache(), ppr, Prerender/Static) is served as usual and only its loaders
|
|
184
|
+
* are skipped.
|
|
165
185
|
*/
|
|
166
186
|
loading: (component: ReactNode | (() => ReactNode), options?: {
|
|
167
187
|
ssr?: boolean;
|
|
188
|
+
prefetch?: boolean;
|
|
168
189
|
}) => LoadingItem;
|
|
169
190
|
/**
|
|
170
191
|
* Attach an error boundary to catch errors in this segment
|
|
@@ -199,8 +220,8 @@ export type PathHelpers<TEnv> = {
|
|
|
199
220
|
* the browser (never on the server); see TransitionWhenFn.
|
|
200
221
|
*/
|
|
201
222
|
transition: {
|
|
202
|
-
():
|
|
203
|
-
(config: TransitionConfig):
|
|
223
|
+
(): TypedTransitionItem<{}, {}>;
|
|
224
|
+
(config: TransitionConfig): TypedTransitionItem<{}, {}>;
|
|
204
225
|
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(children: () => TChildren): TypedTransitionItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
205
226
|
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(config: TransitionConfig, children: () => TChildren): TypedTransitionItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
206
227
|
};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { JsonSerialize } from "../serialize.js";
|
|
2
2
|
import type { TypedRouteItem, TypedIncludeItem, TypedLayoutItem, TypedCacheItem, TypedTransitionItem } from "../route-types.js";
|
|
3
3
|
import type { LocalOnlyInclude, UnnamedRoute } from "./pattern-types.js";
|
|
4
|
+
/** Drops string index signatures, keeping literal and template keys. */
|
|
5
|
+
type StripStringIndex<T> = {
|
|
6
|
+
[K in keyof T as string extends K ? never : K]: T[K];
|
|
7
|
+
};
|
|
4
8
|
/**
|
|
5
9
|
* Prefix route names with a given prefix (e.g., "blog" + "post" = "blog.post")
|
|
6
10
|
*
|
|
@@ -52,7 +56,7 @@ type ExtractRoutesFromItem<T> = T extends TypedRouteItem<infer TName, infer TPat
|
|
|
52
56
|
readonly path: TPattern;
|
|
53
57
|
readonly search: TSearch;
|
|
54
58
|
};
|
|
55
|
-
} : {} : T extends TypedIncludeItem<infer TRoutes, infer TNamePrefix, infer TUrlPrefix> ? TNamePrefix extends LocalOnlyInclude ? {} : TNamePrefix extends string ? TUrlPrefix extends string ? PrefixRoutes<PrefixPatterns<TRoutes, TUrlPrefix>, TNamePrefix> : PrefixRoutes<TRoutes, TNamePrefix> : TUrlPrefix extends string ? PrefixPatterns<TRoutes, TUrlPrefix> : TRoutes : T extends TypedLayoutItem<infer TChildRoutes> ? TChildRoutes : T extends TypedCacheItem<infer TChildRoutes> ? TChildRoutes : T extends TypedTransitionItem<infer TChildRoutes> ? TChildRoutes : {};
|
|
59
|
+
} : {} : T extends TypedIncludeItem<infer TRoutes, infer TNamePrefix, infer TUrlPrefix> ? TNamePrefix extends LocalOnlyInclude ? {} : TNamePrefix extends string ? TUrlPrefix extends string ? PrefixRoutes<PrefixPatterns<TRoutes, TUrlPrefix>, TNamePrefix> : PrefixRoutes<TRoutes, TNamePrefix> : TUrlPrefix extends string ? PrefixPatterns<TRoutes, TUrlPrefix> : TRoutes : T extends TypedLayoutItem<infer TChildRoutes> ? StripStringIndex<TChildRoutes> : T extends TypedCacheItem<infer TChildRoutes> ? StripStringIndex<TChildRoutes> : T extends TypedTransitionItem<infer TChildRoutes> ? StripStringIndex<TChildRoutes> : {};
|
|
56
60
|
/**
|
|
57
61
|
* Extract routes from an array of items using mapped types.
|
|
58
62
|
* Uses UnionToIntersection to combine routes without recursive tuple processing,
|
|
@@ -82,7 +86,7 @@ type PrefixKeys<T extends Record<string, unknown>, TPrefix extends string> = TPr
|
|
|
82
86
|
*/
|
|
83
87
|
type ExtractResponsesFromItem<T> = T extends TypedRouteItem<infer TName, any, infer TData> ? TName extends string ? string extends TName ? {} : TName extends UnnamedRoute ? {} : {
|
|
84
88
|
[K in TName]: TData;
|
|
85
|
-
} : {} : T extends TypedIncludeItem<any, infer TNamePrefix, any, infer TResponses> ? TNamePrefix extends LocalOnlyInclude ? {} : TNamePrefix extends string ? TResponses extends Record<string, unknown> ? PrefixKeys<TResponses, TNamePrefix> : {} : TResponses extends Record<string, unknown> ? TResponses : {} : T extends TypedLayoutItem<any, infer TChildResponses> ? TChildResponses extends Record<string, unknown> ?
|
|
89
|
+
} : {} : T extends TypedIncludeItem<any, infer TNamePrefix, any, infer TResponses> ? TNamePrefix extends LocalOnlyInclude ? {} : TNamePrefix extends string ? TResponses extends Record<string, unknown> ? PrefixKeys<TResponses, TNamePrefix> : {} : TResponses extends Record<string, unknown> ? TResponses : {} : T extends TypedLayoutItem<any, infer TChildResponses> ? StripStringIndex<TChildResponses> extends infer R extends Record<string, unknown> ? R : {} : T extends TypedCacheItem<any, infer TChildResponses> ? StripStringIndex<TChildResponses> extends infer R extends Record<string, unknown> ? R : {} : T extends TypedTransitionItem<any, infer TChildResponses> ? StripStringIndex<TChildResponses> extends infer R extends Record<string, unknown> ? R : {} : {};
|
|
86
90
|
/**
|
|
87
91
|
* Extract responses from an array of items using mapped types.
|
|
88
92
|
* Parallel to ExtractRoutesFromItems.
|
|
@@ -13,5 +13,14 @@ import type { DiscoveryState } from "./state.js";
|
|
|
13
13
|
*
|
|
14
14
|
* Returns the imported `@rangojs/router/server` module so the caller
|
|
15
15
|
* can access the RouterRegistry and manifest setters.
|
|
16
|
+
*
|
|
17
|
+
* A pass reads the router registry and installs clientUrls projections on ONE
|
|
18
|
+
* `@rangojs/router/server` instance, and checks that the runner still serves
|
|
19
|
+
* it. A runner full reload during the pass (a watched-file change at boot)
|
|
20
|
+
* splits the realm: a router module bound to the old instance registers there
|
|
21
|
+
* while urls modules re-evaluate against a fresh one, so include() looks its
|
|
22
|
+
* projection up in the fresh, empty Map ("include() could not resolve the
|
|
23
|
+
* server projection"). Such a pass is redone, at most
|
|
24
|
+
* MAX_DISCOVERY_PASSES times; the redo evaluates the entry in one realm.
|
|
16
25
|
*/
|
|
17
26
|
export declare function discoverRouters(state: DiscoveryState, rscEnv: any, ssrEnv?: any): Promise<any>;
|
|
@@ -188,14 +188,24 @@ export interface DiscoveryState {
|
|
|
188
188
|
/** Cleanup function for build-time env resources (e.g., miniflare). */
|
|
189
189
|
buildEnvDispose?: (() => Promise<void> | void) | null;
|
|
190
190
|
/**
|
|
191
|
-
* Set when the most recent HMR re-discovery
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* rediscovery trigger
|
|
191
|
+
* Set when the most recent dev discovery failed: an HMR re-discovery, or the
|
|
192
|
+
* cold discovery on the Node RSC runner or the Cloudflare temp runner.
|
|
193
|
+
* Cleared on the next successful discovery. While set, the route-file
|
|
194
|
+
* watcher treats any in-scan source change as a rediscovery trigger
|
|
195
|
+
* (recovery mode).
|
|
195
196
|
*/
|
|
196
197
|
lastDiscoveryError?: {
|
|
197
198
|
message: string;
|
|
198
199
|
at: number;
|
|
199
200
|
} | null;
|
|
200
201
|
}
|
|
202
|
+
/** Record a failed dev discovery (lastDiscoveryError): recovery mode. */
|
|
203
|
+
export declare function recordDiscoveryFailure(state: Pick<DiscoveryState, "lastDiscoveryError">, err: unknown): void;
|
|
204
|
+
/**
|
|
205
|
+
* Whether the route-file watcher can re-run runtime discovery: a committed
|
|
206
|
+
* manifest, or a recorded failure. A failed cold discovery commits none, and
|
|
207
|
+
* without its recorded failure the dev server stayed broken until a restart,
|
|
208
|
+
* on the Node runner and on Cloudflare alike.
|
|
209
|
+
*/
|
|
210
|
+
export declare function canRefreshRuntimeDiscovery(state: Pick<DiscoveryState, "perRouterManifests" | "lastDiscoveryError">): boolean;
|
|
201
211
|
export declare function createDiscoveryState(entryPath: string | undefined, opts: PluginOptions | undefined): DiscoveryState & ClientUrlDiscoveryState;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import MagicString from "magic-string";
|
|
3
|
+
/**
|
|
4
|
+
* The key of the predicate `source` declared in `relativeFile` (relative to
|
|
5
|
+
* the project root): a hash of the file and the predicate's syntax, so the
|
|
6
|
+
* same predicate gets one key in every environment and however it is
|
|
7
|
+
* formatted.
|
|
8
|
+
*/
|
|
9
|
+
export declare function revalidateKey(relativeFile: string, source: string): string;
|
|
10
|
+
interface HoistClientUrlsRevalidateDeps {
|
|
11
|
+
/** Project root: keys hash the file relative to it. */
|
|
12
|
+
readonly root: string;
|
|
13
|
+
/**
|
|
14
|
+
* Whether a module a predicate imports is a "use client" module beyond its
|
|
15
|
+
* specifier (the plugin resolves it and reads its directive prologue).
|
|
16
|
+
*/
|
|
17
|
+
isClientModule?(source: string): Promise<boolean> | boolean;
|
|
18
|
+
}
|
|
19
|
+
interface HoistClientUrlsRevalidateResult {
|
|
20
|
+
/** The module with each predicate replaced by its marker. */
|
|
21
|
+
readonly code: string;
|
|
22
|
+
readonly map: ReturnType<MagicString["generateMap"]>;
|
|
23
|
+
/** The server module that registers every hoisted predicate. */
|
|
24
|
+
readonly module: string;
|
|
25
|
+
/** The keys, in declaration order, duplicates removed. */
|
|
26
|
+
readonly keys: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Hoist every clientUrls() `revalidate()` predicate of a "use client"
|
|
30
|
+
* module. Returns null when there is none. Throws, naming file:line, for a
|
|
31
|
+
* predicate that is not pure.
|
|
32
|
+
*/
|
|
33
|
+
export declare function hoistClientUrlsRevalidates(code: string, id: string, deps: HoistClientUrlsRevalidateDeps): Promise<HoistClientUrlsRevalidateResult | null>;
|
|
34
|
+
/** The file a `?rango-revalidate` id names, or null. */
|
|
35
|
+
export declare function parseHoistedRevalidateId(id: string): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* The plugins: a pre transform that hoists in every environment (markers in
|
|
38
|
+
* the client and SSR copies, the server module recorded from the RSC
|
|
39
|
+
* transform) and serves `?rango-revalidate`, and a post transform that
|
|
40
|
+
* appends its import to the RSC client-reference proxy.
|
|
41
|
+
*
|
|
42
|
+
* `load` serves the module the RSC transform emitted, which hoisted the
|
|
43
|
+
* pipeline code; the disk source is re-hoisted only when the transform has
|
|
44
|
+
* not seen the current file (loadEmittedOrDisk). A file whose edit removed
|
|
45
|
+
* every predicate serves an empty module to a proxy that still imports it.
|
|
46
|
+
*
|
|
47
|
+
* The transform's code filter skips a module that never mentions clientUrls,
|
|
48
|
+
* so a file that stops doing so would keep its `emitted` entry: watchChange
|
|
49
|
+
* drops it, together with the cached "use client" answer for an edited
|
|
50
|
+
* dependency (isClientModule memoizes per resolved file; buildStart resets
|
|
51
|
+
* it).
|
|
52
|
+
*/
|
|
53
|
+
export declare function clientUrlsRevalidateHoistPlugin(): Plugin[];
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Literal-level helpers shared by the build-time predicate hoists
|
|
3
|
+
* (transition-when-hoist.ts moves a `when` from a server module into a
|
|
4
|
+
* "use client" one; client-urls-revalidate-hoist.ts moves a `revalidate()`
|
|
5
|
+
* from a "use client" module into a server one): finding a urls-callback
|
|
6
|
+
* helper's calls, the lexical-capture check, and the free imports a literal
|
|
7
|
+
* re-emits in its new module.
|
|
8
|
+
*/
|
|
9
|
+
import { type ImportBinding, type Node, type Reference, type Scope } from "./scope.js";
|
|
10
|
+
/** The offset after the directive prologue (0 when there is none). */
|
|
11
|
+
export declare function directivePrologueEnd(program: Node): number;
|
|
12
|
+
export declare function parseLang(file: string): "ts" | "tsx" | "jsx";
|
|
13
|
+
export declare function unwrapExpression(node: Node): Node;
|
|
14
|
+
export declare function isFunctionLiteral(node: Node): boolean;
|
|
15
|
+
export declare function propertyKeyIs(prop: Node, name: string): boolean;
|
|
16
|
+
/** Which helper calls {@link findHelperCalls} looks for. */
|
|
17
|
+
interface HelperCallSpec {
|
|
18
|
+
/** Module specifiers the builder (and a direct helper import) come from. */
|
|
19
|
+
readonly sources: ReadonlySet<string>;
|
|
20
|
+
/** The builder export whose callback's first parameter hands out `helper`. */
|
|
21
|
+
readonly builder: string;
|
|
22
|
+
readonly helper: string;
|
|
23
|
+
/** A direct import of `helper` from `sources` counts too. */
|
|
24
|
+
readonly directImport: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface HelperCall {
|
|
27
|
+
readonly call: Node;
|
|
28
|
+
readonly scope: Scope;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Every call of `spec.helper` the builder's callback hands out: destructured,
|
|
32
|
+
* renamed or as `helpers.<helper>`, at any depth of the callback, plus a
|
|
33
|
+
* direct import when `spec.directImport`. A builder is recognised by its
|
|
34
|
+
* import (named, renamed, or through a namespace); any other function of the
|
|
35
|
+
* same name is left alone.
|
|
36
|
+
*/
|
|
37
|
+
export declare function findHelperCalls(program: Node, scopeOf: Map<Node, Scope>, moduleScope: Scope, imports: Map<string, ImportBinding>, spec: HelperCallSpec): HelperCall[];
|
|
38
|
+
/**
|
|
39
|
+
* What a lexical-capture error says, per hoist direction. `lexical` explains
|
|
40
|
+
* each construct (`this`, `arguments`, `super`, `new.target`); `captureHint`
|
|
41
|
+
* and `loadsHint` follow every capture and module-load message;
|
|
42
|
+
* `importMetaWhy`, `importMetaMemberWhy` and `dynamicImportWhy` explain the
|
|
43
|
+
* module-loading expressions.
|
|
44
|
+
*/
|
|
45
|
+
export interface LexicalCaptureMessages {
|
|
46
|
+
readonly lexical: Readonly<Record<string, string>>;
|
|
47
|
+
readonly captureHint: string;
|
|
48
|
+
readonly loadsHint: string;
|
|
49
|
+
readonly importMetaWhy: string;
|
|
50
|
+
readonly importMetaMemberWhy: string;
|
|
51
|
+
readonly dynamicImportWhy: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The first use in a literal of a lexical context it would lose when hoisted
|
|
55
|
+
* (`this`, `arguments`, `super`, `new.target` of an enclosing function or
|
|
56
|
+
* object), or of a module-loading expression the build cannot check
|
|
57
|
+
* (`import()`, `import.meta` other than `import.meta.env`). A nested
|
|
58
|
+
* non-arrow function (or class body) owns its `this`/`arguments`, so uses
|
|
59
|
+
* inside one are fine; a method literal owns them too, but its `super`
|
|
60
|
+
* loses the object it was defined on.
|
|
61
|
+
*/
|
|
62
|
+
export declare function findLexicalCapture(literal: Node, references: readonly Reference[], code: string, messages: LexicalCaptureMessages): {
|
|
63
|
+
node: Node;
|
|
64
|
+
detail: string;
|
|
65
|
+
} | null;
|
|
66
|
+
/** The free references of a literal, by what they resolve to. */
|
|
67
|
+
interface FreeReferences {
|
|
68
|
+
/** Import local name -> whether any use is a value use. */
|
|
69
|
+
readonly imports: Map<string, boolean>;
|
|
70
|
+
/** Value references to a binding declared outside the literal that is not an import. */
|
|
71
|
+
readonly bindings: readonly Reference[];
|
|
72
|
+
/** References declared nowhere (window, URL, console, ...). */
|
|
73
|
+
readonly globals: readonly Reference[];
|
|
74
|
+
}
|
|
75
|
+
/** Every reference inside `literal` to something declared outside it. */
|
|
76
|
+
export declare function collectFreeReferences(literal: Node, references: readonly Reference[], moduleScope: Scope, imports: Map<string, ImportBinding>): FreeReferences;
|
|
77
|
+
/**
|
|
78
|
+
* Re-emit the imports a literal uses, grouped per source, type-only uses as
|
|
79
|
+
* `import type`. `checkValueImport` runs first for each value use and throws
|
|
80
|
+
* to reject one.
|
|
81
|
+
*/
|
|
82
|
+
export declare function emitImports(used: Map<string, boolean>, imports: Map<string, ImportBinding>, checkValueImport: (local: string, binding: ImportBinding) => Promise<void> | void): Promise<string[]>;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope analysis shared by the build-time predicate hoists
|
|
3
|
+
* (transition-when-hoist.ts, client-urls-revalidate-hoist.ts): a module's
|
|
4
|
+
* scope tree, every identifier reference, and its imports. Enough of ES
|
|
5
|
+
* scoping for the free-variable analysis of one literal.
|
|
6
|
+
*/
|
|
7
|
+
export type Node = any;
|
|
8
|
+
export interface ImportBinding {
|
|
9
|
+
readonly source: string;
|
|
10
|
+
/** "default", "*", or the imported name. */
|
|
11
|
+
readonly imported: string;
|
|
12
|
+
readonly typeOnly: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare class Scope {
|
|
15
|
+
readonly parent: Scope | null;
|
|
16
|
+
readonly isFunction: boolean;
|
|
17
|
+
readonly node: Node;
|
|
18
|
+
readonly declarations: Set<string>;
|
|
19
|
+
constructor(parent: Scope | null, isFunction: boolean, node: Node);
|
|
20
|
+
nearestFunction(): Scope;
|
|
21
|
+
lookup(name: string): Scope | null;
|
|
22
|
+
}
|
|
23
|
+
export interface Reference {
|
|
24
|
+
readonly node: Node;
|
|
25
|
+
readonly scope: Scope;
|
|
26
|
+
readonly typeOnly: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare const TYPE_KEYS: ReadonlySet<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Scope tree and every identifier reference of a module, TS type positions
|
|
31
|
+
* flagged. Enough of ES scoping for free-variable analysis of one literal:
|
|
32
|
+
* var hoists to the function scope, let/const/class to the block, function
|
|
33
|
+
* declarations to their block.
|
|
34
|
+
*/
|
|
35
|
+
export declare function analyzeScopes(program: Node): {
|
|
36
|
+
moduleScope: Scope;
|
|
37
|
+
references: Reference[];
|
|
38
|
+
scopeOf: Map<Node, Scope>;
|
|
39
|
+
};
|
|
40
|
+
export declare function collectImports(program: Node): Map<string, ImportBinding>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source reading shared by the build-time predicate hoists
|
|
3
|
+
* (transition-when-hoist.ts, client-urls-revalidate-hoist.ts): which ids are
|
|
4
|
+
* source files, reading one off disk, resolving an import to the file it
|
|
5
|
+
* names, and the "emitted or disk" lookup behind their `?rango-*` modules.
|
|
6
|
+
*/
|
|
7
|
+
/** A file path (query already stripped) a hoist transform may rewrite. */
|
|
8
|
+
export declare const SOURCE_FILE_RE: RegExp;
|
|
9
|
+
export declare function readSource(file: string): Promise<string | null>;
|
|
10
|
+
/** The part of a plugin context {@link resolveSourceTarget} needs. */
|
|
11
|
+
export interface SourceResolver {
|
|
12
|
+
resolve(source: string, importer?: string): Promise<{
|
|
13
|
+
id: string;
|
|
14
|
+
external?: boolean | string;
|
|
15
|
+
} | null>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The file `source` names when imported from `importer`, query stripped, or
|
|
19
|
+
* null when it is external or virtual. `skipNodeModules` also yields null for
|
|
20
|
+
* a dependency: transition-when-hoist only looks for `import "server-only"`
|
|
21
|
+
* in project files, while client-urls-revalidate-hoist must see the
|
|
22
|
+
* "use client" directive of a package's modules too.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveSourceTarget(ctx: SourceResolver, source: string, importer: string, options: {
|
|
25
|
+
readonly skipNodeModules: boolean;
|
|
26
|
+
}): Promise<string | null>;
|
|
27
|
+
/** What a hoist's RSC transform emitted for a file, and the disk source it saw. */
|
|
28
|
+
export interface EmittedEntry<T> {
|
|
29
|
+
readonly disk: string | null;
|
|
30
|
+
readonly value: T;
|
|
31
|
+
}
|
|
32
|
+
export declare function recordEmitted<T>(emitted: Map<string, EmittedEntry<T>>, file: string, value: T): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* What a `?rango-*` load serves for `hoistedFile`: the transform's emission
|
|
35
|
+
* when it saw the current disk source (or the file is gone), else
|
|
36
|
+
* `rehoist(disk)`. The transform hoists the pipeline code, which an earlier
|
|
37
|
+
* plugin may have changed, so re-hoisting the disk source is the fallback only
|
|
38
|
+
* for an environment loading before the RSC transform ran or for an edit the
|
|
39
|
+
* RSC environment has not re-transformed yet. Undefined when neither exists.
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadEmittedOrDisk<T>(emitted: ReadonlyMap<string, EmittedEntry<T>>, hoistedFile: string, rehoist: (disk: string) => Promise<T | undefined>): Promise<T | undefined>;
|
|
@@ -2,14 +2,14 @@ import type { Plugin } from "vite";
|
|
|
2
2
|
import MagicString from "magic-string";
|
|
3
3
|
/** Specifiers that can never load in the browser. */
|
|
4
4
|
export declare function isServerOnlySpecifier(source: string): boolean;
|
|
5
|
-
|
|
5
|
+
interface HoistTransitionWhenDeps {
|
|
6
6
|
/**
|
|
7
7
|
* Whether an import the literal re-emits is server-only beyond its
|
|
8
8
|
* specifier (the plugin resolves it and looks for `import "server-only"`).
|
|
9
9
|
*/
|
|
10
10
|
isServerOnlyImport?(source: string): Promise<boolean> | boolean;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
interface HoistTransitionWhenResult {
|
|
13
13
|
readonly code: string;
|
|
14
14
|
readonly map: ReturnType<MagicString["generateMap"]>;
|
|
15
15
|
/** Virtual module source per hoisted literal, by index. */
|
|
@@ -32,14 +32,11 @@ export declare function parseHoistedWhenId(id: string): {
|
|
|
32
32
|
* evaluated) and serves the `?rango-when=N` modules in every environment
|
|
33
33
|
* (RSC, SSR and client all load them).
|
|
34
34
|
*
|
|
35
|
-
* `load` serves the modules the transform emitted, not a
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* environment loading before the RSC transform ran (the order environments
|
|
41
|
-
* ask in is not fixed), or an edit the RSC environment has not re-transformed
|
|
42
|
-
* yet (serving the last transform would then be stale). The map is per
|
|
43
|
-
* plugin instance, so every environment of one dev server or build shares it.
|
|
35
|
+
* `load` serves the modules the transform emitted (loadEmittedOrDisk), not a
|
|
36
|
+
* re-hoist of the file on disk: re-hoisting a disk source an earlier plugin
|
|
37
|
+
* changed can number the literals differently and serve the wrong one for
|
|
38
|
+
* index N. The map is per plugin instance, so every environment of one dev
|
|
39
|
+
* server or build shares it.
|
|
44
40
|
*/
|
|
45
41
|
export declare function transitionWhenHoistPlugin(): Plugin;
|
|
42
|
+
export {};
|
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
import type { Plugin, ViteDevServer } from "vite";
|
|
9
9
|
import { VIRTUAL_ROUTES_MANIFEST_ID, type DiscoveryState, type PluginOptions } from "./discovery/state.js";
|
|
10
10
|
export { VIRTUAL_ROUTES_MANIFEST_ID };
|
|
11
|
+
/** The slice of a Vite environment module graph the route-file watcher reads. */
|
|
12
|
+
interface ModulesByFileGraph {
|
|
13
|
+
getModulesByFile(file: string): ReadonlySet<unknown> | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Whether the dev route-file watcher ignores `file`: it sits in a directory
|
|
17
|
+
* every discovery scan skips (isInSkippedScanDir) and the RSC graph has not
|
|
18
|
+
* loaded it. See docs/manifests.md, "A reload no file of the app asked for".
|
|
19
|
+
*/
|
|
20
|
+
export declare function isFileOutsideApp(root: string, file: string, rscGraph: ModulesByFileGraph | undefined): boolean;
|
|
11
21
|
/**
|
|
12
22
|
* Create a minimal Vite server for router discovery.
|
|
13
23
|
*
|