react-server-frame 0.0.1 → 0.0.3

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.
@@ -0,0 +1,21 @@
1
+ import { t as Payload } from "./generic-payload-Bio3B-X_.mjs";
2
+
3
+ //#region src/browser.d.ts
4
+ declare function createServerCallback({
5
+ createFromFetch,
6
+ createTemporaryReferenceSet,
7
+ encodeReply
8
+ }: {
9
+ createFromFetch: (response: Promise<Response>, options?: object) => Promise<Payload>;
10
+ createTemporaryReferenceSet: () => unknown;
11
+ encodeReply: (v: unknown[], options?: object) => Promise<string | FormData>;
12
+ }): (id: string, args: unknown[]) => Promise<unknown>;
13
+ declare function hydrate({
14
+ createFromFetch,
15
+ createFromReadableStream
16
+ }: {
17
+ createFromFetch: (response: Promise<Response>, options?: object) => Promise<Payload>;
18
+ createFromReadableStream: (stream: ReadableStream<Uint8Array>, options?: object) => Promise<Payload>;
19
+ }): void;
20
+ //#endregion
21
+ export { createServerCallback, hydrate };
@@ -0,0 +1,88 @@
1
+ import { StrictMode, startTransition, use, useState } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { hydrateRoot } from "react-dom/client";
4
+ import { rscStream } from "rsc-html-stream/client";
5
+ //#region src/browser.tsx
6
+ let setPayload;
7
+ function createServerCallback({ createFromFetch, createTemporaryReferenceSet, encodeReply }) {
8
+ return async (id, args) => {
9
+ const url = new URL(window.location.href);
10
+ url.pathname += ".rsc";
11
+ const temporaryReferences = createTemporaryReferenceSet();
12
+ const payload = await createFromFetch(fetch(url, {
13
+ method: "POST",
14
+ body: await encodeReply(args, { temporaryReferences }),
15
+ headers: { "x-rsc-action": id }
16
+ }), { temporaryReferences });
17
+ requestAnimationFrame(() => {
18
+ if (payload.type === "render") startTransition(() => {
19
+ setPayload(Promise.resolve(payload));
20
+ });
21
+ if (payload.type === "redirect") if (window.navigation) requestAnimationFrame(() => {
22
+ window.navigation.navigate(payload.redirect, { history: "replace" });
23
+ });
24
+ else window.location.href = payload.redirect;
25
+ });
26
+ return payload.returnValue;
27
+ };
28
+ }
29
+ let seenPayloads = /* @__PURE__ */ new WeakMap();
30
+ function Content({ initialPayload }) {
31
+ const [promise, _setPayload] = useState(initialPayload);
32
+ setPayload = _setPayload;
33
+ const payload = use(promise);
34
+ if (payload.type === "redirect") if (window.navigation) {
35
+ if (!seenPayloads.has(payload)) {
36
+ const promise = Promise.resolve(window.navigation.navigate(payload.redirect, { history: "replace" }).finished).then(() => {});
37
+ seenPayloads.set(payload, Promise.resolve(promise));
38
+ }
39
+ use(seenPayloads.get(payload));
40
+ return null;
41
+ } else {
42
+ window.location.href = payload.redirect;
43
+ return null;
44
+ }
45
+ return payload.root;
46
+ }
47
+ function hydrate({ createFromFetch, createFromReadableStream }) {
48
+ createFromReadableStream(rscStream).then((payload) => startTransition(() => {
49
+ hydrateRoot(document, /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(Content, { initialPayload: Promise.resolve(payload) }) }), { formState: payload.formState });
50
+ }), (reason) => console.error("Failed to hydrate root", reason));
51
+ let navigationController = new AbortController();
52
+ async function navigate(to) {
53
+ const url = new URL(to, window.location.href);
54
+ url.pathname += ".rsc";
55
+ const thisController = new AbortController();
56
+ const responses = fetch(url, { signal: thisController.signal }).then((response) => [response, response.clone()]);
57
+ startTransition(() => setPayload(createFromFetch(responses.then(([r]) => r))));
58
+ navigationController.abort();
59
+ navigationController = thisController;
60
+ const [, response] = await responses;
61
+ if (!response.body) return;
62
+ const reader = response.body.getReader();
63
+ try {
64
+ let chunk = await reader.read();
65
+ while (!chunk.done) chunk = await reader.read();
66
+ } finally {
67
+ reader.releaseLock();
68
+ }
69
+ }
70
+ window.navigation?.addEventListener("navigate", (event) => {
71
+ if (!event.canIntercept) return;
72
+ if (event.hashChange || event.downloadRequest !== null) return;
73
+ const url = new URL(event.destination.url);
74
+ if (window.location.origin !== url.origin) {
75
+ window.location.href = url.href;
76
+ return;
77
+ }
78
+ event.intercept({ async handler() {
79
+ await navigate(event.destination.url);
80
+ } });
81
+ });
82
+ if (import.meta.hot) import.meta.hot.on("rsc:update", (e) => {
83
+ console.log("[vite-rsc:update]", e.file);
84
+ navigate(location.href);
85
+ });
86
+ }
87
+ //#endregion
88
+ export { createServerCallback, hydrate };
package/dist/client.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { t as Payload } from "./generic-payload-Bio3B-X_.mjs";
2
+ import * as _$react from "react";
1
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
2
4
 
