rari 0.5.28 → 0.5.29
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/client.mjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{runtime-client-DXbydP6X.mjs → runtime-client-Cbat2QnR.mjs} +49 -57
- package/dist/{vite-Crp6BBHv.mjs → vite-CHxbBtJP.mjs} +4 -4
- package/dist/vite.mjs +2 -2
- package/package.json +9 -9
- package/src/router/ClientRouter.tsx +74 -63
- package/src/router/rsc-parser.ts +8 -0
- package/src/router/rsc-types.ts +1 -0
- package/src/runtime/AppRouterProvider.tsx +224 -221
- package/src/runtime/entry-client.js +348 -186
- package/src/runtime/react-server-dom-rari-client.js +203 -35
- package/src/runtime/rsc-client-runtime.js +185 -14
package/dist/client.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as createNavigationError, S as NavigationErrorHandler, _ as LayoutErrorBoundary, a as LoadingSpinner, b as routeInfoCache, c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, l as createLoadingBoundary, m as extractServerPropsWithCache, n as DefaultLoading, o as NotFound, p as extractServerProps, r as ErrorBoundary, s as createErrorBoundary, t as DefaultError, u as clearPropsCache, v as ClientRouter, w as fetchWithTimeout, x as NavigationErrorOverlay, y as StatePreserver } from "./runtime-client-
|
|
1
|
+
import { C as createNavigationError, S as NavigationErrorHandler, _ as LayoutErrorBoundary, a as LoadingSpinner, b as routeInfoCache, c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, l as createLoadingBoundary, m as extractServerPropsWithCache, n as DefaultLoading, o as NotFound, p as extractServerProps, r as ErrorBoundary, s as createErrorBoundary, t as DefaultError, u as clearPropsCache, v as ClientRouter, w as fetchWithTimeout, x as NavigationErrorOverlay, y as StatePreserver } from "./runtime-client-Cbat2QnR.mjs";
|
|
2
2
|
|
|
3
3
|
export { ClientRouter, DefaultError, DefaultLoading, ErrorBoundary, HttpRuntimeClient, LayoutErrorBoundary, LoadingSpinner, NavigationErrorHandler, NavigationErrorOverlay, NotFound, StatePreserver, clearPropsCache, clearPropsCacheForComponent, createErrorBoundary, createHttpRuntimeClient, createLoadingBoundary, createNavigationError, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, fetchWithTimeout, hasServerSideDataFetching, routeInfoCache };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as headers, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, t as defineRariConfig } from "./vite-
|
|
1
|
+
import { a as headers, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, t as defineRariConfig } from "./vite-CHxbBtJP.mjs";
|
|
2
2
|
import { t as generateAppRouteManifest } from "./app-routes-KhTu0CFP.mjs";
|
|
3
|
-
import { c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, m as extractServerPropsWithCache, p as extractServerProps, u as clearPropsCache } from "./runtime-client-
|
|
3
|
+
import { c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, m as extractServerPropsWithCache, p as extractServerProps, u as clearPropsCache } from "./runtime-client-Cbat2QnR.mjs";
|
|
4
4
|
import "./server-build-CQpjQCX6.mjs";
|
|
5
5
|
|
|
6
6
|
export { HttpRuntimeClient, RariResponse, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, headers, rari, rariRouter };
|
|
@@ -836,12 +836,8 @@ function updateDocumentMetadata(metadata) {
|
|
|
836
836
|
function ClientRouter({ children, initialRoute }) {
|
|
837
837
|
const [navigationState, setNavigationState] = useState(() => ({
|
|
838
838
|
currentRoute: normalizePath(initialRoute),
|
|
839
|
-
targetRoute: null,
|
|
840
|
-
isNavigating: false,
|
|
841
839
|
navigationId: 0,
|
|
842
|
-
error: null
|
|
843
|
-
showingLoadingComponent: false,
|
|
844
|
-
loadingComponentRoute: null
|
|
840
|
+
error: null
|
|
845
841
|
}));
|
|
846
842
|
const abortControllerRef = useRef(null);
|
|
847
843
|
const isMountedRef = useRef(true);
|
|
@@ -874,13 +870,7 @@ function ClientRouter({ children, initialRoute }) {
|
|
|
874
870
|
};
|
|
875
871
|
const cleanupAbortedNavigation = (path, navigationId) => {
|
|
876
872
|
pendingNavigationsRef.current.delete(path);
|
|
877
|
-
if (isMountedRef.current && navigationState.navigationId === navigationId) setNavigationState((prev) => ({
|
|
878
|
-
...prev,
|
|
879
|
-
targetRoute: null,
|
|
880
|
-
isNavigating: false,
|
|
881
|
-
showingLoadingComponent: false,
|
|
882
|
-
loadingComponentRoute: null
|
|
883
|
-
}));
|
|
873
|
+
if (isMountedRef.current && navigationState.navigationId === navigationId) setNavigationState((prev) => ({ ...prev }));
|
|
884
874
|
};
|
|
885
875
|
const getRouteInfo = async (route) => {
|
|
886
876
|
return routeInfoCache.get(route);
|
|
@@ -895,34 +885,12 @@ function ClientRouter({ children, initialRoute }) {
|
|
|
895
885
|
if (targetPath === currentRouteRef.current && !options.replace) return;
|
|
896
886
|
const existingPending = pendingNavigationsRef.current.get(targetPath);
|
|
897
887
|
if (existingPending) return existingPending.promise;
|
|
898
|
-
if (navigationState.isNavigating && navigationState.targetRoute !== targetPath) {
|
|
899
|
-
navigationQueueRef.current.push({
|
|
900
|
-
path: targetPath,
|
|
901
|
-
options
|
|
902
|
-
});
|
|
903
|
-
return;
|
|
904
|
-
}
|
|
905
888
|
const routeInfo = await getRouteInfo(targetPath);
|
|
906
889
|
cancelAllPendingNavigations();
|
|
907
890
|
cancelNavigation();
|
|
908
891
|
const abortController = new AbortController();
|
|
909
892
|
abortControllerRef.current = abortController;
|
|
910
893
|
const navigationId = navigationState.navigationId + 1;
|
|
911
|
-
const loadingComponentPath = routeInfo.loading;
|
|
912
|
-
setNavigationState((prev) => ({
|
|
913
|
-
...prev,
|
|
914
|
-
targetRoute: targetPath,
|
|
915
|
-
isNavigating: true,
|
|
916
|
-
navigationId,
|
|
917
|
-
error: null,
|
|
918
|
-
showingLoadingComponent: !!loadingComponentPath,
|
|
919
|
-
loadingComponentRoute: loadingComponentPath
|
|
920
|
-
}));
|
|
921
|
-
if (loadingComponentPath) window.dispatchEvent(new CustomEvent("rari:show-loading", { detail: {
|
|
922
|
-
route: targetPath,
|
|
923
|
-
navigationId,
|
|
924
|
-
loadingPath: loadingComponentPath
|
|
925
|
-
} }));
|
|
926
894
|
const navigationPromise = (async () => {
|
|
927
895
|
const fromRoute = currentRouteRef.current;
|
|
928
896
|
try {
|
|
@@ -957,18 +925,50 @@ function ClientRouter({ children, initialRoute }) {
|
|
|
957
925
|
updateDocumentMetadata(JSON.parse(decodedMetadata));
|
|
958
926
|
}
|
|
959
927
|
} catch {}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
928
|
+
if (response.headers.get("x-render-mode") === "streaming" && response.body) {
|
|
929
|
+
const reader = response.body.getReader();
|
|
930
|
+
const decoder = new TextDecoder();
|
|
931
|
+
let buffer = "";
|
|
932
|
+
try {
|
|
933
|
+
while (true) {
|
|
934
|
+
const { done, value } = await reader.read();
|
|
935
|
+
if (done) break;
|
|
936
|
+
if (abortController.signal.aborted) {
|
|
937
|
+
await reader.cancel();
|
|
938
|
+
cleanupAbortedNavigation(targetPath, navigationId);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
buffer += decoder.decode(value, { stream: true });
|
|
942
|
+
const lines = buffer.split("\n");
|
|
943
|
+
buffer = lines.pop() || "";
|
|
944
|
+
for (const line of lines) if (line.trim()) window.dispatchEvent(new CustomEvent("rari:rsc-row", { detail: { rscRow: line } }));
|
|
945
|
+
}
|
|
946
|
+
if (buffer.trim()) window.dispatchEvent(new CustomEvent("rari:rsc-row", { detail: { rscRow: buffer } }));
|
|
947
|
+
window.dispatchEvent(new CustomEvent("rari:navigate", { detail: {
|
|
948
|
+
from: fromRoute,
|
|
949
|
+
to: targetPath,
|
|
950
|
+
navigationId,
|
|
951
|
+
options,
|
|
952
|
+
routeInfo,
|
|
953
|
+
abortSignal: abortController.signal,
|
|
954
|
+
isStreaming: true
|
|
955
|
+
} }));
|
|
956
|
+
} catch (streamError) {
|
|
957
|
+
console.error("[ClientRouter] Streaming error:", streamError);
|
|
958
|
+
throw streamError;
|
|
959
|
+
}
|
|
960
|
+
} else {
|
|
961
|
+
const rscWireFormat = await response.text();
|
|
962
|
+
window.dispatchEvent(new CustomEvent("rari:navigate", { detail: {
|
|
963
|
+
from: fromRoute,
|
|
964
|
+
to: targetPath,
|
|
965
|
+
navigationId,
|
|
966
|
+
options,
|
|
967
|
+
routeInfo,
|
|
968
|
+
abortSignal: abortController.signal,
|
|
969
|
+
rscWireFormat
|
|
970
|
+
} }));
|
|
971
|
+
}
|
|
972
972
|
if (abortController.signal.aborted) {
|
|
973
973
|
cleanupAbortedNavigation(targetPath, navigationId);
|
|
974
974
|
return;
|
|
@@ -978,11 +978,7 @@ function ClientRouter({ children, initialRoute }) {
|
|
|
978
978
|
setNavigationState((prev) => ({
|
|
979
979
|
...prev,
|
|
980
980
|
currentRoute: targetPath,
|
|
981
|
-
|
|
982
|
-
isNavigating: false,
|
|
983
|
-
error: null,
|
|
984
|
-
showingLoadingComponent: false,
|
|
985
|
-
loadingComponentRoute: null
|
|
981
|
+
error: null
|
|
986
982
|
}));
|
|
987
983
|
errorHandlerRef.current.resetRetry(targetPath);
|
|
988
984
|
if (options.historyKey) requestAnimationFrame(() => {
|
|
@@ -999,11 +995,7 @@ function ClientRouter({ children, initialRoute }) {
|
|
|
999
995
|
const navError = errorHandlerRef.current.handleError(error, targetPath);
|
|
1000
996
|
if (isMountedRef.current) setNavigationState((prev) => ({
|
|
1001
997
|
...prev,
|
|
1002
|
-
|
|
1003
|
-
isNavigating: false,
|
|
1004
|
-
error: navError,
|
|
1005
|
-
showingLoadingComponent: false,
|
|
1006
|
-
loadingComponentRoute: null
|
|
998
|
+
error: navError
|
|
1007
999
|
}));
|
|
1008
1000
|
pendingNavigationsRef.current.delete(targetPath);
|
|
1009
1001
|
window.dispatchEvent(new CustomEvent("rari:navigate-error", { detail: {
|
|
@@ -1024,7 +1016,7 @@ function ClientRouter({ children, initialRoute }) {
|
|
|
1024
1016
|
return navigationPromise;
|
|
1025
1017
|
};
|
|
1026
1018
|
const processNavigationQueue = async () => {
|
|
1027
|
-
if (navigationQueueRef.current.length === 0
|
|
1019
|
+
if (navigationQueueRef.current.length === 0) return;
|
|
1028
1020
|
const lastNavigation = navigationQueueRef.current[navigationQueueRef.current.length - 1];
|
|
1029
1021
|
navigationQueueRef.current = [];
|
|
1030
1022
|
await navigate(lastNavigation.path, lastNavigation.options);
|
|
@@ -1677,7 +1677,7 @@ function getAffectedRoutes(routePath, fileType, allRoutes) {
|
|
|
1677
1677
|
});
|
|
1678
1678
|
return affected.length > 0 ? affected : [routePath];
|
|
1679
1679
|
}
|
|
1680
|
-
function extractMetadata
|
|
1680
|
+
function extractMetadata(fileContent) {
|
|
1681
1681
|
try {
|
|
1682
1682
|
const match = fileContent.match(/export\s+const\s+metadata\s*(?::\s*\w+\s*)?=\s*(\{[\s\S]*?\n\})/);
|
|
1683
1683
|
if (!match) return null;
|
|
@@ -1784,8 +1784,8 @@ function rariRouter(options = {}) {
|
|
|
1784
1784
|
const currentRouteFiles = await scanRouteFiles(appDir);
|
|
1785
1785
|
const currentHash = computeRouteStructureHash(currentRouteFiles);
|
|
1786
1786
|
if (!forceRegenerate && routeStructureHash === currentHash && cachedManifestContent) return cachedManifestContent;
|
|
1787
|
-
const { generateAppRouteManifest
|
|
1788
|
-
const manifest = await generateAppRouteManifest
|
|
1787
|
+
const { generateAppRouteManifest } = await import("./app-routes-q03OTf5N.mjs");
|
|
1788
|
+
const manifest = await generateAppRouteManifest(appDir, { extensions: opts.extensions });
|
|
1789
1789
|
const manifestContent = JSON.stringify(manifest, null, 2);
|
|
1790
1790
|
const outDir = path.resolve(root, opts.outDir);
|
|
1791
1791
|
await promises.mkdir(outDir, { recursive: true });
|
|
@@ -1869,7 +1869,7 @@ function rariRouter(options = {}) {
|
|
|
1869
1869
|
let metadataChanged = false;
|
|
1870
1870
|
let methods;
|
|
1871
1871
|
if (fileType === "page" || fileType === "layout") try {
|
|
1872
|
-
const extractedMetadata = extractMetadata
|
|
1872
|
+
const extractedMetadata = extractMetadata(await promises.readFile(file, "utf-8"));
|
|
1873
1873
|
if (extractedMetadata) {
|
|
1874
1874
|
metadata = extractedMetadata;
|
|
1875
1875
|
metadataChanged = true;
|
package/dist/vite.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as headers, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, t as defineRariConfig } from "./vite-
|
|
1
|
+
import { a as headers, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, t as defineRariConfig } from "./vite-CHxbBtJP.mjs";
|
|
2
2
|
import { t as generateAppRouteManifest } from "./app-routes-KhTu0CFP.mjs";
|
|
3
|
-
import { c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, m as extractServerPropsWithCache, p as extractServerProps, u as clearPropsCache } from "./runtime-client-
|
|
3
|
+
import { c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, m as extractServerPropsWithCache, p as extractServerProps, u as clearPropsCache } from "./runtime-client-Cbat2QnR.mjs";
|
|
4
4
|
import "./server-build-CQpjQCX6.mjs";
|
|
5
5
|
|
|
6
6
|
export { HttpRuntimeClient, RariResponse, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, headers, rari, rariRouter };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rari",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.29",
|
|
5
5
|
"description": "Runtime Accelerated Rendering Infrastructure (Rari)",
|
|
6
6
|
"author": "Ryan Skinner",
|
|
7
7
|
"license": "MIT",
|
|
@@ -89,20 +89,20 @@
|
|
|
89
89
|
"picocolors": "^1.1.1"
|
|
90
90
|
},
|
|
91
91
|
"optionalDependencies": {
|
|
92
|
-
"rari-darwin-arm64": "0.5.
|
|
93
|
-
"rari-darwin-x64": "0.5.
|
|
94
|
-
"rari-linux-arm64": "0.5.
|
|
95
|
-
"rari-linux-x64": "0.5.
|
|
96
|
-
"rari-win32-x64": "0.5.
|
|
92
|
+
"rari-darwin-arm64": "0.5.23",
|
|
93
|
+
"rari-darwin-x64": "0.5.23",
|
|
94
|
+
"rari-linux-arm64": "0.5.23",
|
|
95
|
+
"rari-linux-x64": "0.5.23",
|
|
96
|
+
"rari-win32-x64": "0.5.23"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@types/node": "^25.0.3",
|
|
100
100
|
"@types/react": "^19.2.7",
|
|
101
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
101
|
+
"@typescript/native-preview": "^7.0.0-dev.20260102.1",
|
|
102
102
|
"chokidar": "^5.0.0",
|
|
103
103
|
"eslint": "^9.39.2",
|
|
104
|
-
"oxlint": "^1.
|
|
104
|
+
"oxlint": "^1.36.0",
|
|
105
105
|
"rolldown-vite": "^7.3.0",
|
|
106
|
-
"tsdown": "^0.
|
|
106
|
+
"tsdown": "^0.18.4"
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -205,12 +205,8 @@ export interface ClientRouterProps {
|
|
|
205
205
|
|
|
206
206
|
interface NavigationState {
|
|
207
207
|
currentRoute: string
|
|
208
|
-
targetRoute: string | null
|
|
209
|
-
isNavigating: boolean
|
|
210
208
|
navigationId: number
|
|
211
209
|
error: NavigationError | null
|
|
212
|
-
showingLoadingComponent: boolean
|
|
213
|
-
loadingComponentRoute: string | null
|
|
214
210
|
}
|
|
215
211
|
|
|
216
212
|
interface PendingNavigation {
|
|
@@ -231,12 +227,8 @@ interface HistoryState {
|
|
|
231
227
|
export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
232
228
|
const [navigationState, setNavigationState] = useState<NavigationState>(() => ({
|
|
233
229
|
currentRoute: normalizePath(initialRoute),
|
|
234
|
-
targetRoute: null,
|
|
235
|
-
isNavigating: false,
|
|
236
230
|
navigationId: 0,
|
|
237
231
|
error: null,
|
|
238
|
-
showingLoadingComponent: false,
|
|
239
|
-
loadingComponentRoute: null,
|
|
240
232
|
}))
|
|
241
233
|
|
|
242
234
|
const abortControllerRef = useRef<AbortController | null>(null)
|
|
@@ -288,10 +280,6 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
288
280
|
if (isMountedRef.current && navigationState.navigationId === navigationId) {
|
|
289
281
|
setNavigationState(prev => ({
|
|
290
282
|
...prev,
|
|
291
|
-
targetRoute: null,
|
|
292
|
-
isNavigating: false,
|
|
293
|
-
showingLoadingComponent: false,
|
|
294
|
-
loadingComponentRoute: null,
|
|
295
283
|
}))
|
|
296
284
|
}
|
|
297
285
|
}
|
|
@@ -319,11 +307,6 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
319
307
|
return existingPending.promise
|
|
320
308
|
}
|
|
321
309
|
|
|
322
|
-
if (navigationState.isNavigating && navigationState.targetRoute !== targetPath) {
|
|
323
|
-
navigationQueueRef.current.push({ path: targetPath, options })
|
|
324
|
-
return
|
|
325
|
-
}
|
|
326
|
-
|
|
327
310
|
const routeInfo = await getRouteInfo(targetPath)
|
|
328
311
|
|
|
329
312
|
cancelAllPendingNavigations()
|
|
@@ -334,28 +317,6 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
334
317
|
|
|
335
318
|
const navigationId = navigationState.navigationId + 1
|
|
336
319
|
|
|
337
|
-
const loadingComponentPath = routeInfo.loading
|
|
338
|
-
|
|
339
|
-
setNavigationState(prev => ({
|
|
340
|
-
...prev,
|
|
341
|
-
targetRoute: targetPath,
|
|
342
|
-
isNavigating: true,
|
|
343
|
-
navigationId,
|
|
344
|
-
error: null,
|
|
345
|
-
showingLoadingComponent: !!loadingComponentPath,
|
|
346
|
-
loadingComponentRoute: loadingComponentPath,
|
|
347
|
-
}))
|
|
348
|
-
|
|
349
|
-
if (loadingComponentPath) {
|
|
350
|
-
window.dispatchEvent(new CustomEvent('rari:show-loading', {
|
|
351
|
-
detail: {
|
|
352
|
-
route: targetPath,
|
|
353
|
-
navigationId,
|
|
354
|
-
loadingPath: loadingComponentPath,
|
|
355
|
-
},
|
|
356
|
-
}))
|
|
357
|
-
}
|
|
358
|
-
|
|
359
320
|
const navigationPromise = (async () => {
|
|
360
321
|
const fromRoute = currentRouteRef.current
|
|
361
322
|
try {
|
|
@@ -416,21 +377,79 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
416
377
|
}
|
|
417
378
|
catch {}
|
|
418
379
|
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
380
|
+
const renderMode = response.headers.get('x-render-mode')
|
|
381
|
+
const isStreaming = renderMode === 'streaming'
|
|
382
|
+
|
|
383
|
+
if (isStreaming && response.body) {
|
|
384
|
+
const reader = response.body.getReader()
|
|
385
|
+
const decoder = new TextDecoder()
|
|
386
|
+
let buffer = ''
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
while (true) {
|
|
390
|
+
const { done, value } = await reader.read()
|
|
391
|
+
|
|
392
|
+
if (done)
|
|
393
|
+
break
|
|
394
|
+
|
|
395
|
+
if (abortController.signal.aborted) {
|
|
396
|
+
await reader.cancel()
|
|
397
|
+
cleanupAbortedNavigation(targetPath, navigationId)
|
|
398
|
+
return
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
buffer += decoder.decode(value, { stream: true })
|
|
402
|
+
|
|
403
|
+
const lines = buffer.split('\n')
|
|
404
|
+
buffer = lines.pop() || ''
|
|
405
|
+
|
|
406
|
+
for (const line of lines) {
|
|
407
|
+
if (line.trim()) {
|
|
408
|
+
window.dispatchEvent(new CustomEvent('rari:rsc-row', {
|
|
409
|
+
detail: { rscRow: line },
|
|
410
|
+
}))
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (buffer.trim()) {
|
|
416
|
+
window.dispatchEvent(new CustomEvent('rari:rsc-row', {
|
|
417
|
+
detail: { rscRow: buffer },
|
|
418
|
+
}))
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
window.dispatchEvent(new CustomEvent('rari:navigate', {
|
|
422
|
+
detail: {
|
|
423
|
+
from: fromRoute,
|
|
424
|
+
to: targetPath,
|
|
425
|
+
navigationId,
|
|
426
|
+
options,
|
|
427
|
+
routeInfo,
|
|
428
|
+
abortSignal: abortController.signal,
|
|
429
|
+
isStreaming: true,
|
|
430
|
+
},
|
|
431
|
+
}))
|
|
432
|
+
}
|
|
433
|
+
catch (streamError) {
|
|
434
|
+
console.error('[ClientRouter] Streaming error:', streamError)
|
|
435
|
+
throw streamError
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
const rscWireFormat = await response.text()
|
|
440
|
+
|
|
441
|
+
window.dispatchEvent(new CustomEvent('rari:navigate', {
|
|
442
|
+
detail: {
|
|
443
|
+
from: fromRoute,
|
|
444
|
+
to: targetPath,
|
|
445
|
+
navigationId,
|
|
446
|
+
options,
|
|
447
|
+
routeInfo,
|
|
448
|
+
abortSignal: abortController.signal,
|
|
449
|
+
rscWireFormat,
|
|
450
|
+
},
|
|
451
|
+
}))
|
|
452
|
+
}
|
|
434
453
|
|
|
435
454
|
if (abortController.signal.aborted) {
|
|
436
455
|
cleanupAbortedNavigation(targetPath, navigationId)
|
|
@@ -443,11 +462,7 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
443
462
|
setNavigationState(prev => ({
|
|
444
463
|
...prev,
|
|
445
464
|
currentRoute: targetPath,
|
|
446
|
-
targetRoute: null,
|
|
447
|
-
isNavigating: false,
|
|
448
465
|
error: null,
|
|
449
|
-
showingLoadingComponent: false,
|
|
450
|
-
loadingComponentRoute: null,
|
|
451
466
|
}))
|
|
452
467
|
|
|
453
468
|
errorHandlerRef.current.resetRetry(targetPath)
|
|
@@ -474,11 +489,7 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
474
489
|
if (isMountedRef.current) {
|
|
475
490
|
setNavigationState(prev => ({
|
|
476
491
|
...prev,
|
|
477
|
-
targetRoute: null,
|
|
478
|
-
isNavigating: false,
|
|
479
492
|
error: navError,
|
|
480
|
-
showingLoadingComponent: false,
|
|
481
|
-
loadingComponentRoute: null,
|
|
482
493
|
}))
|
|
483
494
|
}
|
|
484
495
|
|
|
@@ -508,7 +519,7 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
|
|
|
508
519
|
}
|
|
509
520
|
|
|
510
521
|
const processNavigationQueue = async () => {
|
|
511
|
-
if (navigationQueueRef.current.length === 0
|
|
522
|
+
if (navigationQueueRef.current.length === 0) {
|
|
512
523
|
return
|
|
513
524
|
}
|
|
514
525
|
|
package/src/router/rsc-parser.ts
CHANGED
|
@@ -13,6 +13,7 @@ export function parseRscWireFormat(
|
|
|
13
13
|
try {
|
|
14
14
|
const lines = wireFormat.trim().split('\n')
|
|
15
15
|
const modules = new Map<string, any>()
|
|
16
|
+
const symbols = new Map<string, string>()
|
|
16
17
|
let rootElement = null
|
|
17
18
|
const layoutBoundaries: LayoutBoundary[] = []
|
|
18
19
|
let currentLayoutPath: string | null = null
|
|
@@ -30,6 +31,12 @@ export function parseRscWireFormat(
|
|
|
30
31
|
const content = line.substring(colonIndex + 1)
|
|
31
32
|
|
|
32
33
|
try {
|
|
34
|
+
if (content.startsWith('"$S')) {
|
|
35
|
+
const symbolName = content.slice(1, -1)
|
|
36
|
+
symbols.set(`$${rowId}`, symbolName)
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
|
|
33
40
|
if (content.startsWith('I[')) {
|
|
34
41
|
const importData = JSON.parse(content.substring(1))
|
|
35
42
|
if (Array.isArray(importData) && importData.length >= 3) {
|
|
@@ -118,6 +125,7 @@ export function parseRscWireFormat(
|
|
|
118
125
|
return {
|
|
119
126
|
element: rootElement,
|
|
120
127
|
modules,
|
|
128
|
+
symbols,
|
|
121
129
|
wireFormat,
|
|
122
130
|
layoutBoundaries: options.extractLayoutBoundaries ? layoutBoundaries : undefined,
|
|
123
131
|
routeMetadata,
|
package/src/router/rsc-types.ts
CHANGED