@rangojs/router 0.0.0-experimental.8 → 0.0.0-experimental.8a4d0430
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 +5 -0
- package/README.md +884 -4
- package/dist/bin/rango.js +1601 -0
- package/dist/vite/index.js +4474 -867
- package/package.json +60 -51
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +262 -0
- package/skills/caching/SKILL.md +50 -21
- package/skills/composability/SKILL.md +172 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +18 -16
- package/skills/fonts/SKILL.md +167 -0
- package/skills/hooks/SKILL.md +334 -72
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +131 -8
- package/skills/layout/SKILL.md +100 -3
- package/skills/links/SKILL.md +89 -30
- package/skills/loader/SKILL.md +388 -38
- package/skills/middleware/SKILL.md +171 -34
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +78 -1
- package/skills/prerender/SKILL.md +643 -0
- package/skills/rango/SKILL.md +85 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +226 -14
- package/skills/router-setup/SKILL.md +123 -30
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +318 -89
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +321 -0
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/event-controller.ts +87 -64
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +285 -553
- package/src/browser/navigation-client.ts +124 -71
- package/src/browser/navigation-store.ts +33 -50
- package/src/browser/navigation-transaction.ts +295 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +258 -308
- package/src/browser/prefetch/cache.ts +146 -0
- package/src/browser/prefetch/fetch.ts +135 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +42 -0
- package/src/browser/prefetch/queue.ts +88 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +185 -73
- package/src/browser/react/NavigationProvider.tsx +51 -11
- package/src/browser/react/context.ts +6 -0
- package/src/browser/react/filter-segment-order.ts +11 -0
- package/src/browser/react/index.ts +12 -12
- package/src/browser/react/location-state-shared.ts +95 -53
- package/src/browser/react/location-state.ts +60 -15
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +32 -79
- package/src/browser/react/use-href.tsx +2 -2
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +22 -63
- package/src/browser/react/use-params.ts +65 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-router.ts +63 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +80 -97
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +107 -26
- package/src/browser/scroll-restoration.ts +92 -16
- package/src/browser/segment-reconciler.ts +216 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +504 -599
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +109 -47
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +235 -24
- package/src/build/generate-route-types.ts +36 -0
- package/src/build/index.ts +13 -0
- package/src/build/route-trie.ts +265 -0
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +411 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +128 -0
- package/src/build/route-types/router-processing.ts +469 -0
- package/src/build/route-types/scan-filter.ts +78 -0
- package/src/build/runtime-discovery.ts +231 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +338 -0
- package/src/cache/cache-scope.ts +120 -303
- package/src/cache/cf/cf-cache-store.ts +119 -7
- package/src/cache/cf/index.ts +8 -2
- package/src/cache/document-cache.ts +101 -72
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +0 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +98 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +106 -126
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +86 -0
- package/src/debug.ts +17 -7
- package/src/errors.ts +108 -2
- package/src/handle.ts +15 -29
- package/src/handles/MetaTags.tsx +73 -20
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +30 -13
- package/src/host/cookie-handler.ts +21 -15
- package/src/host/errors.ts +8 -8
- package/src/host/index.ts +4 -7
- package/src/host/pattern-matcher.ts +27 -27
- package/src/host/router.ts +61 -39
- package/src/host/testing.ts +8 -8
- package/src/host/types.ts +15 -7
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +119 -29
- package/src/index.rsc.ts +153 -19
- package/src/index.ts +211 -30
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +26 -157
- package/src/loader.ts +27 -10
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +37 -0
- package/src/prerender/store.ts +185 -0
- package/src/prerender.ts +463 -0
- package/src/reverse.ts +330 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +934 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +430 -0
- package/src/route-definition/index.ts +52 -0
- package/src/route-definition/redirect.ts +93 -0
- package/src/route-definition.ts +1 -1428
- package/src/route-map-builder.ts +211 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +59 -8
- package/src/router/content-negotiation.ts +116 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +9 -9
- package/src/router/find-match.ts +158 -0
- package/src/router/handler-context.ts +374 -81
- package/src/router/intercept-resolution.ts +395 -0
- package/src/router/lazy-includes.ts +234 -0
- package/src/router/loader-resolution.ts +215 -122
- package/src/router/logging.ts +248 -0
- package/src/router/manifest.ts +148 -35
- package/src/router/match-api.ts +620 -0
- package/src/router/match-context.ts +5 -3
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +80 -93
- package/src/router/match-middleware/cache-lookup.ts +382 -9
- package/src/router/match-middleware/cache-store.ts +51 -22
- package/src/router/match-middleware/intercept-resolution.ts +55 -17
- package/src/router/match-middleware/segment-resolution.ts +24 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +34 -28
- package/src/router/metrics.ts +235 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +222 -0
- package/src/router/middleware.ts +324 -367
- package/src/router/pattern-matching.ts +211 -43
- package/src/router/prerender-match.ts +402 -0
- package/src/router/preview-match.ts +170 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/router-context.ts +36 -21
- package/src/router/router-interfaces.ts +452 -0
- package/src/router/router-options.ts +592 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +570 -0
- package/src/router/segment-resolution/helpers.ts +263 -0
- package/src/router/segment-resolution/loader-cache.ts +198 -0
- package/src/router/segment-resolution/revalidation.ts +1241 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -0
- package/src/router/segment-wrappers.ts +289 -0
- package/src/router/telemetry-otel.ts +299 -0
- package/src/router/telemetry.ts +300 -0
- package/src/router/timeout.ts +148 -0
- package/src/router/trie-matching.ts +239 -0
- package/src/router/types.ts +77 -3
- package/src/router.ts +692 -4257
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +764 -754
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +209 -0
- package/src/rsc/manifest-init.ts +86 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +379 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +235 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +348 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +38 -11
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +25 -13
- package/src/server/context.ts +182 -51
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +94 -15
- package/src/server/loader-registry.ts +15 -56
- package/src/server/request-context.ts +430 -70
- package/src/server.ts +35 -130
- package/src/ssr/index.tsx +100 -31
- package/src/static-handler.ts +114 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +5 -2
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +4 -30
- package/src/theme/theme-script.ts +21 -18
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +100 -0
- package/src/types/handler-context.ts +687 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +183 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +102 -0
- package/src/types/segments.ts +148 -0
- package/src/types.ts +1 -1623
- package/src/urls/include-helper.ts +197 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +339 -0
- package/src/urls/path-helper.ts +329 -0
- package/src/urls/pattern-types.ts +95 -0
- package/src/urls/response-types.ts +106 -0
- package/src/urls/type-extraction.ts +372 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -802
- package/src/use-loader.tsx +85 -77
- package/src/vite/discovery/bundle-postprocess.ts +184 -0
- package/src/vite/discovery/discover-routers.ts +344 -0
- package/src/vite/discovery/prerender-collection.ts +385 -0
- package/src/vite/discovery/route-types-writer.ts +258 -0
- package/src/vite/discovery/self-gen-tracking.ts +47 -0
- package/src/vite/discovery/state.ts +110 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +11 -1133
- package/src/vite/plugin-types.ts +131 -0
- package/src/vite/plugins/cjs-to-esm.ts +93 -0
- package/src/vite/plugins/client-ref-dedup.ts +115 -0
- package/src/vite/plugins/client-ref-hashing.ts +105 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -51
- package/src/vite/plugins/expose-id-utils.ts +287 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +569 -0
- package/src/vite/plugins/refresh-cmd.ts +65 -0
- package/src/vite/plugins/use-cache-transform.ts +323 -0
- package/src/vite/plugins/version-injector.ts +83 -0
- package/src/vite/plugins/version-plugin.ts +254 -0
- package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +23 -14
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +510 -0
- package/src/vite/router-discovery.ts +785 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +137 -0
- package/src/vite/utils/manifest-utils.ts +70 -0
- package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
- package/src/vite/utils/prerender-utils.ts +189 -0
- package/src/vite/utils/shared-utils.ts +169 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/href-context.ts +0 -33
- package/src/href.ts +0 -255
- package/src/server/route-manifest-cache.ts +0 -173
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -426
- package/src/vite/expose-location-state-id.ts +0 -177
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -13,6 +13,19 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export type HandleData = Record<string, Record<string, unknown[]>>;
|
|
15
15
|
|
|
16
|
+
function createLateHandlePushError(
|
|
17
|
+
handleName: string,
|
|
18
|
+
segmentId: string,
|
|
19
|
+
): Error {
|
|
20
|
+
const error = new Error(
|
|
21
|
+
`Handle "${handleName}" for segment "${segmentId}" was pushed after handle collection completed. ` +
|
|
22
|
+
`This usually means an async JSX subtree suspended and later tried to push a handle during streaming. ` +
|
|
23
|
+
`Push handles from the route/layout handler or during the initial synchronous JSX render instead.`,
|
|
24
|
+
);
|
|
25
|
+
error.name = "LateHandlePushError";
|
|
26
|
+
return error;
|
|
27
|
+
}
|
|
28
|
+
|
|
16
29
|
/**
|
|
17
30
|
* Deep clone handle data to create a snapshot.
|
|
18
31
|
* @internal
|
|
@@ -44,11 +57,26 @@ export interface HandleStore {
|
|
|
44
57
|
track<T>(promise: Promise<T>): Promise<T>;
|
|
45
58
|
|
|
46
59
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
60
|
+
* Signal that no more track() calls will be made.
|
|
61
|
+
* settled will not resolve until seal() is called AND all tracked
|
|
62
|
+
* promises have settled. Calling stream() or getData() auto-seals.
|
|
63
|
+
*/
|
|
64
|
+
seal(): void;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Promise that resolves when the store is sealed AND all tracked
|
|
68
|
+
* handlers have settled.
|
|
49
69
|
*/
|
|
50
70
|
readonly settled: Promise<void>;
|
|
51
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Optional error callback for late streaming-handle failures.
|
|
74
|
+
* Called when push() throws LateHandlePushError (handle pushed after
|
|
75
|
+
* stream completion). Allows the router to surface these errors
|
|
76
|
+
* to onError and telemetry.
|
|
77
|
+
*/
|
|
78
|
+
onError?: (error: Error) => void;
|
|
79
|
+
|
|
52
80
|
/**
|
|
53
81
|
* Push handle data for a specific handle and segment.
|
|
54
82
|
* Multiple pushes to the same handle/segment accumulate in an array.
|
|
@@ -58,9 +86,7 @@ export interface HandleStore {
|
|
|
58
86
|
|
|
59
87
|
/**
|
|
60
88
|
* Get all collected handle data after all handlers have settled.
|
|
61
|
-
*
|
|
62
|
-
* The data may contain unresolved promises which RSC will stream.
|
|
63
|
-
* @deprecated Use stream() for progressive updates
|
|
89
|
+
* Waits for `settled`, then returns the finalized data.
|
|
64
90
|
*/
|
|
65
91
|
getData(): Promise<HandleData>;
|
|
66
92
|
|
|
@@ -81,7 +107,10 @@ export interface HandleStore {
|
|
|
81
107
|
* Replay cached handle data back into the store (for cache hits).
|
|
82
108
|
* Used to restore handle data when serving cached segments.
|
|
83
109
|
*/
|
|
84
|
-
replaySegmentData(
|
|
110
|
+
replaySegmentData(
|
|
111
|
+
segmentId: string,
|
|
112
|
+
segmentHandles: Record<string, unknown[]>,
|
|
113
|
+
): void;
|
|
85
114
|
}
|
|
86
115
|
|
|
87
116
|
/**
|
|
@@ -105,9 +134,31 @@ export interface HandleStore {
|
|
|
105
134
|
* ```
|
|
106
135
|
*/
|
|
107
136
|
export function createHandleStore(): HandleStore {
|
|
108
|
-
const pending: Promise<unknown>[] = [];
|
|
109
137
|
const data: HandleData = {};
|
|
110
138
|
|
|
139
|
+
// Settlement barrier: resolved only when sealed AND inflight === 0.
|
|
140
|
+
// seal() signals "no more track() calls". Each track() increments
|
|
141
|
+
// inflightCount, each promise.finally() decrements. settled resolves
|
|
142
|
+
// once both conditions are met — even if tracks are added while
|
|
143
|
+
// earlier ones are still in flight.
|
|
144
|
+
let sealed = false;
|
|
145
|
+
let inflightCount = 0;
|
|
146
|
+
let drainWaiters: (() => void)[] = [];
|
|
147
|
+
|
|
148
|
+
function notifyDrain() {
|
|
149
|
+
if (sealed && inflightCount === 0 && drainWaiters.length > 0) {
|
|
150
|
+
const waiters = drainWaiters;
|
|
151
|
+
drainWaiters = [];
|
|
152
|
+
for (const resolve of waiters) resolve();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function sealInternal() {
|
|
157
|
+
if (sealed) return;
|
|
158
|
+
sealed = true;
|
|
159
|
+
notifyDrain();
|
|
160
|
+
}
|
|
161
|
+
|
|
111
162
|
// Queue for pending emissions and resolver for waiting consumer
|
|
112
163
|
let pendingEmissions: HandleData[] = [];
|
|
113
164
|
let emissionResolver: (() => void) | null = null;
|
|
@@ -134,18 +185,38 @@ export function createHandleStore(): HandleStore {
|
|
|
134
185
|
|
|
135
186
|
return {
|
|
136
187
|
track<T>(promise: Promise<T>): Promise<T> {
|
|
137
|
-
|
|
188
|
+
inflightCount++;
|
|
189
|
+
// Use .then(onSettle, onSettle) instead of .finally() to avoid
|
|
190
|
+
// creating an unhandled rejection branch when the tracked promise
|
|
191
|
+
// rejects (e.g. error route handlers). .finally() re-throws the
|
|
192
|
+
// rejection on a new branch that nobody catches, which can crash
|
|
193
|
+
// the server process.
|
|
194
|
+
const onSettle = () => {
|
|
195
|
+
inflightCount--;
|
|
196
|
+
notifyDrain();
|
|
197
|
+
};
|
|
198
|
+
promise.then(onSettle, onSettle);
|
|
138
199
|
return promise;
|
|
139
200
|
},
|
|
140
201
|
|
|
202
|
+
seal() {
|
|
203
|
+
sealInternal();
|
|
204
|
+
},
|
|
205
|
+
|
|
141
206
|
get settled(): Promise<void> {
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
207
|
+
if (sealed && inflightCount === 0) return Promise.resolve();
|
|
208
|
+
return new Promise<void>((resolve) => {
|
|
209
|
+
drainWaiters.push(resolve);
|
|
210
|
+
});
|
|
146
211
|
},
|
|
147
212
|
|
|
148
213
|
push(handleName: string, segmentId: string, value: unknown): void {
|
|
214
|
+
if (completed) {
|
|
215
|
+
const error = createLateHandlePushError(handleName, segmentId);
|
|
216
|
+
if (this.onError) this.onError(error);
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
|
|
149
220
|
if (!data[handleName]) {
|
|
150
221
|
data[handleName] = {};
|
|
151
222
|
}
|
|
@@ -160,10 +231,14 @@ export function createHandleStore(): HandleStore {
|
|
|
160
231
|
},
|
|
161
232
|
|
|
162
233
|
getData(): Promise<HandleData> {
|
|
163
|
-
|
|
234
|
+
sealInternal();
|
|
235
|
+
return this.settled.then(() => cloneHandleData(data));
|
|
164
236
|
},
|
|
165
237
|
|
|
166
238
|
async *stream(): AsyncGenerator<HandleData, void, unknown> {
|
|
239
|
+
// Auto-seal: stream() is called after all track() registrations.
|
|
240
|
+
sealInternal();
|
|
241
|
+
|
|
167
242
|
// Set up completion handler
|
|
168
243
|
this.settled.then(() => {
|
|
169
244
|
completed = true;
|
|
@@ -178,7 +253,8 @@ export function createHandleStore(): HandleStore {
|
|
|
178
253
|
if (Object.keys(data).length > 0) {
|
|
179
254
|
// Clear pending emissions since we're yielding current state
|
|
180
255
|
pendingEmissions = [];
|
|
181
|
-
|
|
256
|
+
const snapshot = cloneHandleData(data);
|
|
257
|
+
yield snapshot;
|
|
182
258
|
}
|
|
183
259
|
|
|
184
260
|
// Continue streaming on each push
|
|
@@ -211,7 +287,10 @@ export function createHandleStore(): HandleStore {
|
|
|
211
287
|
return result;
|
|
212
288
|
},
|
|
213
289
|
|
|
214
|
-
replaySegmentData(
|
|
290
|
+
replaySegmentData(
|
|
291
|
+
segmentId: string,
|
|
292
|
+
segmentHandles: Record<string, unknown[]>,
|
|
293
|
+
): void {
|
|
215
294
|
for (const handleName in segmentHandles) {
|
|
216
295
|
if (!data[handleName]) {
|
|
217
296
|
data[handleName] = {};
|
|
@@ -6,13 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { LoaderFn } from "../types.js";
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
fn: LoaderFn<any, any, any>;
|
|
14
|
-
middleware: MiddlewareFn[];
|
|
15
|
-
}
|
|
9
|
+
import {
|
|
10
|
+
getFetchableLoader,
|
|
11
|
+
type LoaderRegistryEntry,
|
|
12
|
+
} from "./fetchable-loader-store.js";
|
|
16
13
|
|
|
17
14
|
// Server-side cache - maps loader $$id to function and middleware
|
|
18
15
|
// This is a CACHE populated by getLoaderLazy() when loaders are first accessed.
|
|
@@ -21,7 +18,7 @@ interface RegisteredLoader {
|
|
|
21
18
|
// 1. Avoid repeated lookups/imports for the same loader
|
|
22
19
|
// 2. Support lazy loading in production (loaders imported on-demand)
|
|
23
20
|
// 3. Provide a stable reference for the RSC handler
|
|
24
|
-
const loaderRegistry = new Map<string,
|
|
21
|
+
const loaderRegistry = new Map<string, LoaderRegistryEntry>();
|
|
25
22
|
|
|
26
23
|
// Lazy import map - set by the loader manifest
|
|
27
24
|
// Maps loader $$id to a function that imports the loader module
|
|
@@ -32,35 +29,11 @@ let lazyLoaderImports: Map<string, LazyLoaderImport> | null = null;
|
|
|
32
29
|
* Set the lazy loader imports map (called by the loader manifest)
|
|
33
30
|
*/
|
|
34
31
|
export function setLoaderImports(
|
|
35
|
-
imports: Record<string, LazyLoaderImport
|
|
32
|
+
imports: Record<string, LazyLoaderImport>,
|
|
36
33
|
): void {
|
|
37
34
|
lazyLoaderImports = new Map(Object.entries(imports));
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
/**
|
|
41
|
-
* Register a fetchable loader by $$id
|
|
42
|
-
* Called by createLoader when fetchable option is provided
|
|
43
|
-
*/
|
|
44
|
-
export function registerLoader(
|
|
45
|
-
id: string,
|
|
46
|
-
fn: LoaderFn<any, any, any>,
|
|
47
|
-
middleware: MiddlewareFn[] = []
|
|
48
|
-
): void {
|
|
49
|
-
if (loaderRegistry.has(id)) {
|
|
50
|
-
// Already registered (can happen during HMR)
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
loaderRegistry.set(id, { fn, middleware });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get a registered loader by $$id (synchronous)
|
|
58
|
-
* Returns undefined if loader is not registered
|
|
59
|
-
*/
|
|
60
|
-
export function getLoader(id: string): RegisteredLoader | undefined {
|
|
61
|
-
return loaderRegistry.get(id);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
37
|
/**
|
|
65
38
|
* Get a loader by $$id, loading it lazily if needed
|
|
66
39
|
* This is the primary method for the RSC handler to get loaders
|
|
@@ -69,8 +42,8 @@ export function getLoader(id: string): RegisteredLoader | undefined {
|
|
|
69
42
|
* In dev: IDs are "filePath#exportName", resolved via dynamic import
|
|
70
43
|
*/
|
|
71
44
|
export async function getLoaderLazy(
|
|
72
|
-
id: string
|
|
73
|
-
): Promise<
|
|
45
|
+
id: string,
|
|
46
|
+
): Promise<LoaderRegistryEntry | undefined> {
|
|
74
47
|
// Check if already cached in main registry
|
|
75
48
|
const existing = loaderRegistry.get(id);
|
|
76
49
|
if (existing) {
|
|
@@ -130,20 +103,6 @@ export async function getLoaderLazy(
|
|
|
130
103
|
return undefined;
|
|
131
104
|
}
|
|
132
105
|
|
|
133
|
-
/**
|
|
134
|
-
* Check if a loader is registered by $$id
|
|
135
|
-
*/
|
|
136
|
-
export function hasLoader(id: string): boolean {
|
|
137
|
-
return loaderRegistry.has(id) || getFetchableLoader(id) !== undefined;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Get all registered loader IDs (for debugging)
|
|
142
|
-
*/
|
|
143
|
-
export function getRegisteredLoaderIds(): string[] {
|
|
144
|
-
return Array.from(loaderRegistry.keys());
|
|
145
|
-
}
|
|
146
|
-
|
|
147
106
|
/**
|
|
148
107
|
* Register a loader by its $$id (injected by Vite plugin)
|
|
149
108
|
* This is called during module loading to cache loaders
|
|
@@ -155,12 +114,8 @@ export function registerLoaderById(loader: {
|
|
|
155
114
|
if (!loader.$$id) {
|
|
156
115
|
return;
|
|
157
116
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// For fetchable loaders, fn is stored in the fetchable registry by $$id
|
|
117
|
+
// For fetchable loaders, fn is stored in the fetchable registry by $$id.
|
|
118
|
+
// Always re-check the fetchable registry so HMR picks up the new function.
|
|
164
119
|
const fetchable = getFetchableLoader(loader.$$id);
|
|
165
120
|
if (fetchable) {
|
|
166
121
|
loaderRegistry.set(loader.$$id, fetchable);
|
|
@@ -169,6 +124,10 @@ export function registerLoaderById(loader: {
|
|
|
169
124
|
|
|
170
125
|
// Fall back to using fn from the loader object (non-fetchable loaders)
|
|
171
126
|
if (loader.fn) {
|
|
172
|
-
loaderRegistry.set(loader.$$id, {
|
|
127
|
+
loaderRegistry.set(loader.$$id, {
|
|
128
|
+
fn: loader.fn,
|
|
129
|
+
middleware: [],
|
|
130
|
+
fetchable: false,
|
|
131
|
+
});
|
|
173
132
|
}
|
|
174
133
|
}
|