@ivogt/rsc-router 0.0.0-experimental.1
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/README.md +19 -0
- package/package.json +131 -0
- package/src/__mocks__/version.ts +6 -0
- package/src/__tests__/route-definition.test.ts +63 -0
- package/src/browser/event-controller.ts +876 -0
- package/src/browser/index.ts +18 -0
- package/src/browser/link-interceptor.ts +121 -0
- package/src/browser/lru-cache.ts +69 -0
- package/src/browser/merge-segment-loaders.ts +126 -0
- package/src/browser/navigation-bridge.ts +891 -0
- package/src/browser/navigation-client.ts +155 -0
- package/src/browser/navigation-store.ts +823 -0
- package/src/browser/partial-update.ts +545 -0
- package/src/browser/react/Link.tsx +248 -0
- package/src/browser/react/NavigationProvider.tsx +228 -0
- package/src/browser/react/ScrollRestoration.tsx +94 -0
- package/src/browser/react/context.ts +53 -0
- package/src/browser/react/index.ts +52 -0
- package/src/browser/react/location-state-shared.ts +120 -0
- package/src/browser/react/location-state.ts +62 -0
- package/src/browser/react/use-action.ts +240 -0
- package/src/browser/react/use-client-cache.ts +56 -0
- package/src/browser/react/use-handle.ts +178 -0
- package/src/browser/react/use-link-status.ts +134 -0
- package/src/browser/react/use-navigation.ts +150 -0
- package/src/browser/react/use-segments.ts +188 -0
- package/src/browser/request-controller.ts +149 -0
- package/src/browser/rsc-router.tsx +310 -0
- package/src/browser/scroll-restoration.ts +324 -0
- package/src/browser/server-action-bridge.ts +747 -0
- package/src/browser/shallow.ts +35 -0
- package/src/browser/types.ts +443 -0
- package/src/cache/__tests__/memory-segment-store.test.ts +487 -0
- package/src/cache/__tests__/memory-store.test.ts +484 -0
- package/src/cache/cache-scope.ts +565 -0
- package/src/cache/cf/__tests__/cf-cache-store.test.ts +361 -0
- package/src/cache/cf/cf-cache-store.ts +274 -0
- package/src/cache/cf/index.ts +19 -0
- package/src/cache/index.ts +52 -0
- package/src/cache/memory-segment-store.ts +150 -0
- package/src/cache/memory-store.ts +253 -0
- package/src/cache/types.ts +366 -0
- package/src/client.rsc.tsx +88 -0
- package/src/client.tsx +609 -0
- package/src/components/DefaultDocument.tsx +20 -0
- package/src/default-error-boundary.tsx +88 -0
- package/src/deps/browser.ts +8 -0
- package/src/deps/html-stream-client.ts +2 -0
- package/src/deps/html-stream-server.ts +2 -0
- package/src/deps/rsc.ts +10 -0
- package/src/deps/ssr.ts +2 -0
- package/src/errors.ts +259 -0
- package/src/handle.ts +120 -0
- package/src/handles/MetaTags.tsx +178 -0
- package/src/handles/index.ts +6 -0
- package/src/handles/meta.ts +247 -0
- package/src/href-client.ts +128 -0
- package/src/href.ts +139 -0
- package/src/index.rsc.ts +69 -0
- package/src/index.ts +84 -0
- package/src/loader.rsc.ts +204 -0
- package/src/loader.ts +47 -0
- package/src/network-error-thrower.tsx +21 -0
- package/src/outlet-context.ts +15 -0
- package/src/root-error-boundary.tsx +277 -0
- package/src/route-content-wrapper.tsx +198 -0
- package/src/route-definition.ts +1333 -0
- package/src/route-map-builder.ts +140 -0
- package/src/route-types.ts +148 -0
- package/src/route-utils.ts +89 -0
- package/src/router/__tests__/match-context.test.ts +104 -0
- package/src/router/__tests__/match-pipelines.test.ts +537 -0
- package/src/router/__tests__/match-result.test.ts +566 -0
- package/src/router/__tests__/on-error.test.ts +935 -0
- package/src/router/__tests__/pattern-matching.test.ts +577 -0
- package/src/router/error-handling.ts +287 -0
- package/src/router/handler-context.ts +60 -0
- package/src/router/loader-resolution.ts +326 -0
- package/src/router/manifest.ts +116 -0
- package/src/router/match-context.ts +261 -0
- package/src/router/match-middleware/background-revalidation.ts +236 -0
- package/src/router/match-middleware/cache-lookup.ts +261 -0
- package/src/router/match-middleware/cache-store.ts +250 -0
- package/src/router/match-middleware/index.ts +81 -0
- package/src/router/match-middleware/intercept-resolution.ts +268 -0
- package/src/router/match-middleware/segment-resolution.ts +174 -0
- package/src/router/match-pipelines.ts +214 -0
- package/src/router/match-result.ts +212 -0
- package/src/router/metrics.ts +62 -0
- package/src/router/middleware.test.ts +1355 -0
- package/src/router/middleware.ts +748 -0
- package/src/router/pattern-matching.ts +271 -0
- package/src/router/revalidation.ts +190 -0
- package/src/router/router-context.ts +299 -0
- package/src/router/types.ts +96 -0
- package/src/router.ts +3484 -0
- package/src/rsc/__tests__/helpers.test.ts +175 -0
- package/src/rsc/handler.ts +942 -0
- package/src/rsc/helpers.ts +64 -0
- package/src/rsc/index.ts +56 -0
- package/src/rsc/nonce.ts +18 -0
- package/src/rsc/types.ts +225 -0
- package/src/segment-system.tsx +405 -0
- package/src/server/__tests__/request-context.test.ts +171 -0
- package/src/server/context.ts +340 -0
- package/src/server/handle-store.ts +230 -0
- package/src/server/loader-registry.ts +174 -0
- package/src/server/request-context.ts +470 -0
- package/src/server/root-layout.tsx +10 -0
- package/src/server/tsconfig.json +14 -0
- package/src/server.ts +126 -0
- package/src/ssr/__tests__/ssr-handler.test.tsx +188 -0
- package/src/ssr/index.tsx +215 -0
- package/src/types.ts +1473 -0
- package/src/use-loader.tsx +346 -0
- package/src/vite/__tests__/expose-loader-id.test.ts +117 -0
- package/src/vite/expose-action-id.ts +344 -0
- package/src/vite/expose-handle-id.ts +209 -0
- package/src/vite/expose-loader-id.ts +357 -0
- package/src/vite/expose-location-state-id.ts +177 -0
- package/src/vite/index.ts +608 -0
- package/src/vite/version.d.ts +12 -0
- package/src/vite/virtual-entries.ts +109 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for RSC helpers, specifically createResponseWithMergedHeaders
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
createRequestContext,
|
|
7
|
+
runWithRequestContext,
|
|
8
|
+
} from "../../server/request-context.js";
|
|
9
|
+
import { createResponseWithMergedHeaders } from "../helpers.js";
|
|
10
|
+
|
|
11
|
+
describe("createResponseWithMergedHeaders", () => {
|
|
12
|
+
it("should create response without context", () => {
|
|
13
|
+
const response = createResponseWithMergedHeaders("body", { status: 200 });
|
|
14
|
+
expect(response.status).toBe(200);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should merge headers from stub response", () => {
|
|
18
|
+
const ctx = createRequestContext({
|
|
19
|
+
env: {},
|
|
20
|
+
request: new Request("https://example.com"),
|
|
21
|
+
url: new URL("https://example.com"),
|
|
22
|
+
variables: {},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Set header on stub response
|
|
26
|
+
ctx.res.headers.set("X-Custom", "value");
|
|
27
|
+
|
|
28
|
+
const response = runWithRequestContext(ctx, () => {
|
|
29
|
+
return createResponseWithMergedHeaders("body", { status: 200 });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
expect(response.headers.get("X-Custom")).toBe("value");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should trigger onResponse callbacks", () => {
|
|
36
|
+
const ctx = createRequestContext({
|
|
37
|
+
env: {},
|
|
38
|
+
request: new Request("https://example.com"),
|
|
39
|
+
url: new URL("https://example.com"),
|
|
40
|
+
variables: {},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
let callbackCalled = false;
|
|
44
|
+
let capturedStatus: number | undefined;
|
|
45
|
+
|
|
46
|
+
ctx.onResponse((res) => {
|
|
47
|
+
callbackCalled = true;
|
|
48
|
+
capturedStatus = res.status;
|
|
49
|
+
return res;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
runWithRequestContext(ctx, () => {
|
|
53
|
+
createResponseWithMergedHeaders("body", { status: 201 });
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(callbackCalled).toBe(true);
|
|
57
|
+
expect(capturedStatus).toBe(201);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should allow callbacks to modify response", () => {
|
|
61
|
+
const ctx = createRequestContext({
|
|
62
|
+
env: {},
|
|
63
|
+
request: new Request("https://example.com"),
|
|
64
|
+
url: new URL("https://example.com"),
|
|
65
|
+
variables: {},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
ctx.onResponse((res) => {
|
|
69
|
+
const headers = new Headers(res.headers);
|
|
70
|
+
headers.set("X-Added-By-Callback", "yes");
|
|
71
|
+
return new Response(res.body, { status: res.status, headers });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const response = runWithRequestContext(ctx, () => {
|
|
75
|
+
return createResponseWithMergedHeaders("body", { status: 200 });
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(response.headers.get("X-Added-By-Callback")).toBe("yes");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("should keep original response if callback returns undefined", () => {
|
|
82
|
+
const ctx = createRequestContext({
|
|
83
|
+
env: {},
|
|
84
|
+
request: new Request("https://example.com"),
|
|
85
|
+
url: new URL("https://example.com"),
|
|
86
|
+
variables: {},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
ctx.onResponse((_res) => {
|
|
90
|
+
// Oops, forgot to return response
|
|
91
|
+
return undefined as any;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const response = runWithRequestContext(ctx, () => {
|
|
95
|
+
return createResponseWithMergedHeaders("body", { status: 200 });
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
expect(response.status).toBe(200);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should chain multiple callback modifications", () => {
|
|
102
|
+
const ctx = createRequestContext({
|
|
103
|
+
env: {},
|
|
104
|
+
request: new Request("https://example.com"),
|
|
105
|
+
url: new URL("https://example.com"),
|
|
106
|
+
variables: {},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
ctx.onResponse((res) => {
|
|
110
|
+
const headers = new Headers(res.headers);
|
|
111
|
+
headers.set("X-First", "1");
|
|
112
|
+
return new Response(res.body, { status: res.status, headers });
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
ctx.onResponse((res) => {
|
|
116
|
+
const headers = new Headers(res.headers);
|
|
117
|
+
headers.set("X-Second", "2");
|
|
118
|
+
return new Response(res.body, { status: res.status, headers });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const response = runWithRequestContext(ctx, () => {
|
|
122
|
+
return createResponseWithMergedHeaders("body", { status: 200 });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(response.headers.get("X-First")).toBe("1");
|
|
126
|
+
expect(response.headers.get("X-Second")).toBe("2");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("should pass correct status to callbacks for error responses", () => {
|
|
130
|
+
const ctx = createRequestContext({
|
|
131
|
+
env: {},
|
|
132
|
+
request: new Request("https://example.com"),
|
|
133
|
+
url: new URL("https://example.com"),
|
|
134
|
+
variables: {},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const capturedStatuses: number[] = [];
|
|
138
|
+
|
|
139
|
+
ctx.onResponse((res) => {
|
|
140
|
+
capturedStatuses.push(res.status);
|
|
141
|
+
return res;
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
runWithRequestContext(ctx, () => {
|
|
145
|
+
createResponseWithMergedHeaders("Not Found", { status: 404 });
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
expect(capturedStatuses).toEqual([404]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("should pass correct status to callbacks for redirects", () => {
|
|
152
|
+
const ctx = createRequestContext({
|
|
153
|
+
env: {},
|
|
154
|
+
request: new Request("https://example.com"),
|
|
155
|
+
url: new URL("https://example.com"),
|
|
156
|
+
variables: {},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
let capturedStatus: number | undefined;
|
|
160
|
+
|
|
161
|
+
ctx.onResponse((res) => {
|
|
162
|
+
capturedStatus = res.status;
|
|
163
|
+
return res;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
runWithRequestContext(ctx, () => {
|
|
167
|
+
createResponseWithMergedHeaders(null, {
|
|
168
|
+
status: 308,
|
|
169
|
+
headers: { Location: "/new-url" },
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(capturedStatus).toBe(308);
|
|
174
|
+
});
|
|
175
|
+
});
|