@rangojs/router 0.0.0-experimental.20 → 0.0.0-experimental.204030a9
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/AGENTS.md +4 -0
- package/README.md +242 -55
- package/dist/bin/rango.js +277 -99
- package/dist/vite/index.js +2929 -1132
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +68 -21
- package/skills/breadcrumbs/SKILL.md +252 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +243 -21
- package/skills/caching/SKILL.md +159 -10
- package/skills/composability/SKILL.md +27 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +262 -51
- package/skills/host-router/SKILL.md +243 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +46 -4
- package/skills/layout/SKILL.md +28 -7
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +291 -31
- package/skills/middleware/SKILL.md +49 -12
- package/skills/migrate-nextjs/SKILL.md +562 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +197 -6
- package/skills/prerender/SKILL.md +125 -102
- package/skills/rango/SKILL.md +242 -23
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +66 -9
- package/skills/route/SKILL.md +91 -8
- package/skills/router-setup/SKILL.md +98 -8
- package/skills/server-actions/SKILL.md +751 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/testing/SKILL.md +511 -188
- package/skills/typesafety/SKILL.md +354 -50
- package/skills/use-cache/SKILL.md +34 -5
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +117 -0
- package/src/__internal.ts +92 -0
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +91 -70
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +183 -18
- package/src/browser/navigation-client.ts +187 -57
- package/src/browser/navigation-store.ts +75 -17
- package/src/browser/navigation-transaction.ts +21 -37
- package/src/browser/partial-update.ts +143 -40
- package/src/browser/prefetch/cache.ts +275 -28
- package/src/browser/prefetch/fetch.ts +191 -46
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +123 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +53 -13
- package/src/browser/react/Link.tsx +98 -14
- package/src/browser/react/NavigationProvider.tsx +110 -33
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +51 -7
- package/src/browser/react/index.ts +3 -0
- package/src/browser/react/location-state-shared.ts +175 -4
- package/src/browser/react/location-state.ts +39 -13
- package/src/browser/react/use-handle.ts +23 -64
- package/src/browser/react/use-navigation.ts +22 -2
- package/src/browser/react/use-params.ts +20 -8
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +43 -10
- package/src/browser/react/use-segments.ts +11 -8
- package/src/browser/response-adapter.ts +25 -0
- package/src/browser/rsc-router.tsx +200 -75
- package/src/browser/scroll-restoration.ts +46 -39
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +31 -36
- package/src/browser/types.ts +81 -5
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -0
- package/src/build/index.ts +2 -0
- package/src/build/route-trie.ts +69 -26
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +278 -88
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-runtime.ts +15 -11
- package/src/cache/cache-scope.ts +76 -49
- package/src/cache/cf/cf-cache-store.ts +501 -18
- package/src/cache/cf/index.ts +5 -1
- package/src/cache/document-cache.ts +17 -7
- package/src/cache/index.ts +1 -0
- package/src/cache/taint.ts +55 -0
- package/src/client.rsc.tsx +5 -1
- package/src/client.tsx +95 -284
- package/src/context-var.ts +72 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/errors.ts +30 -1
- package/src/handle.ts +65 -12
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/host/index.ts +2 -5
- package/src/host/router.ts +129 -57
- package/src/host/types.ts +31 -2
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +140 -20
- package/src/index.rsc.ts +15 -40
- package/src/index.ts +92 -76
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +2 -5
- package/src/loader.ts +3 -10
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/prerender/store.ts +57 -15
- package/src/prerender.ts +141 -80
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/route-content-wrapper.tsx +6 -28
- package/src/route-definition/dsl-helpers.ts +435 -260
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +110 -34
- package/src/route-definition/index.ts +3 -3
- package/src/route-definition/redirect.ts +11 -3
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -1
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +113 -1
- package/src/router/error-handling.ts +1 -1
- package/src/router/find-match.ts +4 -2
- package/src/router/handler-context.ts +105 -39
- package/src/router/intercept-resolution.ts +15 -22
- package/src/router/lazy-includes.ts +12 -9
- package/src/router/loader-resolution.ts +175 -23
- package/src/router/logging.ts +5 -2
- package/src/router/manifest.ts +31 -16
- package/src/router/match-api.ts +129 -193
- package/src/router/match-handlers.ts +63 -20
- package/src/router/match-middleware/background-revalidation.ts +30 -2
- package/src/router/match-middleware/cache-lookup.ts +136 -106
- package/src/router/match-middleware/cache-store.ts +54 -10
- package/src/router/match-middleware/intercept-resolution.ts +9 -7
- package/src/router/match-middleware/segment-resolution.ts +61 -5
- package/src/router/match-result.ts +124 -18
- package/src/router/metrics.ts +239 -14
- package/src/router/middleware-types.ts +61 -31
- package/src/router/middleware.ts +226 -124
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +118 -19
- package/src/router/prerender-match.ts +114 -10
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +286 -0
- package/src/router/revalidation.ts +85 -9
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +6 -1
- package/src/router/router-interfaces.ts +91 -29
- package/src/router/router-options.ts +89 -19
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +240 -23
- package/src/router/segment-resolution/helpers.ts +30 -25
- package/src/router/segment-resolution/loader-cache.ts +1 -0
- package/src/router/segment-resolution/revalidation.ts +483 -289
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-wrappers.ts +2 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry.ts +99 -0
- package/src/router/trie-matching.ts +38 -15
- package/src/router/types.ts +9 -0
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +120 -32
- package/src/rsc/handler-context.ts +2 -2
- package/src/rsc/handler.ts +524 -370
- package/src/rsc/helpers.ts +91 -43
- package/src/rsc/index.ts +1 -21
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +5 -1
- package/src/rsc/origin-guard.ts +28 -10
- package/src/rsc/progressive-enhancement.ts +39 -10
- package/src/rsc/response-route-handler.ts +46 -53
- package/src/rsc/rsc-rendering.ts +69 -89
- package/src/rsc/runtime-warnings.ts +9 -10
- package/src/rsc/server-action.ts +39 -47
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/types.ts +19 -3
- package/src/search-params.ts +20 -17
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +219 -67
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +285 -63
- package/src/server/cookie-store.ts +28 -4
- package/src/server/handle-store.ts +19 -0
- package/src/server/loader-registry.ts +9 -8
- package/src/server/request-context.ts +228 -65
- package/src/server.ts +6 -0
- package/src/ssr/index.tsx +9 -1
- package/src/static-handler.ts +19 -7
- package/src/testing/cache-status.ts +166 -0
- package/src/testing/collect-handle.ts +63 -0
- package/src/testing/dispatch.ts +440 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +154 -0
- package/src/testing/e2e/index.ts +149 -0
- package/src/testing/e2e/matchers.ts +51 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +306 -0
- package/src/testing/e2e/server.ts +183 -0
- package/src/testing/flight-matchers.ts +104 -0
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/flight.entry.ts +22 -0
- package/src/testing/flight.ts +182 -0
- package/src/testing/generated-routes.ts +223 -0
- package/src/testing/index.ts +98 -0
- package/src/testing/internal/context.ts +151 -0
- package/src/testing/render-route.tsx +536 -0
- package/src/testing/run-loader.ts +296 -0
- package/src/testing/run-middleware.ts +170 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +112 -0
- package/src/theme/index.ts +4 -13
- package/src/types/cache-types.ts +4 -4
- package/src/types/global-namespace.ts +39 -26
- package/src/types/handler-context.ts +197 -79
- package/src/types/index.ts +1 -0
- package/src/types/loader-types.ts +41 -15
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-config.ts +17 -8
- package/src/types/route-entry.ts +19 -1
- package/src/types/segments.ts +37 -6
- package/src/urls/include-helper.ts +34 -67
- package/src/urls/index.ts +0 -3
- package/src/urls/path-helper-types.ts +50 -9
- package/src/urls/path-helper.ts +63 -63
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +26 -116
- package/src/urls/urls-function.ts +1 -5
- package/src/use-loader.tsx +487 -44
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +63 -91
- package/src/vite/discovery/discover-routers.ts +106 -53
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +222 -107
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +50 -13
- package/src/vite/discovery/virtual-module-codegen.ts +13 -23
- package/src/vite/index.ts +10 -3
- package/src/vite/plugin-types.ts +111 -72
- package/src/vite/plugins/cjs-to-esm.ts +8 -7
- package/src/vite/plugins/client-ref-dedup.ts +16 -0
- package/src/vite/plugins/client-ref-hashing.ts +28 -5
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
- package/src/vite/plugins/expose-action-id.ts +55 -33
- package/src/vite/plugins/expose-id-utils.ts +24 -8
- package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
- package/src/vite/plugins/expose-ids/handler-transform.ts +12 -35
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
- package/src/vite/plugins/expose-internal-ids.ts +544 -317
- package/src/vite/plugins/performance-tracks.ts +92 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +65 -50
- package/src/vite/plugins/version-injector.ts +39 -23
- package/src/vite/plugins/version-plugin.ts +72 -3
- package/src/vite/plugins/virtual-entries.ts +2 -2
- package/src/vite/rango.ts +265 -226
- package/src/vite/router-discovery.ts +924 -137
- package/src/vite/utils/ast-handler-extract.ts +15 -15
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +4 -2
- package/src/vite/utils/client-chunks.ts +190 -0
- package/src/vite/utils/forward-user-plugins.ts +193 -0
- package/src/vite/utils/manifest-utils.ts +21 -5
- package/src/vite/utils/package-resolution.ts +41 -1
- package/src/vite/utils/prerender-utils.ts +98 -5
- package/src/vite/utils/shared-utils.ts +109 -27
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/route-definition/route-function.ts +0 -119
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
buildExportMap,
|
|
7
7
|
escapeRegExp,
|
|
8
8
|
} from "../expose-id-utils.js";
|
|
9
|
+
import { codeMatchIndices } from "../../../build/route-types/source-scan.js";
|
|
9
10
|
import type { CreateExportBinding } from "./types.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -59,19 +60,57 @@ export function isExportOnlyFile(
|
|
|
59
60
|
return true;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
function createCallPattern(fnNames: string[]): RegExp {
|
|
64
|
+
return new RegExp(
|
|
65
|
+
`\\b(?:${fnNames.map(escapeRegExp).join("|")})\\s*(?:<[^>]*>\\s*)?\\(`,
|
|
66
|
+
"g",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Counts real create*() call sites, ignoring occurrences inside comments and
|
|
71
|
+
// string literals. Used by the unsupported-shape warning heuristic and the
|
|
72
|
+
// inline-extraction pre-check.
|
|
66
73
|
export function countCreateCallsForNames(
|
|
67
74
|
code: string,
|
|
68
75
|
fnNames: string[],
|
|
69
76
|
): number {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
return codeMatchIndices(code, createCallPattern(fnNames)).length;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Convert a 0-based byte offset to a 1-based { line, column }. */
|
|
81
|
+
export function offsetToLineColumn(
|
|
82
|
+
code: string,
|
|
83
|
+
index: number,
|
|
84
|
+
): { line: number; column: number } {
|
|
85
|
+
let line = 1;
|
|
86
|
+
let lineStart = 0;
|
|
87
|
+
const end = Math.min(index, code.length);
|
|
88
|
+
for (let i = 0; i < end; i++) {
|
|
89
|
+
if (code[i] === "\n") {
|
|
90
|
+
line++;
|
|
91
|
+
lineStart = i + 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { line, column: index - lineStart + 1 };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Locate every real create*() call site (comment/string-free) that is NOT one
|
|
99
|
+
* of the supported, id-injectable export bindings, returning each as a 1-based
|
|
100
|
+
* { line, column }. The empty result means every call is in a supported shape.
|
|
101
|
+
* Both binding-collection paths anchor `callExprStart` at the start of the
|
|
102
|
+
* create* identifier — exactly where this pattern matches — so the set
|
|
103
|
+
* difference is exact.
|
|
104
|
+
*/
|
|
105
|
+
export function findUnsupportedCreateCallSites(
|
|
106
|
+
code: string,
|
|
107
|
+
fnNames: string[],
|
|
108
|
+
supportedBindings: CreateExportBinding[],
|
|
109
|
+
): Array<{ line: number; column: number }> {
|
|
110
|
+
const supported = new Set(supportedBindings.map((b) => b.callExprStart));
|
|
111
|
+
return codeMatchIndices(code, createCallPattern(fnNames))
|
|
112
|
+
.filter((index) => !supported.has(index))
|
|
113
|
+
.map((index) => offsetToLineColumn(code, index));
|
|
75
114
|
}
|
|
76
115
|
|
|
77
116
|
export function getImportedFnNames(
|
|
@@ -119,6 +158,28 @@ export function getCalledIdentifierFromCall(callExpr: any): string | null {
|
|
|
119
158
|
return null;
|
|
120
159
|
}
|
|
121
160
|
|
|
161
|
+
/**
|
|
162
|
+
* plugin-react's dev Fast Refresh wraps exports whose function body uses
|
|
163
|
+
* hook-like calls in a signature-registration call. A loader/handle that calls
|
|
164
|
+
* `ctx.use(...)` trips this heuristic, so `export const X = createLoader(...)`
|
|
165
|
+
* becomes `export const X = _s(createLoader(...), "<sig>", true)` — the create*
|
|
166
|
+
* call is the first argument of an unrelated wrapper call. Unwrap a single such
|
|
167
|
+
* layer so ID injection still targets the inner create* call. The `$$id`
|
|
168
|
+
* assignment is appended after the whole statement (against the export local),
|
|
169
|
+
* which is unaffected by the wrapper since `_s(x)` returns `x`.
|
|
170
|
+
*/
|
|
171
|
+
function unwrapSignatureWrappedCall(init: any, fnNameSet: Set<string>): any {
|
|
172
|
+
if (init?.type !== "CallExpression") return init;
|
|
173
|
+
const directId = getCalledIdentifierFromCall(init);
|
|
174
|
+
if (directId && fnNameSet.has(directId)) return init;
|
|
175
|
+
const firstArg = init.arguments?.[0];
|
|
176
|
+
if (firstArg?.type === "CallExpression") {
|
|
177
|
+
const innerId = getCalledIdentifierFromCall(firstArg);
|
|
178
|
+
if (innerId && fnNameSet.has(innerId)) return firstArg;
|
|
179
|
+
}
|
|
180
|
+
return init;
|
|
181
|
+
}
|
|
182
|
+
|
|
122
183
|
export function collectCreateExportBindingsFallback(
|
|
123
184
|
code: string,
|
|
124
185
|
fnNames: string[],
|
|
@@ -196,7 +257,7 @@ export function collectCreateExportBindings(
|
|
|
196
257
|
): CreateExportBinding[] {
|
|
197
258
|
if (!program) {
|
|
198
259
|
try {
|
|
199
|
-
program = parseAst(code, {
|
|
260
|
+
program = parseAst(code, { lang: "tsx" });
|
|
200
261
|
} catch {
|
|
201
262
|
return collectCreateExportBindingsFallback(code, fnNames);
|
|
202
263
|
}
|
|
@@ -212,10 +273,13 @@ export function collectCreateExportBindings(
|
|
|
212
273
|
}
|
|
213
274
|
|
|
214
275
|
for (const decl of varDecl.declarations ?? []) {
|
|
215
|
-
|
|
276
|
+
// Unwrap a Fast Refresh signature wrapper (`_s(createLoader(...), ...)`)
|
|
277
|
+
// so injection targets the inner create* call. Falls back to decl.init.
|
|
278
|
+
const callExpr = unwrapSignatureWrappedCall(decl?.init, fnNameSet);
|
|
279
|
+
const calledIdentifier = getCalledIdentifierFromCall(callExpr);
|
|
216
280
|
if (
|
|
217
281
|
decl?.id?.type !== "Identifier" ||
|
|
218
|
-
|
|
282
|
+
callExpr?.type !== "CallExpression" ||
|
|
219
283
|
!calledIdentifier ||
|
|
220
284
|
!fnNameSet.has(calledIdentifier)
|
|
221
285
|
) {
|
|
@@ -226,9 +290,8 @@ export function collectCreateExportBindings(
|
|
|
226
290
|
const exportNames = exportMap.get(localName) ?? [];
|
|
227
291
|
if (exportNames.length === 0) continue;
|
|
228
292
|
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
const calleeEnd = decl.init.callee.end as number;
|
|
293
|
+
const callEnd = callExpr.end as number;
|
|
294
|
+
const calleeEnd = callExpr.callee.end as number;
|
|
232
295
|
|
|
233
296
|
let openParenPos = -1;
|
|
234
297
|
for (let i = calleeEnd; i < callEnd; i++) {
|
|
@@ -245,10 +308,10 @@ export function collectCreateExportBindings(
|
|
|
245
308
|
bindings.push({
|
|
246
309
|
localName,
|
|
247
310
|
exportNames,
|
|
248
|
-
callExprStart:
|
|
311
|
+
callExprStart: callExpr.start as number,
|
|
249
312
|
callOpenParenPos: openParenPos,
|
|
250
313
|
callCloseParenPos: closeParenPos,
|
|
251
|
-
argCount:
|
|
314
|
+
argCount: callExpr.arguments?.length ?? 0,
|
|
252
315
|
statementEnd,
|
|
253
316
|
});
|
|
254
317
|
}
|
|
@@ -282,9 +345,25 @@ export function collectCreateExportBindings(
|
|
|
282
345
|
export function buildUnsupportedShapeWarning(
|
|
283
346
|
filePath: string,
|
|
284
347
|
fnName: string,
|
|
348
|
+
sites: Array<{ line: number; column: number }> = [],
|
|
285
349
|
): string {
|
|
286
|
-
|
|
287
|
-
|
|
350
|
+
const lines = [`[rango] Unsupported ${fnName} shape in "${filePath}".`];
|
|
351
|
+
|
|
352
|
+
// Point at the exact call(s) so the location is clickable in the terminal/IDE
|
|
353
|
+
// (file:line:column) instead of leaving the user to scan the whole file.
|
|
354
|
+
if (sites.length === 1) {
|
|
355
|
+
const s = sites[0];
|
|
356
|
+
lines.push(
|
|
357
|
+
`The ${fnName}(...) call at ${filePath}:${s.line}:${s.column} has no stable $$id injected — it is not in a supported shape.`,
|
|
358
|
+
);
|
|
359
|
+
} else if (sites.length > 1) {
|
|
360
|
+
lines.push(
|
|
361
|
+
`These ${fnName}(...) calls have no stable $$id injected — they are not in a supported shape:`,
|
|
362
|
+
);
|
|
363
|
+
for (const s of sites) lines.push(` - ${filePath}:${s.line}:${s.column}`);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
lines.push(
|
|
288
367
|
`Supported shapes are:`,
|
|
289
368
|
` - export const X = ${fnName}(...)`,
|
|
290
369
|
` - const X = ${fnName}(...); export { X }`,
|
|
@@ -292,5 +371,6 @@ export function buildUnsupportedShapeWarning(
|
|
|
292
371
|
`Potentially unsupported forms include:`,
|
|
293
372
|
` - export let/var X = ${fnName}(...)`,
|
|
294
373
|
` - inline ${fnName}(...) calls`,
|
|
295
|
-
|
|
374
|
+
);
|
|
375
|
+
return lines.join("\n");
|
|
296
376
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import MagicString from "magic-string";
|
|
2
|
-
import {
|
|
2
|
+
import { makeStubId } from "../expose-id-utils.js";
|
|
3
3
|
import type { HandlerTransformConfig, CreateExportBinding } from "./types.js";
|
|
4
4
|
import { isExportOnlyFile } from "./export-analysis.js";
|
|
5
5
|
|
|
@@ -28,9 +28,7 @@ export function transformHandles(
|
|
|
28
28
|
binding.callCloseParenPos,
|
|
29
29
|
);
|
|
30
30
|
|
|
31
|
-
const handleId = isBuild
|
|
32
|
-
? hashId(filePath, exportName)
|
|
33
|
-
: `${filePath}#${exportName}`;
|
|
31
|
+
const handleId = makeStubId(filePath, exportName, isBuild);
|
|
34
32
|
|
|
35
33
|
let paramInjection: string;
|
|
36
34
|
if (!args.hasArgs) {
|
|
@@ -58,9 +56,7 @@ export function transformLocationState(
|
|
|
58
56
|
for (const binding of bindings) {
|
|
59
57
|
const exportName = binding.exportNames[0];
|
|
60
58
|
|
|
61
|
-
const stateKey = isBuild
|
|
62
|
-
? hashId(filePath, exportName)
|
|
63
|
-
: `${filePath}#${exportName}`;
|
|
59
|
+
const stateKey = makeStubId(filePath, exportName, isBuild);
|
|
64
60
|
|
|
65
61
|
// Key is injected as a property assignment (not as a function argument).
|
|
66
62
|
// This allows createLocationState to accept options like { flash: true }
|
|
@@ -88,7 +84,7 @@ export function generateWholeFileStubs(
|
|
|
88
84
|
|
|
89
85
|
const exportNames = bindings.flatMap((b) => b.exportNames);
|
|
90
86
|
const stubs = exportNames.map((name) => {
|
|
91
|
-
const handlerId =
|
|
87
|
+
const handlerId = makeStubId(filePath, name, isBuild);
|
|
92
88
|
return `export const ${name} = { __brand: "${cfg.brand}", $$id: "${handlerId}" };`;
|
|
93
89
|
});
|
|
94
90
|
|
|
@@ -96,27 +92,20 @@ export function generateWholeFileStubs(
|
|
|
96
92
|
}
|
|
97
93
|
|
|
98
94
|
/**
|
|
99
|
-
* Replace handler call expressions with lightweight stub objects
|
|
100
|
-
*
|
|
95
|
+
* Replace handler call expressions with lightweight stub objects on the shared
|
|
96
|
+
* unified-pipeline MagicString so all transforms share one sourcemap.
|
|
101
97
|
*/
|
|
102
|
-
export function
|
|
98
|
+
export function stubHandlerExprs(
|
|
103
99
|
cfg: HandlerTransformConfig,
|
|
104
100
|
bindings: CreateExportBinding[],
|
|
105
|
-
|
|
101
|
+
s: MagicString,
|
|
106
102
|
filePath: string,
|
|
107
|
-
sourceId: string,
|
|
108
103
|
isBuild: boolean,
|
|
109
|
-
):
|
|
110
|
-
if (bindings.length === 0) return null;
|
|
111
|
-
|
|
112
|
-
const s = new MagicString(code);
|
|
104
|
+
): boolean {
|
|
113
105
|
let hasChanges = false;
|
|
114
|
-
|
|
115
106
|
for (const binding of bindings) {
|
|
116
107
|
const exportName = binding.exportNames[0];
|
|
117
|
-
const handlerId = isBuild
|
|
118
|
-
? hashId(filePath, exportName)
|
|
119
|
-
: `${filePath}#${exportName}`;
|
|
108
|
+
const handlerId = makeStubId(filePath, exportName, isBuild);
|
|
120
109
|
|
|
121
110
|
s.overwrite(
|
|
122
111
|
binding.callExprStart,
|
|
@@ -125,17 +114,7 @@ export function generateExprStubs(
|
|
|
125
114
|
);
|
|
126
115
|
hasChanges = true;
|
|
127
116
|
}
|
|
128
|
-
|
|
129
|
-
if (!hasChanges) return null;
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
code: s.toString(),
|
|
133
|
-
map: s.generateMap({
|
|
134
|
-
source: sourceId,
|
|
135
|
-
includeContent: true,
|
|
136
|
-
hires: "boundary",
|
|
137
|
-
}),
|
|
138
|
-
};
|
|
117
|
+
return hasChanges;
|
|
139
118
|
}
|
|
140
119
|
|
|
141
120
|
/**
|
|
@@ -152,9 +131,7 @@ export function transformHandlerIds(
|
|
|
152
131
|
for (const binding of bindings) {
|
|
153
132
|
const exportName = binding.exportNames[0];
|
|
154
133
|
|
|
155
|
-
const handlerId = isBuild
|
|
156
|
-
? hashId(filePath, exportName)
|
|
157
|
-
: `${filePath}#${exportName}`;
|
|
134
|
+
const handlerId = makeStubId(filePath, exportName, isBuild);
|
|
158
135
|
|
|
159
136
|
// Injection strategy matches the runtime overload signatures:
|
|
160
137
|
// 0 args -> inject undefined, "id"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type MagicString from "magic-string";
|
|
2
|
-
import {
|
|
2
|
+
import { makeStubId } from "../expose-id-utils.js";
|
|
3
3
|
import type { CreateExportBinding } from "./types.js";
|
|
4
4
|
import { isExportOnlyFile } from "./export-analysis.js";
|
|
5
5
|
|
|
@@ -33,7 +33,7 @@ export function generateClientLoaderStubs(
|
|
|
33
33
|
|
|
34
34
|
for (const binding of bindings) {
|
|
35
35
|
for (const name of binding.exportNames) {
|
|
36
|
-
const loaderId =
|
|
36
|
+
const loaderId = makeStubId(filePath, name, isBuild);
|
|
37
37
|
lines.push(
|
|
38
38
|
`export const ${name} = { __brand: "loader", $$id: "${loaderId}" };`,
|
|
39
39
|
);
|
|
@@ -54,9 +54,7 @@ export function transformLoaders(
|
|
|
54
54
|
for (const binding of bindings) {
|
|
55
55
|
const exportName = binding.exportNames[0];
|
|
56
56
|
|
|
57
|
-
const loaderId = isBuild
|
|
58
|
-
? hashId(filePath, exportName)
|
|
59
|
-
: `${filePath}#${exportName}`;
|
|
57
|
+
const loaderId = makeStubId(filePath, exportName, isBuild);
|
|
60
58
|
|
|
61
59
|
// Inject $$id as hidden third parameter.
|
|
62
60
|
// createLoader(fn) -> createLoader(fn, undefined, "id")
|
|
@@ -4,6 +4,9 @@ import path from "node:path";
|
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { normalizePath, findMatchingParen } from "../expose-id-utils.js";
|
|
6
6
|
import { getImportedFnNames } from "./export-analysis.js";
|
|
7
|
+
import { createRangoDebugger, createCounter, NS } from "../../debug.js";
|
|
8
|
+
|
|
9
|
+
const debug = createRangoDebugger(NS.transform);
|
|
7
10
|
|
|
8
11
|
export function transformRouter(
|
|
9
12
|
code: string,
|
|
@@ -82,11 +85,15 @@ export function transformRouter(
|
|
|
82
85
|
*/
|
|
83
86
|
export function exposeRouterId(): Plugin {
|
|
84
87
|
let projectRoot = "";
|
|
88
|
+
const counter = createCounter(debug, "expose-router-id");
|
|
85
89
|
return {
|
|
86
90
|
name: "@rangojs/router:expose-router-id",
|
|
87
91
|
configResolved(config) {
|
|
88
92
|
projectRoot = config.root;
|
|
89
93
|
},
|
|
94
|
+
buildEnd() {
|
|
95
|
+
counter?.flush();
|
|
96
|
+
},
|
|
90
97
|
transform(code, id) {
|
|
91
98
|
if (!code.includes("createRouter")) return null;
|
|
92
99
|
// Accepts both @rangojs/router and @rangojs/router/server subpath.
|
|
@@ -102,9 +109,19 @@ export function exposeRouterId(): Plugin {
|
|
|
102
109
|
}
|
|
103
110
|
if (id.includes("node_modules")) return null;
|
|
104
111
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
const start = counter ? performance.now() : 0;
|
|
113
|
+
try {
|
|
114
|
+
const filePath = normalizePath(path.relative(projectRoot, id));
|
|
115
|
+
const routerFnNames = getImportedFnNames(code, "createRouter");
|
|
116
|
+
return transformRouter(
|
|
117
|
+
code,
|
|
118
|
+
filePath,
|
|
119
|
+
routerFnNames,
|
|
120
|
+
normalizePath(id),
|
|
121
|
+
);
|
|
122
|
+
} finally {
|
|
123
|
+
counter?.record(id, performance.now() - start);
|
|
124
|
+
}
|
|
108
125
|
},
|
|
109
126
|
};
|
|
110
127
|
}
|