3
5
  //#region src/frames.client.d.ts
@@ -20,5 +22,6 @@ declare function ClientFrame({
20
22
  children?: React.ReactNode;
21
23
  src: string;
22
24
  }): _$react_jsx_runtime0.JSX.Element;
25
+ declare function fetchFrame(url: URL, signal: AbortSignal, createFromFetch: (response: Promise<Response>, options?: object) => Promise<Payload>): Promise<string | number | bigint | boolean | Iterable<_$react.ReactNode> | _$react.ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | _$react.ReactPortal | null | undefined>;
23
26
  //#endregion
24
- export { ClientFrame, FetchFrameProvider, useFrame };
27
+ export { ClientFrame, FetchFrameProvider, fetchFrame, useFrame };
package/dist/client.mjs CHANGED
@@ -48,5 +48,17 @@ function ClientFrame({ children, src }) {
48
48
  children: content
49
49
  });
50
50
  }
51
+ async function fetchFrame(url, signal, createFromFetch) {
52
+ url.pathname += ".rsc";
53
+ const payload = await createFromFetch(fetch(url, { signal }));
54
+ if (payload.type === "redirect") if (window.navigation) return Promise.resolve(window.navigation.navigate(payload.redirect, { history: "replace" }).finished).then(() => {
55
+ return null;
56
+ });
57
+ else {
58
+ window.location.href = payload.redirect;
59
+ return;
60
+ }
61
+ return payload.root;
62
+ }
51
63
  //#endregion
52
- export { ClientFrame, FetchFrameProvider, useFrame };
64
+ export { ClientFrame, FetchFrameProvider, fetchFrame, useFrame };
@@ -0,0 +1,16 @@
1
+ import { ReactFormState } from "react-dom/client";
2
+
3
+ //#region src/generic-payload.d.ts
4
+ type Payload = {
5
+ type: "render";
6
+ root: React.ReactNode;
7
+ returnValue?: Promise<unknown>;
8
+ formState?: ReactFormState;
9
+ } | {
10
+ type: "redirect";
11
+ redirect: string;
12
+ returnValue?: Promise<unknown>;
13
+ formState?: undefined;
14
+ };
15
+ //#endregion
16
+ export { Payload as t };
package/dist/index.d.mts CHANGED
@@ -1,8 +1,24 @@
1
1
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
2
2
  import { ReactFormState } from "react-dom/client";
3
+ import { Middleware, Router } from "remix/fetch-router";
3
4
  import { Route } from "remix/fetch-router/routes";
4
5
 
5
6
  //#region src/frames.d.ts
