rwsdk 1.0.0-alpha.9 → 1.0.0-beta.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/dist/lib/constants.mjs +1 -2
- package/dist/lib/e2e/browser.d.mts +1 -1
- package/dist/lib/e2e/browser.mjs +3 -4
- package/dist/lib/e2e/dev.mjs +62 -52
- package/dist/lib/e2e/environment.d.mts +2 -6
- package/dist/lib/e2e/environment.mjs +72 -72
- package/dist/lib/e2e/index.d.mts +5 -4
- package/dist/lib/e2e/index.mjs +5 -4
- package/dist/lib/e2e/poll.d.mts +8 -0
- package/dist/lib/e2e/poll.mjs +31 -0
- package/dist/lib/e2e/release.mjs +4 -4
- package/dist/lib/e2e/retry.d.mts +4 -0
- package/dist/lib/e2e/retry.mjs +16 -0
- package/dist/lib/e2e/setup.d.mts +2 -0
- package/dist/lib/e2e/setup.mjs +1 -0
- package/dist/lib/e2e/tarball.d.mts +3 -2
- package/dist/lib/e2e/tarball.mjs +30 -5
- package/dist/lib/e2e/testHarness.d.mts +59 -50
- package/dist/lib/e2e/testHarness.mjs +289 -343
- package/dist/lib/getShortName.mjs +1 -2
- package/dist/lib/getShortName.test.mjs +2 -2
- package/dist/lib/getSrcPaths.js +2 -2
- package/dist/lib/hasPkgScript.test.mjs +2 -2
- package/dist/lib/jsonUtils.test.mjs +2 -2
- package/dist/lib/normalizeModulePath.test.mjs +2 -2
- package/dist/lib/setupEnvFiles.mjs +2 -2
- package/dist/lib/smokeTests/artifacts.mjs +2 -2
- package/dist/lib/smokeTests/browser.d.mts +1 -1
- package/dist/lib/smokeTests/browser.mjs +6 -7
- package/dist/lib/smokeTests/cleanup.mjs +6 -9
- package/dist/lib/smokeTests/codeUpdates.mjs +5 -5
- package/dist/lib/smokeTests/development.mjs +2 -2
- package/dist/lib/smokeTests/environment.d.mts +2 -3
- package/dist/lib/smokeTests/environment.mjs +17 -3
- package/dist/lib/smokeTests/release.d.mts +2 -2
- package/dist/lib/smokeTests/release.mjs +3 -3
- package/dist/lib/smokeTests/reporting.mjs +2 -2
- package/dist/lib/smokeTests/runSmokeTests.mjs +4 -4
- package/dist/lib/smokeTests/utils.mjs +3 -3
- package/dist/lib/testUtils/stubEnvVars.mjs +1 -1
- package/dist/llms/rules/middleware.d.ts +1 -1
- package/dist/llms/rules/middleware.js +4 -4
- package/dist/runtime/client/client.d.ts +2 -2
- package/dist/runtime/client/client.js +2 -2
- package/dist/runtime/client/navigation.test.js +1 -1
- package/dist/runtime/client/types.d.ts +1 -1
- package/dist/runtime/entries/client.d.ts +2 -2
- package/dist/runtime/entries/client.js +2 -2
- package/dist/runtime/entries/router.d.ts +1 -1
- package/dist/runtime/entries/router.js +1 -1
- package/dist/runtime/entries/worker.d.ts +5 -6
- package/dist/runtime/entries/worker.js +5 -6
- package/dist/runtime/imports/worker.js +1 -1
- package/dist/runtime/lib/auth/session.d.ts +2 -2
- package/dist/runtime/lib/auth/session.js +5 -5
- package/dist/runtime/lib/db/DOWorkerDialect.d.ts +1 -1
- package/dist/runtime/lib/db/DOWorkerDialect.js +1 -1
- package/dist/runtime/lib/db/SqliteDurableObject.js +2 -2
- package/dist/runtime/lib/db/index.d.ts +2 -2
- package/dist/runtime/lib/db/index.js +2 -2
- package/dist/runtime/lib/db/migrations.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/alterTable.d.ts +3 -3
- package/dist/runtime/lib/db/typeInference/builders/columnDefinition.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/createTable.d.ts +2 -2
- package/dist/runtime/lib/db/typeInference/builders/createView.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/dropTable.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/dropView.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/schema.d.ts +3 -3
- package/dist/runtime/lib/db/typeInference/database.d.ts +2 -2
- package/dist/runtime/lib/memoizeOnId.test.js +1 -1
- package/dist/runtime/lib/realtime/client.js +2 -2
- package/dist/runtime/lib/realtime/durableObject.js +1 -1
- package/dist/runtime/lib/realtime/protocol.test.js +1 -1
- package/dist/runtime/lib/realtime/shared.test.js +1 -1
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.js +1 -1
- package/dist/runtime/lib/realtime/worker.js +2 -2
- package/dist/runtime/lib/router.d.ts +1 -1
- package/dist/runtime/lib/router.test.js +2 -3
- package/dist/runtime/lib/rwContext.d.ts +1 -1
- package/dist/runtime/lib/stitchDocumentAndAppStreams.d.ts +18 -0
- package/dist/runtime/lib/stitchDocumentAndAppStreams.js +143 -0
- package/dist/runtime/lib/turnstile/useTurnstile.js +1 -1
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.js +1 -1
- package/dist/runtime/register/worker.d.ts +1 -1
- package/dist/runtime/register/worker.js +34 -22
- package/dist/runtime/render/assembleDocument.d.ts +1 -1
- package/dist/runtime/render/createThenableFromReadableStream.js +1 -1
- package/dist/runtime/render/preloads.d.ts +2 -2
- package/dist/runtime/render/renderDocumentHtmlStream.js +6 -6
- package/dist/runtime/render/renderHtmlStream.d.ts +1 -1
- package/dist/runtime/render/renderToRscStream.d.ts +4 -1
- package/dist/runtime/render/renderToRscStream.js +11 -1
- package/dist/runtime/render/renderToStream.d.ts +1 -1
- package/dist/runtime/render/renderToStream.js +2 -2
- package/dist/runtime/render/stylesheets.d.ts +1 -1
- package/dist/runtime/requestInfo/types.d.ts +0 -2
- package/dist/runtime/requestInfo/worker.d.ts +1 -1
- package/dist/runtime/requestInfo/worker.js +1 -9
- package/dist/runtime/script.js +1 -1
- package/dist/runtime/ssrBridge.d.ts +2 -2
- package/dist/runtime/ssrBridge.js +2 -2
- package/dist/runtime/worker.d.ts +1 -1
- package/dist/runtime/worker.js +3 -11
- package/dist/scripts/addon.d.mts +1 -0
- package/dist/scripts/addon.mjs +73 -0
- package/dist/scripts/debug-sync.mjs +106 -137
- package/dist/scripts/ensure-deploy-env.mjs +6 -6
- package/dist/scripts/migrate-new.mjs +3 -4
- package/dist/scripts/smoke-test.mjs +2 -9
- package/dist/scripts/worker-run.mjs +7 -9
- package/dist/vite/buildApp.mjs +1 -1
- package/dist/vite/checkIsUsingPrisma.test.mjs +1 -1
- package/dist/vite/configPlugin.mjs +33 -6
- package/dist/vite/createDirectiveLookupPlugin.mjs +1 -1
- package/dist/vite/createDirectiveLookupPlugin.test.mjs +2 -2
- package/dist/vite/createViteAwareResolver.d.mts +1 -2
- package/dist/vite/createViteAwareResolver.mjs +1 -1
- package/dist/vite/directiveModulesDevPlugin.mjs +4 -4
- package/dist/vite/directiveModulesDevPlugin.test.mjs +2 -2
- package/dist/vite/directivesPlugin.mjs +3 -3
- package/dist/vite/directivesPlugin.test.mjs +1 -1
- package/dist/vite/ensureAliasArray.test.mjs +1 -1
- package/dist/vite/findSpecifiers.mjs +1 -1
- package/dist/vite/findSpecifiers.test.mjs +2 -2
- package/dist/vite/findSsrSpecifiers.mjs +1 -1
- package/dist/vite/findSsrSpecifiers.test.mjs +1 -1
- package/dist/vite/getViteEsbuild.mjs +1 -1
- package/dist/vite/hasDirective.test.mjs +1 -1
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/invalidateCacheIfPrismaClientChanged.mjs +2 -2
- package/dist/vite/isJsFile.test.mjs +1 -1
- package/dist/vite/{reactConditionsResolverPlugin.d.mts → knownDepsResolverPlugin.d.mts} +3 -3
- package/dist/vite/{reactConditionsResolverPlugin.mjs → knownDepsResolverPlugin.mjs} +29 -24
- package/dist/vite/linkerPlugin.mjs +2 -2
- package/dist/vite/linkerPlugin.test.mjs +1 -1
- package/dist/vite/miniflareHMRPlugin.mjs +5 -5
- package/dist/vite/miniflareHMRPlugin.test.mjs +1 -1
- package/dist/vite/prismaPlugin.mjs +1 -1
- package/dist/vite/redwoodPlugin.d.mts +2 -0
- package/dist/vite/redwoodPlugin.mjs +36 -17
- package/dist/vite/redwoodPlugin.test.mjs +2 -2
- package/dist/vite/resolveForcedPaths.d.mts +4 -0
- package/dist/vite/resolveForcedPaths.mjs +9 -0
- package/dist/vite/runDirectivesScan.d.mts +2 -1
- package/dist/vite/runDirectivesScan.mjs +53 -17
- package/dist/vite/runDirectivesScan.test.mjs +2 -2
- package/dist/vite/ssrBridgePlugin.mjs +10 -3
- package/dist/vite/transformClientComponents.mjs +8 -6
- package/dist/vite/transformClientComponents.test.mjs +117 -59
- package/dist/vite/transformJsxScriptTagsPlugin.mjs +1 -1
- package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +2 -2
- package/dist/vite/transformServerFunctions.d.mts +1 -1
- package/dist/vite/transformServerFunctions.mjs +5 -5
- package/dist/vite/transformServerFunctions.test.mjs +3 -3
- package/package.json +54 -44
- package/dist/runtime/imports/resolveSSRValue.d.ts +0 -1
- package/dist/runtime/imports/resolveSSRValue.js +0 -8
- package/dist/runtime/lib/injectHtmlAtMarker.d.ts +0 -11
- package/dist/runtime/lib/injectHtmlAtMarker.js +0 -90
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Kysely } from "kysely";
|
|
2
|
-
import { ExecutedBuilder, Prettify, ProcessAlteredTable, UnionToTuple } from "./utils";
|
|
3
|
-
import { CreateTableBuilder } from "./builders/createTable";
|
|
4
2
|
import { AlterTableBuilder } from "./builders/alterTable";
|
|
3
|
+
import { CreateTableBuilder } from "./builders/createTable";
|
|
5
4
|
import { DropTableBuilder } from "./builders/dropTable";
|
|
6
5
|
import { SchemaBuilder } from "./builders/schema";
|
|
6
|
+
import { ExecutedBuilder, Prettify, ProcessAlteredTable, UnionToTuple } from "./utils";
|
|
7
7
|
export interface InferenceBuilder {
|
|
8
8
|
schema: SchemaBuilder;
|
|
9
9
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { initClient } from "../../client/client";
|
|
2
1
|
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
|
3
|
-
import {
|
|
2
|
+
import { initClient } from "../../client/client";
|
|
4
3
|
import { packMessage, unpackMessage, } from "./protocol";
|
|
4
|
+
import { MESSAGE_TYPE } from "./shared";
|
|
5
5
|
const DEFAULT_KEY = "default";
|
|
6
6
|
export const initRealtimeClient = ({ key = DEFAULT_KEY, handleResponse, } = {}) => {
|
|
7
7
|
const transport = realtimeTransport({ key, handleResponse });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DurableObject } from "cloudflare:workers";
|
|
2
|
+
import { packMessage, unpackMessage, } from "./protocol";
|
|
2
3
|
import { MESSAGE_TYPE } from "./shared";
|
|
3
4
|
import { validateUpgradeRequest } from "./validateUpgradeRequest";
|
|
4
|
-
import { packMessage, unpackMessage, } from "./protocol";
|
|
5
5
|
export class RealtimeDurableObject extends DurableObject {
|
|
6
6
|
constructor(state, env) {
|
|
7
7
|
super(state, env);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe,
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { validateUpgradeRequest } from "./validateUpgradeRequest";
|
|
3
3
|
describe("validateUpgradeRequest", () => {
|
|
4
4
|
it("should return valid for a correct WebSocket upgrade request", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { env } from "cloudflare:workers";
|
|
1
2
|
import { route } from "../../entries/router";
|
|
2
|
-
import { validateUpgradeRequest } from "./validateUpgradeRequest";
|
|
3
3
|
import { DEFAULT_REALTIME_KEY } from "./constants";
|
|
4
|
-
import {
|
|
4
|
+
import { validateUpgradeRequest } from "./validateUpgradeRequest";
|
|
5
5
|
export { renderRealtimeClients } from "./renderRealtimeClients";
|
|
6
6
|
export const realtimeRoute = (getDurableObjectNamespace) => route("/__realtime", async function ({ request }) {
|
|
7
7
|
const validation = validateUpgradeRequest(request);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
1
|
import React from "react";
|
|
3
|
-
import {
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { defineRoutes, layout, matchPath, prefix, render, route, } from "./router";
|
|
4
4
|
describe("matchPath", () => {
|
|
5
5
|
// Test case 1: Static paths
|
|
6
6
|
it("should match static paths", () => {
|
|
@@ -64,7 +64,6 @@ describe("defineRoutes - Request Handling Behavior", () => {
|
|
|
64
64
|
request: new Request("http://localhost:3000/"),
|
|
65
65
|
params: {},
|
|
66
66
|
ctx: {},
|
|
67
|
-
headers: new Headers(),
|
|
68
67
|
rw: {
|
|
69
68
|
nonce: "test-nonce",
|
|
70
69
|
Document: () => React.createElement("html"),
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A utility to orchestrate and interleave two ReadableStreams (a document shell and an app shell)
|
|
3
|
+
* based on a set of markers within their content. This is designed to solve a specific
|
|
4
|
+
* race condition in streaming Server-Side Rendering (SSR) with Suspense.
|
|
5
|
+
*
|
|
6
|
+
* The logic is as follows:
|
|
7
|
+
* 1. Stream the document until a start marker is found.
|
|
8
|
+
* 2. Switch to the app stream and stream it until an end marker is found. This is the non-suspended shell.
|
|
9
|
+
* 3. Switch back to the document stream and stream it until the closing body tag. This sends the client script.
|
|
10
|
+
* 4. Switch back to the app stream and stream the remainder (the suspended content).
|
|
11
|
+
* 5. Switch back to the document stream and stream the remainder (closing body and html tags).
|
|
12
|
+
*
|
|
13
|
+
* @param outerHtml The stream for the document shell (`<Document>`).
|
|
14
|
+
* @param innerHtml The stream for the application's content.
|
|
15
|
+
* @param startMarker The marker in the document to start injecting the app.
|
|
16
|
+
* @param endMarker The marker in the app stream that signals the end of the initial, non-suspended render.
|
|
17
|
+
*/
|
|
18
|
+
export declare function stitchDocumentAndAppStreams(outerHtml: ReadableStream<Uint8Array>, innerHtml: ReadableStream<Uint8Array>, startMarker: string, endMarker: string): ReadableStream<Uint8Array>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A utility to orchestrate and interleave two ReadableStreams (a document shell and an app shell)
|
|
3
|
+
* based on a set of markers within their content. This is designed to solve a specific
|
|
4
|
+
* race condition in streaming Server-Side Rendering (SSR) with Suspense.
|
|
5
|
+
*
|
|
6
|
+
* The logic is as follows:
|
|
7
|
+
* 1. Stream the document until a start marker is found.
|
|
8
|
+
* 2. Switch to the app stream and stream it until an end marker is found. This is the non-suspended shell.
|
|
9
|
+
* 3. Switch back to the document stream and stream it until the closing body tag. This sends the client script.
|
|
10
|
+
* 4. Switch back to the app stream and stream the remainder (the suspended content).
|
|
11
|
+
* 5. Switch back to the document stream and stream the remainder (closing body and html tags).
|
|
12
|
+
*
|
|
13
|
+
* @param outerHtml The stream for the document shell (`<Document>`).
|
|
14
|
+
* @param innerHtml The stream for the application's content.
|
|
15
|
+
* @param startMarker The marker in the document to start injecting the app.
|
|
16
|
+
* @param endMarker The marker in the app stream that signals the end of the initial, non-suspended render.
|
|
17
|
+
*/
|
|
18
|
+
export function stitchDocumentAndAppStreams(outerHtml, innerHtml, startMarker, endMarker) {
|
|
19
|
+
const decoder = new TextDecoder();
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
let outerReader;
|
|
22
|
+
let innerReader;
|
|
23
|
+
let buffer = "";
|
|
24
|
+
let outerBufferRemains = "";
|
|
25
|
+
let phase = "outer-head";
|
|
26
|
+
const pump = async (controller) => {
|
|
27
|
+
try {
|
|
28
|
+
if (phase === "outer-head") {
|
|
29
|
+
const { done, value } = await outerReader.read();
|
|
30
|
+
if (done) {
|
|
31
|
+
if (buffer)
|
|
32
|
+
controller.enqueue(encoder.encode(buffer));
|
|
33
|
+
controller.close();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
buffer += decoder.decode(value, { stream: true });
|
|
37
|
+
const markerIndex = buffer.indexOf(startMarker);
|
|
38
|
+
if (markerIndex !== -1) {
|
|
39
|
+
controller.enqueue(encoder.encode(buffer.slice(0, markerIndex)));
|
|
40
|
+
outerBufferRemains = buffer.slice(markerIndex + startMarker.length);
|
|
41
|
+
buffer = "";
|
|
42
|
+
phase = "inner-shell";
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const flushIndex = buffer.lastIndexOf("\n");
|
|
46
|
+
if (flushIndex !== -1) {
|
|
47
|
+
controller.enqueue(encoder.encode(buffer.slice(0, flushIndex + 1)));
|
|
48
|
+
buffer = buffer.slice(flushIndex + 1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (phase === "inner-shell") {
|
|
53
|
+
const { done, value } = await innerReader.read();
|
|
54
|
+
if (done) {
|
|
55
|
+
if (buffer)
|
|
56
|
+
controller.enqueue(encoder.encode(buffer));
|
|
57
|
+
phase = "outer-tail";
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
buffer += decoder.decode(value, { stream: true });
|
|
61
|
+
const markerIndex = buffer.indexOf(endMarker);
|
|
62
|
+
if (markerIndex !== -1) {
|
|
63
|
+
const endOfMarkerIndex = markerIndex + endMarker.length;
|
|
64
|
+
controller.enqueue(encoder.encode(buffer.slice(0, endOfMarkerIndex)));
|
|
65
|
+
buffer = buffer.slice(endOfMarkerIndex);
|
|
66
|
+
phase = "outer-tail";
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const flushIndex = buffer.lastIndexOf("\n");
|
|
70
|
+
if (flushIndex !== -1) {
|
|
71
|
+
controller.enqueue(encoder.encode(buffer.slice(0, flushIndex + 1)));
|
|
72
|
+
buffer = buffer.slice(flushIndex + 1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (phase === "outer-tail") {
|
|
78
|
+
if (outerBufferRemains) {
|
|
79
|
+
buffer = outerBufferRemains;
|
|
80
|
+
outerBufferRemains = "";
|
|
81
|
+
}
|
|
82
|
+
const { done, value } = await outerReader.read();
|
|
83
|
+
if (done) {
|
|
84
|
+
if (buffer)
|
|
85
|
+
controller.enqueue(encoder.encode(buffer));
|
|
86
|
+
phase = "inner-suspended";
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
buffer += decoder.decode(value, { stream: true });
|
|
90
|
+
const markerIndex = buffer.indexOf("</body>");
|
|
91
|
+
if (markerIndex !== -1) {
|
|
92
|
+
controller.enqueue(encoder.encode(buffer.slice(0, markerIndex)));
|
|
93
|
+
buffer = buffer.slice(markerIndex);
|
|
94
|
+
phase = "inner-suspended";
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const flushIndex = buffer.lastIndexOf("\n");
|
|
98
|
+
if (flushIndex !== -1) {
|
|
99
|
+
controller.enqueue(encoder.encode(buffer.slice(0, flushIndex + 1)));
|
|
100
|
+
buffer = buffer.slice(flushIndex + 1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (phase === "inner-suspended") {
|
|
106
|
+
const { done, value } = await innerReader.read();
|
|
107
|
+
if (done) {
|
|
108
|
+
phase = "outer-end";
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
controller.enqueue(value);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (phase === "outer-end") {
|
|
115
|
+
if (buffer) {
|
|
116
|
+
controller.enqueue(encoder.encode(buffer));
|
|
117
|
+
buffer = "";
|
|
118
|
+
}
|
|
119
|
+
const { done, value } = await outerReader.read();
|
|
120
|
+
if (done) {
|
|
121
|
+
controller.close();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
controller.enqueue(value);
|
|
125
|
+
}
|
|
126
|
+
await pump(controller);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
controller.error(e);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
return new ReadableStream({
|
|
133
|
+
start(controller) {
|
|
134
|
+
outerReader = outerHtml.getReader();
|
|
135
|
+
innerReader = innerHtml.getReader();
|
|
136
|
+
pump(controller).catch((e) => controller.error(e));
|
|
137
|
+
},
|
|
138
|
+
cancel(reason) {
|
|
139
|
+
outerReader?.cancel(reason);
|
|
140
|
+
innerReader?.cancel(reason);
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe,
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { verifyTurnstileToken } from "./verifyTurnstileToken";
|
|
3
3
|
describe("verifyTurnstileToken", () => {
|
|
4
4
|
it("should return true for a successful verification", async () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare function registerServerReference(action: Function, id: string, name: string): Function;
|
|
2
|
-
export declare function registerClientReference<Target extends Record<string,
|
|
2
|
+
export declare function registerClientReference<Target extends Record<string, unknown>>(ssrModule: Target, id: string, exportName: string): {};
|
|
3
3
|
export declare function __smokeTestActionHandler(timestamp?: number): Promise<unknown>;
|
|
4
4
|
export declare function rscActionHandler(req: Request): Promise<unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isValidElementType } from "react-is";
|
|
2
|
+
import { registerClientReference as baseRegisterClientReference, registerServerReference as baseRegisterServerReference, decodeReply, } from "react-server-dom-webpack/server.edge";
|
|
2
3
|
import { getServerModuleExport } from "../imports/worker.js";
|
|
3
4
|
import { requestInfo } from "../requestInfo/worker.js";
|
|
4
5
|
export function registerServerReference(action, id, name) {
|
|
@@ -8,28 +9,39 @@ export function registerServerReference(action, id, name) {
|
|
|
8
9
|
// Note: We no longer need to register in a Map since we use virtual lookup
|
|
9
10
|
return baseRegisterServerReference(action, id, name);
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
12
|
+
const isComponent = (target) => isValidElementType(target) && target?.toString().includes("jsx");
|
|
13
|
+
export function registerClientReference(ssrModule, id, exportName) {
|
|
14
|
+
const target = ssrModule[exportName] ?? {};
|
|
15
|
+
if (isValidElementType(target)) {
|
|
16
|
+
// This is the original logic from 'main'.
|
|
17
|
+
// For React components, we create a serializable reference for the RSC pass.
|
|
18
|
+
const reference = baseRegisterClientReference({}, id, exportName);
|
|
19
|
+
const finalDescriptors = Object.getOwnPropertyDescriptors(reference);
|
|
20
|
+
const idDescriptor = finalDescriptors.$$id;
|
|
21
|
+
if (idDescriptor) {
|
|
22
|
+
const originalValue = idDescriptor.value;
|
|
23
|
+
// Create a new accessor descriptor, NOT by spreading the old one.
|
|
24
|
+
finalDescriptors.$$id = {
|
|
25
|
+
enumerable: idDescriptor.enumerable,
|
|
26
|
+
configurable: idDescriptor.configurable,
|
|
27
|
+
get() {
|
|
28
|
+
requestInfo.rw.scriptsToBeLoaded.add(id);
|
|
29
|
+
return originalValue;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
finalDescriptors.$$async = { value: true };
|
|
34
|
+
finalDescriptors.$$isClientReference = { value: true };
|
|
35
|
+
// context(justinvdm, 25 Sep 2025): We create a wrapper function to avoid
|
|
36
|
+
// getting the SSR component's property descriptors - otherwise
|
|
37
|
+
// this will take precedence over the client reference descriptors
|
|
38
|
+
const fn = typeof target === "function"
|
|
39
|
+
? (...args) => target(...args)
|
|
40
|
+
: () => null;
|
|
41
|
+
return Object.defineProperties(fn, finalDescriptors);
|
|
29
42
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return Object.defineProperties(wrappedValue, finalDescriptors);
|
|
43
|
+
// For non-components, return the target object directly for use in SSR.
|
|
44
|
+
return target;
|
|
33
45
|
}
|
|
34
46
|
export async function __smokeTestActionHandler(timestamp) {
|
|
35
47
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createModuleMap } from "./createModuleMap.js";
|
|
2
1
|
import ReactServerDom from "react-server-dom-webpack/client.edge";
|
|
2
|
+
import { createModuleMap } from "./createModuleMap.js";
|
|
3
3
|
const { createFromReadableStream } = ReactServerDom;
|
|
4
4
|
export const createThenableFromReadableStream = (stream) => createFromReadableStream(stream, {
|
|
5
5
|
serverConsumerManifest: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { RequestInfo } from "../requestInfo/types.js";
|
|
2
1
|
import type { Manifest, ManifestChunk } from "../lib/manifest.js";
|
|
2
|
+
import type { RequestInfo } from "../requestInfo/types.js";
|
|
3
3
|
export declare function findScriptForModule(id: string, manifest: Manifest): ManifestChunk | undefined;
|
|
4
4
|
export declare const Preloads: ({ requestInfo, }: {
|
|
5
5
|
requestInfo: RequestInfo;
|
|
6
|
-
}) => Promise<import("react/jsx-runtime
|
|
6
|
+
}) => Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Preloads } from "./preloads.js";
|
|
3
3
|
import { Stylesheets } from "./stylesheets.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { createThenableFromReadableStream, renderHtmlStream, } from "rwsdk/__ssr_bridge";
|
|
5
|
+
import { stitchDocumentAndAppStreams } from "../lib/stitchDocumentAndAppStreams.js";
|
|
6
6
|
export const renderDocumentHtmlStream = async ({ rscPayloadStream, Document, requestInfo, shouldSSR, onError, }) => {
|
|
7
7
|
// Extract the app node from the RSC payload
|
|
8
8
|
const rscAppThenable = createThenableFromReadableStream(rscPayloadStream);
|
|
9
|
-
const { node:
|
|
9
|
+
const { node: innerAppNode } = (await rscAppThenable);
|
|
10
10
|
// todo(justinvdm, 18 Jun 2025): We can build on this later to allow users
|
|
11
11
|
// surface context. e.g:
|
|
12
12
|
// * we assign `user: requestInfo.clientCtx` here
|
|
@@ -21,7 +21,7 @@ export const renderDocumentHtmlStream = async ({ rscPayloadStream, Document, req
|
|
|
21
21
|
// Create the outer document with a marker for injection
|
|
22
22
|
const documentElement = (_jsxs(Document, { ...requestInfo, children: [_jsx("script", { nonce: requestInfo.rw.nonce, dangerouslySetInnerHTML: {
|
|
23
23
|
__html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)}`,
|
|
24
|
-
} }), _jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root",
|
|
24
|
+
} }), _jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: _jsx("div", { id: "rwsdk-app-start" }) })] }));
|
|
25
25
|
const outerHtmlStream = await renderHtmlStream({
|
|
26
26
|
node: documentElement,
|
|
27
27
|
requestInfo,
|
|
@@ -29,11 +29,11 @@ export const renderDocumentHtmlStream = async ({ rscPayloadStream, Document, req
|
|
|
29
29
|
identifierPrefix: "__RWSDK_DOCUMENT__",
|
|
30
30
|
});
|
|
31
31
|
const appHtmlStream = await renderHtmlStream({
|
|
32
|
-
node:
|
|
32
|
+
node: innerAppNode,
|
|
33
33
|
requestInfo,
|
|
34
34
|
onError,
|
|
35
35
|
});
|
|
36
36
|
// Stitch the streams together
|
|
37
|
-
const stitchedStream =
|
|
37
|
+
const stitchedStream = stitchDocumentAndAppStreams(outerHtmlStream, appHtmlStream, '<div id="rwsdk-app-start"></div>', '<div id="rwsdk-app-end"></div>');
|
|
38
38
|
return stitchedStream;
|
|
39
39
|
};
|
|
@@ -4,4 +4,4 @@ export declare const renderHtmlStream: ({ node, identifierPrefix, requestInfo, o
|
|
|
4
4
|
requestInfo: RequestInfo;
|
|
5
5
|
onError: (error: unknown) => void;
|
|
6
6
|
identifierPrefix?: string;
|
|
7
|
-
}) => Promise<import("react-dom/server
|
|
7
|
+
}) => Promise<import("react-dom/server").ReactDOMServerReadableStream>;
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
import { renderToReadableStream as baseRenderToRscStream } from "react-server-dom-webpack/server.edge";
|
|
2
3
|
import { createClientManifest } from "./createClientManifest.js";
|
|
3
4
|
export const renderToRscStream = ({ input, onError, }) => {
|
|
4
|
-
|
|
5
|
+
const { node: inputNode, actionResult } = input;
|
|
6
|
+
// context(justinvdm, 2025-09-26): We add a marker here for our stitching logic in
|
|
7
|
+
// renderDocumentHtmlStream() to find and use. It needs to live here rather than there,
|
|
8
|
+
// since it needs to live in the RSC payload for hydration to work.
|
|
9
|
+
const wrappedNode = (_jsxs(_Fragment, { children: [inputNode, _jsx("div", { id: "rwsdk-app-end" })] }));
|
|
10
|
+
const wrappedInput = {
|
|
11
|
+
node: wrappedNode,
|
|
12
|
+
actionResult,
|
|
13
|
+
};
|
|
14
|
+
return baseRenderToRscStream(wrappedInput, createClientManifest(), {
|
|
5
15
|
onError,
|
|
6
16
|
});
|
|
7
17
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { renderToRscStream } from "./renderToRscStream";
|
|
3
|
-
import { requestInfo } from "../requestInfo/worker";
|
|
4
2
|
import { injectRSCPayload } from "rsc-html-stream/server";
|
|
3
|
+
import { requestInfo } from "../requestInfo/worker";
|
|
5
4
|
import { renderDocumentHtmlStream } from "./renderDocumentHtmlStream";
|
|
5
|
+
import { renderToRscStream } from "./renderToRscStream";
|
|
6
6
|
export const IdentityDocument = ({ children }) => (_jsx(_Fragment, { children: children }));
|
|
7
7
|
export const renderToStream = async (element, { ssr: shouldSSR = true, Document = IdentityDocument, injectRSCPayload: shouldInjectRSCPayload = true, onError = () => { }, } = {}) => {
|
|
8
8
|
let rscStream = renderToRscStream({
|
|
@@ -5,8 +5,6 @@ export interface RequestInfo<Params = any, AppContext = DefaultAppContext> {
|
|
|
5
5
|
request: Request;
|
|
6
6
|
params: Params;
|
|
7
7
|
ctx: AppContext;
|
|
8
|
-
/** @deprecated: Use `response.headers` instead */
|
|
9
|
-
headers: Headers;
|
|
10
8
|
rw: RwContext;
|
|
11
9
|
cf: ExecutionContext;
|
|
12
10
|
response: ResponseInit & {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DefaultAppContext, RequestInfo } from "./types";
|
|
2
2
|
type DefaultRequestInfo = RequestInfo<DefaultAppContext>;
|
|
3
3
|
export declare const requestInfo: DefaultRequestInfo;
|
|
4
4
|
export declare function getRequestInfo(): RequestInfo;
|
|
@@ -2,15 +2,7 @@ import { AsyncLocalStorage } from "async_hooks";
|
|
|
2
2
|
const requestInfoDeferred = Promise.withResolvers();
|
|
3
3
|
const requestInfoStore = new AsyncLocalStorage();
|
|
4
4
|
const requestInfoBase = {};
|
|
5
|
-
const REQUEST_INFO_KEYS = [
|
|
6
|
-
"request",
|
|
7
|
-
"params",
|
|
8
|
-
"ctx",
|
|
9
|
-
"headers",
|
|
10
|
-
"rw",
|
|
11
|
-
"cf",
|
|
12
|
-
"response",
|
|
13
|
-
];
|
|
5
|
+
const REQUEST_INFO_KEYS = ["request", "params", "ctx", "rw", "cf", "response"];
|
|
14
6
|
REQUEST_INFO_KEYS.forEach((key) => {
|
|
15
7
|
Object.defineProperty(requestInfoBase, key, {
|
|
16
8
|
enumerable: true,
|
package/dist/runtime/script.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { renderHtmlStream } from "./render/renderHtmlStream";
|
|
2
1
|
export { createThenableFromReadableStream } from "./render/createThenableFromReadableStream";
|
|
3
|
-
export {
|
|
2
|
+
export { renderHtmlStream } from "./render/renderHtmlStream";
|
|
3
|
+
export { ssrGetModuleExport, ssrLoadModule, ssrWebpackRequire, } from "./imports/ssr";
|
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
// import it through this bridge module, using the bare import path
|
|
8
8
|
// `rwsdk/__ssr_bridge`. We have bundler logic (ssrBridgePlugin) that looks out
|
|
9
9
|
// for imports to it.
|
|
10
|
-
export { renderHtmlStream } from "./render/renderHtmlStream";
|
|
11
10
|
export { createThenableFromReadableStream } from "./render/createThenableFromReadableStream";
|
|
12
|
-
export {
|
|
11
|
+
export { renderHtmlStream } from "./render/renderHtmlStream";
|
|
12
|
+
export { ssrGetModuleExport, ssrLoadModule, ssrWebpackRequire, } from "./imports/ssr";
|
package/dist/runtime/worker.d.ts
CHANGED
package/dist/runtime/worker.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { renderDocumentHtmlStream } from "./render/renderDocumentHtmlStream";
|
|
3
2
|
import { normalizeActionResult } from "./render/normalizeActionResult";
|
|
3
|
+
import { renderDocumentHtmlStream } from "./render/renderDocumentHtmlStream";
|
|
4
4
|
import { renderToRscStream } from "./render/renderToRscStream";
|
|
5
|
-
import { rscActionHandler } from "./register/worker";
|
|
6
5
|
import { injectRSCPayload } from "rsc-html-stream/server";
|
|
7
6
|
import { ErrorResponse } from "./error";
|
|
7
|
+
import { rscActionHandler } from "./register/worker";
|
|
8
8
|
import { getRequestInfo, runWithRequestInfo, runWithRequestInfoOverrides, } from "./requestInfo/worker";
|
|
9
|
+
import { ssrWebpackRequire } from "./imports/worker";
|
|
9
10
|
import { defineRoutes } from "./lib/router";
|
|
10
11
|
import { generateNonce } from "./lib/utils";
|
|
11
|
-
import { ssrWebpackRequire } from "./imports/worker";
|
|
12
12
|
export * from "./requestInfo/types";
|
|
13
13
|
export const defineApp = (routes) => {
|
|
14
14
|
return {
|
|
@@ -36,7 +36,6 @@ export const defineApp = (routes) => {
|
|
|
36
36
|
const isRSCRequest = url.searchParams.has("__rsc") ||
|
|
37
37
|
request.headers.get("accept")?.includes("text/x-component");
|
|
38
38
|
const isAction = url.searchParams.has("__rsc_action_id");
|
|
39
|
-
const userHeaders = new Headers();
|
|
40
39
|
const rw = {
|
|
41
40
|
Document: DefaultDocument,
|
|
42
41
|
nonce: generateNonce(),
|
|
@@ -52,7 +51,6 @@ export const defineApp = (routes) => {
|
|
|
52
51
|
};
|
|
53
52
|
const outerRequestInfo = {
|
|
54
53
|
request,
|
|
55
|
-
headers: userHeaders,
|
|
56
54
|
cf,
|
|
57
55
|
params: {},
|
|
58
56
|
ctx: {},
|
|
@@ -144,12 +142,6 @@ export const defineApp = (routes) => {
|
|
|
144
142
|
// context(justinvdm, 18 Mar 2025): In some cases, such as a .fetch() call to a durable object instance, or Response.redirect(),
|
|
145
143
|
// we need to return a mutable response object.
|
|
146
144
|
const mutableResponse = new Response(response.body, response);
|
|
147
|
-
// Merge user headers from the legacy headers object
|
|
148
|
-
for (const [key, value] of userHeaders.entries()) {
|
|
149
|
-
if (!response.headers.has(key)) {
|
|
150
|
-
mutableResponse.headers.set(key, value);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
145
|
// Merge headers from user response init (these take precedence)
|
|
154
146
|
if (userResponseInit.headers) {
|
|
155
147
|
const userResponseHeaders = new Headers(userResponseInit.headers);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const addon: () => Promise<void>;
|