@rangojs/router 0.0.0-experimental.100 → 0.0.0-experimental.102
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 +16 -1
- package/dist/vite/index.js +81 -14
- package/package.json +1 -1
- package/skills/hooks/SKILL.md +78 -0
- package/skills/loader/SKILL.md +7 -0
- package/src/browser/history-state.ts +21 -0
- package/src/browser/navigation-bridge.ts +2 -6
- package/src/browser/navigation-transaction.ts +3 -7
- package/src/browser/react/location-state-shared.ts +82 -1
- package/src/browser/react/location-state.ts +39 -13
- package/src/browser/react/use-router.ts +14 -1
- package/src/browser/scroll-restoration.ts +22 -14
- package/src/href-client.ts +4 -1
- package/src/loader-store.ts +202 -0
- package/src/use-loader.tsx +181 -37
- package/src/vite/discovery/state.ts +9 -0
- package/src/vite/plugins/version-plugin.ts +57 -0
- package/src/vite/router-discovery.ts +73 -14
|
@@ -987,10 +987,25 @@ export function createRouterDiscoveryPlugin(
|
|
|
987
987
|
writeRouteTypesFiles(s),
|
|
988
988
|
);
|
|
989
989
|
}
|
|
990
|
+
if (s.lastDiscoveryError) {
|
|
991
|
+
debugDiscovery?.(
|
|
992
|
+
"hmr: cleared lastDiscoveryError (%s) after successful rediscovery",
|
|
993
|
+
s.lastDiscoveryError.message,
|
|
994
|
+
);
|
|
995
|
+
s.lastDiscoveryError = null;
|
|
996
|
+
}
|
|
990
997
|
} catch (err: any) {
|
|
998
|
+
s.lastDiscoveryError = {
|
|
999
|
+
message: err?.message ?? String(err),
|
|
1000
|
+
at: Date.now(),
|
|
1001
|
+
};
|
|
991
1002
|
console.warn(
|
|
992
1003
|
`[rsc-router] Runtime re-discovery failed: ${err.message}`,
|
|
993
1004
|
);
|
|
1005
|
+
debugDiscovery?.(
|
|
1006
|
+
"hmr: lastDiscoveryError set (%s) — manifest preserved at last-good; recovery mode active (any in-scan source change will trigger rediscovery)",
|
|
1007
|
+
err?.message,
|
|
1008
|
+
);
|
|
994
1009
|
} finally {
|
|
995
1010
|
debugDiscovery?.(
|
|
996
1011
|
"hmr re-discovery done (%sms)",
|
|
@@ -1059,27 +1074,63 @@ export function createRouterDiscoveryPlugin(
|
|
|
1059
1074
|
!filePath.endsWith(".tsx") &&
|
|
1060
1075
|
!filePath.endsWith(".js") &&
|
|
1061
1076
|
!filePath.endsWith(".jsx")
|
|
1062
|
-
)
|
|
1077
|
+
) {
|
|
1078
|
+
if (s.lastDiscoveryError) {
|
|
1079
|
+
debugDiscovery?.(
|
|
1080
|
+
"watcher: skip non-source %s [LASTERR %s]",
|
|
1081
|
+
filePath,
|
|
1082
|
+
s.lastDiscoveryError.message,
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1063
1085
|
return;
|
|
1086
|
+
}
|
|
1064
1087
|
// Apply scan filter as early-exit before reading file
|
|
1065
|
-
if (s.scanFilter && !s.scanFilter(filePath))
|
|
1088
|
+
if (s.scanFilter && !s.scanFilter(filePath)) {
|
|
1089
|
+
if (s.lastDiscoveryError) {
|
|
1090
|
+
debugDiscovery?.(
|
|
1091
|
+
"watcher: skip scan-filter %s [LASTERR %s]",
|
|
1092
|
+
filePath,
|
|
1093
|
+
s.lastDiscoveryError.message,
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
// Recovery mode: when the previous HMR re-discovery failed, the
|
|
1099
|
+
// import graph is incomplete and the manifest is stuck at the
|
|
1100
|
+
// last-good state. The fix may land in a non-route file (e.g. a
|
|
1101
|
+
// helper imported by the router, a missing module being created,
|
|
1102
|
+
// or a "use client" component) that the narrow content sniff
|
|
1103
|
+
// would otherwise filter out. While in recovery, treat any
|
|
1104
|
+
// in-scan source change as a candidate for rediscovery; the
|
|
1105
|
+
// tighter filter resumes once discovery succeeds again.
|
|
1106
|
+
const inRecoveryMode = !!s.lastDiscoveryError;
|
|
1066
1107
|
try {
|
|
1067
1108
|
const source = readFileSync(filePath, "utf-8");
|
|
1068
1109
|
const trimmed = source.trimStart();
|
|
1069
|
-
|
|
1110
|
+
const isUseClient =
|
|
1070
1111
|
trimmed.startsWith('"use client"') ||
|
|
1071
|
-
trimmed.startsWith("'use client'")
|
|
1072
|
-
)
|
|
1073
|
-
return;
|
|
1112
|
+
trimmed.startsWith("'use client'");
|
|
1113
|
+
if (!inRecoveryMode && isUseClient) return;
|
|
1074
1114
|
const hasUrls = source.includes("urls(");
|
|
1075
1115
|
const hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
|
|
1076
|
-
if (!hasUrls && !hasCreateRouter) return;
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1116
|
+
if (!inRecoveryMode && !hasUrls && !hasCreateRouter) return;
|
|
1117
|
+
if (inRecoveryMode) {
|
|
1118
|
+
debugDiscovery?.(
|
|
1119
|
+
"watcher: recovery rediscovery for %s (urls=%s, router=%s, useClient=%s) [LASTERR %s]",
|
|
1120
|
+
filePath,
|
|
1121
|
+
hasUrls,
|
|
1122
|
+
hasCreateRouter,
|
|
1123
|
+
isUseClient,
|
|
1124
|
+
s.lastDiscoveryError!.message,
|
|
1125
|
+
);
|
|
1126
|
+
} else {
|
|
1127
|
+
debugDiscovery?.(
|
|
1128
|
+
"watcher: %s matches (urls=%s, router=%s)",
|
|
1129
|
+
filePath,
|
|
1130
|
+
hasUrls,
|
|
1131
|
+
hasCreateRouter,
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1083
1134
|
// Invalidate cache when a router file changes (new router added/removed)
|
|
1084
1135
|
if (hasCreateRouter) {
|
|
1085
1136
|
const nestedRouterConflict = findNestedRouterConflict([
|
|
@@ -1106,7 +1157,15 @@ export function createRouterDiscoveryPlugin(
|
|
|
1106
1157
|
gate.noteRouteEvent();
|
|
1107
1158
|
}
|
|
1108
1159
|
scheduleRouteRegeneration();
|
|
1109
|
-
} catch {
|
|
1160
|
+
} catch (readErr: any) {
|
|
1161
|
+
if (s.lastDiscoveryError) {
|
|
1162
|
+
debugDiscovery?.(
|
|
1163
|
+
"watcher: read error %s: %s [LASTERR %s]",
|
|
1164
|
+
filePath,
|
|
1165
|
+
readErr?.message,
|
|
1166
|
+
s.lastDiscoveryError.message,
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1110
1169
|
// Ignore read errors for deleted/moved files
|
|
1111
1170
|
}
|
|
1112
1171
|
};
|