7
+ declare function mapFrames<Frames extends Routes>(router: Router<any>, frames: Frames, {
8
+ components,
9
+ middleware
10
+ }: {
11
+ middleware?: Middleware[];
12
+ components: Components<Frames>;
13
+ }, config: {
14
+ createTemporaryReferenceSet: () => unknown;
15
+ fetchFrame: (url: URL, signal: AbortSignal) => Promise<React.ReactNode>;
16
+ prerender: (body: ReadableStream<Uint8Array>) => Promise<Response>;
17
+ renderToReadableStream: (payload: any, options?: {
18
+ temporaryReferences: unknown;
19
+ onError: (error: unknown) => string | undefined;
20
+ }) => ReadableStream<Uint8Array>;
21
+ }): void;
6
22
  declare class UseServerState {
7
23
  formState?: ReactFormState;
8
24
  returnValue?: Promise<unknown>;
@@ -14,6 +30,19 @@ declare class RedirectState {
14
30
  location: string;
15
31
  constructor(location: string);
16
32
  }
33
+ declare function useServerMiddleware({
34
+ createTemporaryReferenceSet,
35
+ decodeAction,
36
+ decodeFormState,
37
+ decodeReply,
38
+ loadServerAction
39
+ }: {
40
+ createTemporaryReferenceSet: () => unknown;
41
+ decodeAction: (formData: FormData) => Promise<() => Promise<void>>;
42
+ decodeFormState: (actionResult: unknown, body: FormData) => Promise<ReactFormState | undefined>;
43
+ decodeReply: (body: string | FormData, options?: object) => Promise<unknown[]>;
44
+ loadServerAction: (id: string) => Promise<Function>;
45
+ }): Middleware;
17
46
  declare function redirect(location: string): void;
18
47
  declare function render({
19
48
  createTemporaryReferenceSet,
@@ -24,7 +53,7 @@ declare function render({
24
53
  }: {
25
54
  createTemporaryReferenceSet: () => unknown;
26
55
  prerender: (body: ReadableStream<Uint8Array>) => Promise<Response>;
27
- renderToReadableStream: (payload: any, options: {
56
+ renderToReadableStream: (payload: any, options?: {
28
57
  temporaryReferences: unknown;
29
58
  onError: (error: unknown) => string | undefined;
30
59
  }) => ReadableStream<Uint8Array>;
@@ -35,7 +64,7 @@ declare class NotFoundError extends Error {
35
64
  constructor(message: string);
36
65
  }
37
66
  interface Routes extends Record<string, Route | Routes> {}
38
- type Components<R extends Record<any, any>> = { [K in keyof R]: (R[K] extends Record<any, any> ? Components<R[K]> : never) | React.ComponentType };
67
+ type Components<R extends Routes> = { [K in keyof R]: R[K] extends Routes ? Components<R[K]> : React.ComponentType };
39
68
  type ProvideFramesProps<Frames extends Routes> = {
40
69
  children?: React.ReactNode;
41
70
  components: Components<Frames>;
@@ -54,4 +83,4 @@ declare function Frame({
54
83
  src: string;
55
84
  }): _$react_jsx_runtime0.JSX.Element;
56
85
  //#endregion
57
- export { Frame, NotFoundError, ProvideFrames, ProvideFramesProps, RedirectState, UseServerState, redirect, render };
86
+ export { Frame, NotFoundError, ProvideFrames, ProvideFramesProps, RedirectState, UseServerState, mapFrames, redirect, render, useServerMiddleware };
package/dist/index.mjs CHANGED
@@ -2,7 +2,39 @@ import { ClientFrame, FetchFrameProvider } from "./client.mjs";
2
2
  import { cache } from "react";
3
3
  import { getContext } from "remix/async-context-middleware";
4
4
  import { jsx } from "react/jsx-runtime";
5
+ import "remix/route-pattern";
5
6
  //#region src/frames.tsx
7
+ function mapFrames(router, frames, { components, middleware }, config) {
8
+ for (let [key, frame] of Object.entries(frames)) if (typeof frame.pattern?.test === "function") {
9
+ const handler = ({ request }) => {
10
+ const { createTemporaryReferenceSet, fetchFrame, prerender, renderToReadableStream } = config;
11
+ return render({
12
+ createTemporaryReferenceSet,
13
+ prerender,
14
+ renderToReadableStream,
15
+ request,
16
+ root: /* @__PURE__ */ jsx(ProvideFrames, {
17
+ fetchFrame,
18
+ frames,
19
+ components,
20
+ children: /* @__PURE__ */ jsx(Frame, { src: request.url })
21
+ })
22
+ });
23
+ };
24
+ const action = {
25
+ handler,
26
+ middleware
27
+ };
28
+ let route = frame.pattern;
29
+ router.route("GET", route.source, action);
30
+ router.route("GET", route.source + ".rsc", action);
31
+ router.route("POST", route.source, action);
32
+ router.route("POST", route.source + ".rsc", action);
33
+ } else mapFrames(router, frame, {
34
+ components: components[key],
35
+ middleware
36
+ }, config);
37
+ }
6
38
  var UseServerState = class {
7
39
  formState;
8
40
  returnValue;
@@ -21,6 +53,35 @@ var RedirectState = class {
21
53
  this.location = location;
22
54
  }
23
55
  };
56
+ function useServerMiddleware({ createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction }) {
57
+ return async ({ request, set }, next) => {
58
+ let formState;
59
+ let returnValue;
60
+ let temporaryReferences;
61
+ let actionStatus;
62
+ if (request.method === "POST") {
63
+ const actionId = request.headers.get("x-rsc-action");
64
+ if (actionId) try {
65
+ const body = request.headers.get("content-type")?.startsWith("multipart/form-data") ? await request.formData() : await request.text();
66
+ temporaryReferences = createTemporaryReferenceSet();
67
+ const args = await decodeReply(body, { temporaryReferences });
68
+ returnValue = (await loadServerAction(actionId)).apply(null, args);
69
+ await returnValue;
70
+ } catch (e) {
71
+ actionStatus = 500;
72
+ returnValue = Promise.reject(e);
73
+ }
74
+ else try {
75
+ const formData = await request.formData();
76
+ formState = await decodeFormState(await (await decodeAction(formData))(), formData);
77
+ } catch (e) {
78
+ console.error(e);
79
+ }
80
+ }
81
+ set(UseServerState, new UseServerState(formState, returnValue, temporaryReferences, actionStatus));
82
+ return next();
83
+ };
84
+ }
24
85
  function redirect(location) {
25
86
  getContext().set(RedirectState, new RedirectState(location));
26
87
  }
@@ -103,4 +164,4 @@ function match(frames, components, href) {
103
164
  }
104
165
  }
105
166
  //#endregion
106
- export { Frame, NotFoundError, ProvideFrames, RedirectState, UseServerState, redirect, render };
167
+ export { Frame, NotFoundError, ProvideFrames, RedirectState, UseServerState, mapFrames, redirect, render, useServerMiddleware };
@@ -5,119 +5,16 @@ import {
5
5
  encodeReply,
6
6
  setServerCallback,
7
7
  } from "@vitejs/plugin-rsc/browser";
8
- import { startTransition, StrictMode, use, useState } from "react";
9
- import { hydrateRoot } from "react-dom/client";
10
- import { rscStream } from "rsc-html-stream/client";
11
8
 
9
+ import { createServerCallback, hydrate } from "react-server-frame/browser";
12
10
  import type { Payload } from "../generic-payload.ts";
13
11
 
14
- setServerCallback(async (id, args) => {
15
- const url = new URL(window.location.href);
16
- url.pathname += ".rsc";
17
- const temporaryReferences = createTemporaryReferenceSet();
18
- const payload = await createFromFetch<Payload>(
19
- fetch(url, {
20
- method: "POST",
21
- body: await encodeReply(args, { temporaryReferences }),
22
- headers: {
23
- "x-rsc-action": id,
24
- },
25
- }),
26
- { temporaryReferences },
27
- );
28
- if (payload.type === "render") {
29
- startTransition(() => {
30
- setPayload(Promise.resolve(payload));
31
- });
32
- }
33
- if (payload.type === "redirect") {
34
- if (window.navigation) {
35
- navigate(payload.redirect);
36
- } else {
37
- window.location.href = payload.redirect;
38
- }
39
- }
40
- return payload.returnValue;
41
- });
42
-
43
- createFromReadableStream<Payload>(rscStream).then(
44
- (payload) =>
45
- startTransition(() => {
46
- hydrateRoot(
47
- document,
48
- <StrictMode>
49
- <Content initialPayload={Promise.resolve(payload)} />
50
- </StrictMode>,
51
- {
52
- formState: payload.formState,
53
- },
54
- );
55
- }),
56
- (reason) => console.error("Failed to hydrate root", reason),
12
+ setServerCallback(
13
+ createServerCallback({
14
+ createFromFetch: (response, options) => createFromFetch<Payload>(response, options),
15
+ createTemporaryReferenceSet,
16
+ encodeReply,
17
+ }),
57
18
  );
58
19
 
59
- let setPayload: (payload: Promise<Payload>) => void;
60
-
61
- let seenPayloads = new WeakSet<Payload>();
62
-
63
- function Content({ initialPayload }: { initialPayload: Promise<Payload> }) {
64
- const [promise, _setPayload] = useState(initialPayload);
65
- setPayload = _setPayload;
66
-
67
- const payload = use(promise);
68
-
69
- if (payload.type === "redirect") {
70
- if (window.navigation) {
71
- if (!seenPayloads) {
72
- navigate(payload.redirect);
73
- }
74
- return null;
75
- } else {
76
- window.location.href = payload.redirect;
77
- return null;
78
- }
79
- }
80
-
81
- return payload.root;
82
- }
83
-
84
- let navigationController = new AbortController();
85
- function navigate(to: string) {
86
- const url = new URL(to, window.location.href);
87
- url.pathname += ".rsc";
88
-
89
- if (window.location.host !== url.host) {
90
- window.location.href = url.href;
91
- return;
92
- }
93
-
94
- let thisController = new AbortController();
95
- startTransition(() =>
96
- setPayload(createFromFetch<Payload>(fetch(url, { signal: thisController.signal }))),
97
- );
98
- navigationController.abort();
99
- navigationController = thisController;
100
- }
101
-
102
- window.navigation?.addEventListener("navigate", (event) => {
103
- if (!event.canIntercept) {
104
- return;
105
- }
106
-
107
- if (event.hashChange || event.downloadRequest !== null) {
108
- return;
109
- }
110
-
111
- event.intercept({
112
- async handler() {
113
- navigate(event.destination.url);
114
- },
115
- });
116
- });
117
-
118
- if (import.meta.hot) {
119
- import.meta.hot.on("rsc:update", (e) => {
120
- console.log("[vite-rsc:update]", e.file);
121
- navigate(location.href);
122
- });
123
- }
20
+ hydrate({ createFromFetch, createFromReadableStream });
@@ -6,7 +6,8 @@ import { injectRSCPayload } from "rsc-html-stream/server";
6
6
  import type { Payload } from "../generic-payload.ts";
7
7
 
8
8
  export async function prerender(body: ReadableStream<Uint8Array>) {
9
- const [decodeBody, inlineBody] = body.tee();
9
+ const [decodeBody, _formStateBody] = body.tee();
10
+ const [formStateBody, inlineBody] = _formStateBody.tee();
10
11
 
11
12
  let decode: Promise<Payload> | undefined;
12
13
  function Content() {
@@ -31,8 +32,11 @@ export async function prerender(body: ReadableStream<Uint8Array>) {
31
32
  try {
32
33
  const bootstrapScriptContent = await import.meta.viteRsc.loadBootstrapScriptContent("index");
33
34
 
35
+ const payload = await createFromReadableStream<Payload>(formStateBody);
36
+
34
37
  const html = await renderToReadableStream(<Content />, {
35
38
  bootstrapScriptContent,
39
+ formState: payload.formState,
36
40
  onError(reason: unknown) {
37
41
  if (
38
42
  typeof reason === "object" &&
@@ -46,7 +50,6 @@ export async function prerender(body: ReadableStream<Uint8Array>) {
46
50
  },
47
51
  });
48
52
 
49
- const payload = await decode;
50
53
  return new Response(html.pipeThrough(injectRSCPayload(inlineBody)), {
51
54
  status: payload!.type === "redirect" ? 302 : notFoundError ? 404 : 200,
52
55
  headers: {
@@ -1,18 +1,10 @@
1
1
  "use client";
2
+ import { fetchFrame as fetchFrame$1 } from "../client.mjs";
2
3
  //#region src/vite/fetch-frame.ts
3
4
  if (typeof document !== "undefined") import("@vitejs/plugin-rsc/browser");
4
5
  async function fetchFrame(url, signal) {
5
6
  const { createFromFetch } = await import("@vitejs/plugin-rsc/browser");
6
- url.pathname += ".rsc";
7
- const payload = await createFromFetch(fetch(url, { signal }));
8
- if (payload.type === "redirect") if (window.navigation) return Promise.resolve(window.navigation.navigate(payload.redirect, { history: "replace" }).finished).then(() => {
9
- return null;
10
- });
11
- else {
12
- window.location.href = payload.redirect;
13
- return;
14
- }
15
- return payload.root;
7
+ return fetchFrame$1(url, signal, createFromFetch);
16
8
  }
17
9
  //#endregion
18
10
  export { fetchFrame };
@@ -1,10 +1,13 @@
1
- import { ProvideFrames as ProvideFrames$1 } from "../index.mjs";
1
+ import { ProvideFrames as ProvideFrames$1, mapFrames as mapFrames$1 } from "../index.mjs";
2
2
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
3
  import { Middleware } from "remix/fetch-router";
4
+ import { Route } from "remix/fetch-router/routes";
4
5
 
5
6
  //#region src/vite/frames.d.ts
7
+ interface Routes extends Record<string, Route | Routes> {}
8
+ declare function mapFrames<Frames extends Routes>(router: Parameters<typeof mapFrames$1<Frames>>[0], frames: Parameters<typeof mapFrames$1<Frames>>[1], actions: Parameters<typeof mapFrames$1<Frames>>[2]): void;
6
9
  declare function useServerMiddleware(): Middleware;
7
10
  declare function render(request: Request, root: React.ReactNode): Promise<Response>;
8
11
  declare function ProvideFrames(props: Omit<React.ComponentProps<typeof ProvideFrames$1>, "fetchFrame">): _$react_jsx_runtime0.JSX.Element;
9
12
  //#endregion
10
- export { ProvideFrames, render, useServerMiddleware };
13
+ export { ProvideFrames, mapFrames, render, useServerMiddleware };
@@ -1,41 +1,26 @@
1
- import { ProvideFrames as ProvideFrames$1, UseServerState, render as render$1 } from "../index.mjs";
1
+ import { ProvideFrames as ProvideFrames$1, mapFrames as mapFrames$1, render as render$1, useServerMiddleware as useServerMiddleware$1 } from "../index.mjs";
2
2
  import { fetchFrame } from "./fetch-frame.mjs";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction, renderToReadableStream } from "@vitejs/plugin-rsc/rsc";
5
5
  //#region src/vite/frames.tsx
6
+ function mapFrames(router, frames, actions) {
7
+ return mapFrames$1(router, frames, actions, {
8
+ createTemporaryReferenceSet,
9
+ fetchFrame,
10
+ prerender: async (...args) => {
11
+ return (await import.meta.viteRsc.import("./entry.ssr.tsx", { environment: "ssr" })).prerender(...args);
12
+ },
13
+ renderToReadableStream
14
+ });
15
+ }
6
16
  function useServerMiddleware() {
7
- return async ({ request, set }, next) => {
8
- let formState;
9
- let returnValue;
10
- let temporaryReferences;
11
- let actionStatus;
12
- if (request.method === "POST") {
13
- const actionId = request.headers.get("x-rsc-action");
14
- if (actionId) {
15
- const body = request.headers.get("content-type")?.startsWith("multipart/form-data") ? await request.formData() : await request.text();
16
- temporaryReferences = createTemporaryReferenceSet();
17
- const args = await decodeReply(body, { temporaryReferences });
18
- const action = await loadServerAction(actionId);
19
- try {
20
- returnValue = action.apply(null, args);
21
- await returnValue;
22
- } catch (e) {
23
- actionStatus = 500;
24
- returnValue = Promise.reject(e);
25
- }
26
- } else {
27
- const formData = await request.formData();
28
- const decodedAction = await decodeAction(formData);
29
- try {
30
- formState = await decodeFormState(await decodedAction(), formData);
31
- } catch (e) {
32
- console.error(e);
33
- }
34
- }
35
- }
36
- set(UseServerState, new UseServerState(formState, returnValue, temporaryReferences, actionStatus));
37
- return next();
38
- };
17
+ return useServerMiddleware$1({
18
+ createTemporaryReferenceSet,
19
+ decodeAction,
20
+ decodeFormState,
21
+ decodeReply,
22
+ loadServerAction
23
+ });
39
24
  }
40
25
  async function render(request, root) {
41
26
  return render$1({
@@ -53,4 +38,4 @@ function ProvideFrames(props) {
53
38
  });
54
39
  }
55
40
  //#endregion
56
- export { ProvideFrames, render, useServerMiddleware };
41
+ export { ProvideFrames, mapFrames, render, useServerMiddleware };
@@ -1,7 +1,7 @@
1
1
  import * as Vite from "vite";
2
2
 
3
3
  //#region src/vite/plugin.d.ts
4
- declare function framework({
4
+ declare function reactServerFrame({
5
5
  entry
6
6
  }?: {
7
7
  entry?: string;
@@ -10,4 +10,4 @@ declare function framework({
10
10
  config(this: Vite.ConfigPluginContext, userConfig: Vite.UserConfig): Record<string, any>;
11
11
  };
12
12
  //#endregion
13
- export { framework };
13
+ export { reactServerFrame };
@@ -5,7 +5,7 @@ import * as Vite from "vite";
5
5
  function getEntry(file) {
6
6
  return Vite.normalizePath(path.join(path.dirname(fileURLToPath(import.meta.url)), file));
7
7
  }
8
- function framework({ entry = "/src/entry.server" } = {}) {
8
+ function reactServerFrame({ entry = "/src/entry.server" } = {}) {
9
9
  return {
10
10
  name: "framework",
11
11
  config(userConfig) {
@@ -18,4 +18,4 @@ function framework({ entry = "/src/entry.server" } = {}) {
18
18
  };
19
19
  }
20
20
  //#endregion
21
- export { framework };
21
+ export { reactServerFrame };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-server-frame",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A new type of RSC routing.",
5
5
  "homepage": "https://github.com/jacob-ebey/react-server-frame#readme",
6
6
  "bugs": {
@@ -19,6 +19,7 @@
19
19
  "type": "module",
20
20
  "exports": {
21
21
  ".": "./dist/index.mjs",
22
+ "./browser": "./dist/browser.mjs",
22
23
  "./client": "./dist/client.mjs",
23
24
  "./vite/fetch-frame": "./dist/vite/fetch-frame.mjs",
24
25
  "./vite/frames": "./dist/vite/frames.mjs",
@@ -28,39 +29,31 @@
28
29
  "publishConfig": {
29
30
  "access": "public"
30
31
  },
31
- "scripts": {
32
- "build": "vp pack",
33
- "dev": "vp pack --watch",
34
- "test": "vp test",
35
- "check": "vp check",
36
- "prepublishOnly": "vp run build"
37
- },
38
32
  "dependencies": {
39
33
  "rsc-html-stream": "0.0.7"
40
34
  },
41
35
  "devDependencies": {
42
36
  "@types/dom-navigation": "^1.0.7",
43
- "@types/node": "catalog:",
44
- "@types/react": "catalog:",
45
- "@types/react-dom": "catalog:",
46
- "@typescript/native-preview": "catalog:",
37
+ "@types/node": "^24",
38
+ "@types/react": "^19.2.14",
39
+ "@types/react-dom": "^19.2.3",
40
+ "@typescript/native-preview": "7.0.0-dev.20260328.1",
47
41
  "@vitejs/plugin-react": "^6.0.1",
48
- "@vitejs/plugin-rsc": "^0.5.21",
49
- "bumpp": "^11.0.1",
50
- "react": "catalog:",
51
- "react-dom": "catalog:",
52
- "react-server-dom-webpack": "catalog:",
53
- "remix": "catalog:",
54
- "typescript": "catalog:",
55
- "vite": "catalog:",
56
- "vite-plus": "catalog:"
42
+ "@vitejs/plugin-rsc": "~0.5.21",
43
+ "react": "canary",
44
+ "react-dom": "canary",
45
+ "react-server-dom-webpack": "canary",
46
+ "remix": "3.0.0-alpha.4",
47
+ "typescript": "^6.0.2",
48
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
49
+ "vite-plus": "latest"
57
50
  },
58
51
  "peerDependencies": {
59
- "@vitejs/plugin-react": "catalog:",
60
- "@vitejs/plugin-rsc": "catalog:",
61
- "react": "catalog:",
62
- "react-dom": "catalog:",
63
- "react-server-dom-webpack": "catalog:",
52
+ "@vitejs/plugin-react": "^6.0.1",
53
+ "@vitejs/plugin-rsc": "~0.5.21",
54
+ "react": "canary",
55
+ "react-dom": "canary",
56
+ "react-server-dom-webpack": "canary",
64
57
  "remix": "*",
65
58
  "vite": "*"
66
59
  },
@@ -77,5 +70,11 @@
77
70
  "vite": {
78
71
  "optional": true
79
72
  }
73
+ },
74
+ "scripts": {
75
+ "build": "vp pack",
76
+ "dev": "vp pack --watch",
77
+ "test": "vp test",
78
+ "check": "vp check"
80
79
  }
81
- }
80
+ }