rwsdk 1.0.0-beta.42 → 1.0.0-beta.44
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/runtime/client/client.d.ts +22 -1
- package/dist/runtime/client/client.js +23 -2
- package/dist/runtime/entries/no-react-server-ssr-bridge.js +1 -1
- package/dist/runtime/entries/no-react-server.js +3 -1
- package/dist/runtime/entries/react-server-only.js +1 -1
- package/dist/runtime/entries/worker.d.ts +1 -0
- package/dist/runtime/entries/worker.js +1 -0
- package/dist/runtime/lib/links.js +6 -6
- package/dist/runtime/lib/router.d.ts +19 -17
- package/dist/runtime/lib/router.js +343 -108
- package/dist/runtime/lib/router.test.js +343 -1
- package/dist/runtime/requestInfo/types.d.ts +1 -0
- package/dist/runtime/requestInfo/utils.js +1 -0
- package/dist/runtime/requestInfo/worker.js +2 -1
- package/dist/runtime/worker.js +6 -1
- package/dist/use-synced-state/SyncedStateServer.d.mts +19 -4
- package/dist/use-synced-state/SyncedStateServer.mjs +76 -8
- package/dist/use-synced-state/__tests__/SyncStateServer.test.mjs +18 -11
- package/dist/use-synced-state/__tests__/worker.test.mjs +13 -12
- package/dist/use-synced-state/client-core.d.ts +3 -0
- package/dist/use-synced-state/client-core.js +77 -13
- package/dist/use-synced-state/useSyncedState.d.ts +3 -2
- package/dist/use-synced-state/useSyncedState.js +9 -3
- package/dist/use-synced-state/worker.d.mts +2 -1
- package/dist/use-synced-state/worker.mjs +82 -16
- package/dist/vite/runDirectivesScan.mjs +3 -1
- package/dist/vite/transformClientComponents.test.mjs +32 -0
- package/package.json +7 -3
|
@@ -13,7 +13,11 @@ export declare const fetchTransport: Transport;
|
|
|
13
13
|
* making the page interactive. Call this from your client entry point.
|
|
14
14
|
*
|
|
15
15
|
* @param transport - Custom transport for server communication (defaults to fetchTransport)
|
|
16
|
-
* @param hydrateRootOptions - Options passed to React's hydrateRoot
|
|
16
|
+
* @param hydrateRootOptions - Options passed to React's `hydrateRoot`. Supports all React hydration options including:
|
|
17
|
+
* - `onUncaughtError`: Handler for uncaught errors (async errors, event handler errors).
|
|
18
|
+
* If not provided, defaults to logging errors to console.
|
|
19
|
+
* - `onCaughtError`: Handler for errors caught by error boundaries
|
|
20
|
+
* - `onRecoverableError`: Handler for recoverable errors
|
|
17
21
|
* @param handleResponse - Custom response handler for navigation errors (navigation GETs)
|
|
18
22
|
* @param onHydrationUpdate - Callback invoked after a new RSC payload has been committed on the client
|
|
19
23
|
* @param onActionResponse - Optional hook invoked when an action returns a Response;
|
|
@@ -34,6 +38,23 @@ export declare const fetchTransport: Transport;
|
|
|
34
38
|
* initClient({ handleResponse });
|
|
35
39
|
*
|
|
36
40
|
* @example
|
|
41
|
+
* // With error handling
|
|
42
|
+
* initClient({
|
|
43
|
+
* hydrateRootOptions: {
|
|
44
|
+
* onUncaughtError: (error, errorInfo) => {
|
|
45
|
+
* console.error("Uncaught error:", error);
|
|
46
|
+
* // Send to monitoring service
|
|
47
|
+
* sendToSentry(error, errorInfo);
|
|
48
|
+
* },
|
|
49
|
+
* onCaughtError: (error, errorInfo) => {
|
|
50
|
+
* console.error("Caught error:", error);
|
|
51
|
+
* // Handle errors from error boundaries
|
|
52
|
+
* sendToSentry(error, errorInfo);
|
|
53
|
+
* },
|
|
54
|
+
* },
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
37
58
|
* // With custom React hydration options
|
|
38
59
|
* initClient({
|
|
39
60
|
* hydrateRootOptions: {
|
|
@@ -105,7 +105,11 @@ export const fetchTransport = (transportContext) => {
|
|
|
105
105
|
* making the page interactive. Call this from your client entry point.
|
|
106
106
|
*
|
|
107
107
|
* @param transport - Custom transport for server communication (defaults to fetchTransport)
|
|
108
|
-
* @param hydrateRootOptions - Options passed to React's hydrateRoot
|
|
108
|
+
* @param hydrateRootOptions - Options passed to React's `hydrateRoot`. Supports all React hydration options including:
|
|
109
|
+
* - `onUncaughtError`: Handler for uncaught errors (async errors, event handler errors).
|
|
110
|
+
* If not provided, defaults to logging errors to console.
|
|
111
|
+
* - `onCaughtError`: Handler for errors caught by error boundaries
|
|
112
|
+
* - `onRecoverableError`: Handler for recoverable errors
|
|
109
113
|
* @param handleResponse - Custom response handler for navigation errors (navigation GETs)
|
|
110
114
|
* @param onHydrationUpdate - Callback invoked after a new RSC payload has been committed on the client
|
|
111
115
|
* @param onActionResponse - Optional hook invoked when an action returns a Response;
|
|
@@ -126,6 +130,23 @@ export const fetchTransport = (transportContext) => {
|
|
|
126
130
|
* initClient({ handleResponse });
|
|
127
131
|
*
|
|
128
132
|
* @example
|
|
133
|
+
* // With error handling
|
|
134
|
+
* initClient({
|
|
135
|
+
* hydrateRootOptions: {
|
|
136
|
+
* onUncaughtError: (error, errorInfo) => {
|
|
137
|
+
* console.error("Uncaught error:", error);
|
|
138
|
+
* // Send to monitoring service
|
|
139
|
+
* sendToSentry(error, errorInfo);
|
|
140
|
+
* },
|
|
141
|
+
* onCaughtError: (error, errorInfo) => {
|
|
142
|
+
* console.error("Caught error:", error);
|
|
143
|
+
* // Handle errors from error boundaries
|
|
144
|
+
* sendToSentry(error, errorInfo);
|
|
145
|
+
* },
|
|
146
|
+
* },
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
129
150
|
* // With custom React hydration options
|
|
130
151
|
* initClient({
|
|
131
152
|
* hydrateRootOptions: {
|
|
@@ -158,7 +179,7 @@ export const initClient = async ({ transport = fetchTransport, hydrateRootOption
|
|
|
158
179
|
};
|
|
159
180
|
const rootEl = document.getElementById("hydrate-root");
|
|
160
181
|
if (!rootEl) {
|
|
161
|
-
throw new Error('
|
|
182
|
+
throw new Error('RedwoodSDK: No element with id "hydrate-root" found in the document. This element is required for hydration. Ensure your Document component contains a <div id="hydrate-root">{children}</div>.');
|
|
162
183
|
}
|
|
163
184
|
let rscPayload;
|
|
164
185
|
// context(justinvdm, 18 Jun 2025): We inject the RSC payload
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
throw new Error("
|
|
2
|
+
throw new Error("RedwoodSDK: SSR bridge was resolved with 'react-server' condition. This is a bug - the SSR bridge should be intercepted by the esbuild plugin before reaching package.json exports. Please report this issue at https://github.com/redwoodjs/sdk/issues.");
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
throw new Error("
|
|
2
|
+
throw new Error("RedwoodSDK: A client-only module was incorrectly resolved with the 'react-server' condition.\n\n" +
|
|
3
|
+
"This error occurs when modules like 'rwsdk/client', 'rwsdk/__ssr', or 'rwsdk/__ssr_bridge' are being imported in a React Server Components context.\n\n" +
|
|
4
|
+
"For detailed troubleshooting steps, see: https://docs.rwsdk.com/guides/troubleshooting#react-server-components-configuration-errors");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
throw new Error("
|
|
2
|
+
throw new Error("RedwoodSDK: 'react-server' import condition needs to be used in this environment. This code should only run in React Server Components (RSC) context. Check that you're not importing server-only code in client components.");
|
|
@@ -19,13 +19,13 @@ export function defineLinks(routes) {
|
|
|
19
19
|
// Original implementation for route arrays
|
|
20
20
|
routes.forEach((route) => {
|
|
21
21
|
if (typeof route !== "string") {
|
|
22
|
-
throw new Error(`Invalid route: ${route}. Routes must be
|
|
22
|
+
throw new Error(`RedwoodSDK: Invalid route: ${route}. Routes must be string literals. Ensure you're passing an array of route paths.`);
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
const link = createLinkFunction();
|
|
26
26
|
return ((path, params) => {
|
|
27
27
|
if (!routes.includes(path)) {
|
|
28
|
-
throw new Error(`Invalid route: ${path}
|
|
28
|
+
throw new Error(`RedwoodSDK: Invalid route: ${path}. This route is not included in the routes array passed to defineLinks(). Check for typos or ensure the route is defined in your router.`);
|
|
29
29
|
}
|
|
30
30
|
return link(path, params);
|
|
31
31
|
});
|
|
@@ -36,7 +36,7 @@ function createLinkFunction() {
|
|
|
36
36
|
const expectsParams = hasRouteParameters(path);
|
|
37
37
|
if (!params || Object.keys(params).length === 0) {
|
|
38
38
|
if (expectsParams) {
|
|
39
|
-
throw new Error(`Route ${path} requires an object of parameters
|
|
39
|
+
throw new Error(`RedwoodSDK: Route ${path} requires an object of parameters (e.g., link("${path}", { id: "123" })).`);
|
|
40
40
|
}
|
|
41
41
|
return path;
|
|
42
42
|
}
|
|
@@ -62,7 +62,7 @@ function interpolate(template, params) {
|
|
|
62
62
|
const name = match[1];
|
|
63
63
|
const value = params[name];
|
|
64
64
|
if (value === undefined) {
|
|
65
|
-
throw new Error(`Missing parameter "${name}" for route ${template}
|
|
65
|
+
throw new Error(`RedwoodSDK: Missing parameter "${name}" for route ${template}. Ensure you're providing all required parameters in the params object.`);
|
|
66
66
|
}
|
|
67
67
|
result += encodeURIComponent(value);
|
|
68
68
|
consumed.add(name);
|
|
@@ -71,7 +71,7 @@ function interpolate(template, params) {
|
|
|
71
71
|
const key = `$${wildcardIndex}`;
|
|
72
72
|
const value = params[key];
|
|
73
73
|
if (value === undefined) {
|
|
74
|
-
throw new Error(`Missing parameter "${key}" for route ${template}
|
|
74
|
+
throw new Error(`RedwoodSDK: Missing parameter "${key}" for route ${template}. Wildcard routes use $0, $1, etc. as parameter keys.`);
|
|
75
75
|
}
|
|
76
76
|
result += encodeWildcardValue(value);
|
|
77
77
|
consumed.add(key);
|
|
@@ -82,7 +82,7 @@ function interpolate(template, params) {
|
|
|
82
82
|
result += template.slice(lastIndex);
|
|
83
83
|
for (const key of Object.keys(params)) {
|
|
84
84
|
if (!consumed.has(key)) {
|
|
85
|
-
throw new Error(`Parameter "${key}" is not used by route ${template}
|
|
85
|
+
throw new Error(`RedwoodSDK: Parameter "${key}" is not used by route ${template}. Check your params object for typos or remove unused parameters.`);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
TOKEN_REGEX.lastIndex = 0;
|
|
@@ -6,6 +6,10 @@ type BivariantRouteHandler<T extends RequestInfo, R> = {
|
|
|
6
6
|
bivarianceHack(requestInfo: T): R;
|
|
7
7
|
}["bivarianceHack"];
|
|
8
8
|
export type RouteMiddleware<T extends RequestInfo = RequestInfo> = BivariantRouteHandler<T, MaybePromise<React.JSX.Element | Response | void>>;
|
|
9
|
+
export type ExceptHandler<T extends RequestInfo = RequestInfo> = {
|
|
10
|
+
__rwExcept: true;
|
|
11
|
+
handler: (error: unknown, requestInfo: T) => MaybePromise<React.JSX.Element | Response | void>;
|
|
12
|
+
};
|
|
9
13
|
type RouteFunction<T extends RequestInfo = RequestInfo> = BivariantRouteHandler<T, MaybePromise<Response>>;
|
|
10
14
|
type RouteComponent<T extends RequestInfo = RequestInfo> = BivariantRouteHandler<T, MaybePromise<React.JSX.Element | Response | void>>;
|
|
11
15
|
type RouteHandler<T extends RequestInfo = RequestInfo> = RouteFunction<T> | RouteComponent<T> | readonly [...RouteMiddleware<T>[], RouteFunction<T> | RouteComponent<T>];
|
|
@@ -22,7 +26,7 @@ export type MethodHandlers<T extends RequestInfo = RequestInfo> = {
|
|
|
22
26
|
[method: string]: RouteHandler<T>;
|
|
23
27
|
};
|
|
24
28
|
};
|
|
25
|
-
export type Route<T extends RequestInfo = RequestInfo> = RouteMiddleware<T> | RouteDefinition<string, T> | readonly Route<T>[];
|
|
29
|
+
export type Route<T extends RequestInfo = RequestInfo> = RouteMiddleware<T> | RouteDefinition<string, T> | ExceptHandler<T> | readonly Route<T>[];
|
|
26
30
|
type NormalizedRouteDefinition<T extends RequestInfo = RequestInfo> = {
|
|
27
31
|
path: string;
|
|
28
32
|
handler: RouteHandler<T> | MethodHandlers<T>;
|
|
@@ -36,7 +40,7 @@ type TrimLeadingSlash<S extends string> = S extends `/${infer Rest}` ? TrimLeadi
|
|
|
36
40
|
type NormalizePrefix<Prefix extends string> = TrimTrailingSlash<TrimLeadingSlash<Prefix>> extends "" ? "" : `/${TrimTrailingSlash<TrimLeadingSlash<Prefix>>}`;
|
|
37
41
|
type NormalizePath<Path extends string> = TrimTrailingSlash<Path> extends "/" ? "/" : `/${TrimTrailingSlash<TrimLeadingSlash<Path>>}`;
|
|
38
42
|
type JoinPaths<Prefix extends string, Path extends string> = NormalizePrefix<Prefix> extends "" ? NormalizePath<Path> : Path extends "/" ? NormalizePrefix<Prefix> : `${NormalizePrefix<Prefix>}${NormalizePath<Path>}`;
|
|
39
|
-
type PrefixedRouteValue<Prefix extends string, Value> = Value extends RouteDefinition<infer Path, infer Req> ? RouteDefinition<JoinPaths<Prefix, Path>, Req> : Value extends readonly Route<any>[] ? PrefixedRouteArray<Prefix, Value> : Value;
|
|
43
|
+
type PrefixedRouteValue<Prefix extends string, Value> = Value extends RouteDefinition<infer Path, infer Req> ? RouteDefinition<JoinPaths<Prefix, Path>, Req> : Value extends ExceptHandler<any> ? Value : Value extends readonly Route<any>[] ? PrefixedRouteArray<Prefix, Value> : Value;
|
|
40
44
|
type PrefixedRouteArray<Prefix extends string, Routes extends readonly Route<any>[]> = Routes extends readonly [] ? [] : Routes extends readonly [infer Head, ...infer Tail] ? readonly [
|
|
41
45
|
PrefixedRouteValue<Prefix, Head>,
|
|
42
46
|
...PrefixedRouteArray<Prefix, Tail extends readonly Route<any>[] ? Tail : []>
|
|
@@ -104,24 +108,22 @@ export declare function route<Path extends string, T extends RequestInfo = Reque
|
|
|
104
108
|
*/
|
|
105
109
|
export declare function index<T extends RequestInfo = RequestInfo>(handler: RouteHandler<T>): RouteDefinition<"/", T>;
|
|
106
110
|
/**
|
|
107
|
-
*
|
|
111
|
+
* Defines an error handler that catches errors from routes, middleware, and RSC actions.
|
|
108
112
|
*
|
|
109
113
|
* @example
|
|
110
|
-
* //
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* ]
|
|
114
|
+
* // Global error handler
|
|
115
|
+
* except((error, requestInfo) => {
|
|
116
|
+
* console.error(error);
|
|
117
|
+
* return new Response("Internal Server Error", { status: 500 });
|
|
118
|
+
* })
|
|
116
119
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* ]),
|
|
123
|
-
* ])
|
|
120
|
+
* @example
|
|
121
|
+
* // Error handler that returns a React component
|
|
122
|
+
* except((error) => {
|
|
123
|
+
* return <ErrorPage error={error} />;
|
|
124
|
+
* })
|
|
124
125
|
*/
|
|
126
|
+
export declare function except<T extends RequestInfo = RequestInfo>(handler: (error: unknown, requestInfo: T) => MaybePromise<React.JSX.Element | Response | void>): ExceptHandler<T>;
|
|
125
127
|
export declare function prefix<Prefix extends string, T extends RequestInfo = RequestInfo, Routes extends readonly Route<T>[] = readonly Route<T>[]>(prefixPath: Prefix, routes: Routes): PrefixedRouteArray<Prefix, Routes>;
|
|
126
128
|
export declare const wrapHandlerToThrowResponses: <T extends RequestInfo = RequestInfo>(handler: RouteFunction<T> | RouteComponent<T>) => RouteHandler<T>;
|
|
127
129
|
/**
|
|
@@ -129,7 +131,7 @@ export declare const wrapHandlerToThrowResponses: <T extends RequestInfo = Reque
|
|
|
129
131
|
*
|
|
130
132
|
* @example
|
|
131
133
|
* // Define a layout component
|
|
132
|
-
* function BlogLayout({ children }: { children
|
|
134
|
+
* function BlogLayout({ children }: { children?: React.ReactNode }) {
|
|
133
135
|
* return (
|
|
134
136
|
* <div>
|
|
135
137
|
* <nav>Blog Navigation</nav>
|