react-server-frame 0.0.5 → 0.0.6
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/browser.d.mts +2 -1
- package/dist/browser.d.mts.map +1 -0
- package/dist/browser.mjs +2 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/client.d.mts +2 -1
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +2 -0
- package/dist/client.mjs.map +1 -0
- package/dist/generic-payload-Bio3B-X_.d.mts +2 -1
- package/dist/generic-payload-Bio3B-X_.d.mts.map +1 -0
- package/dist/index.d.mts +13 -5
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +38 -10
- package/dist/index.mjs.map +1 -0
- package/dist/vite/fetch-frame.d.mts +2 -1
- package/dist/vite/fetch-frame.d.mts.map +1 -0
- package/dist/vite/fetch-frame.mjs +2 -0
- package/dist/vite/fetch-frame.mjs.map +1 -0
- package/dist/vite/frames.d.mts +2 -1
- package/dist/vite/frames.d.mts.map +1 -0
- package/dist/vite/frames.mjs +2 -0
- package/dist/vite/frames.mjs.map +1 -0
- package/dist/vite/plugin.d.mts +2 -1
- package/dist/vite/plugin.d.mts.map +1 -0
- package/dist/vite/plugin.mjs +2 -0
- package/dist/vite/plugin.mjs.map +1 -0
- package/package.json +2 -2
package/dist/browser.d.mts
CHANGED
|
@@ -18,4 +18,5 @@ declare function hydrate({
|
|
|
18
18
|
createFromReadableStream: (stream: ReadableStream<Uint8Array>, options?: object) => Promise<Payload>;
|
|
19
19
|
}): void;
|
|
20
20
|
//#endregion
|
|
21
|
-
export { createServerCallback, hydrate };
|
|
21
|
+
export { createServerCallback, hydrate };
|
|
22
|
+
//# sourceMappingURL=browser.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.mts","names":[],"sources":["../src/browser.tsx"],"mappings":";;;iBAQgB,oBAAA,CAAA;EACd,eAAA;EACA,2BAAA;EACA;AAAA;EAEA,eAAA,GAAkB,QAAA,EAAU,OAAA,CAAQ,QAAA,GAAW,OAAA,cAAqB,OAAA,CAAQ,OAAA;EAC5E,2BAAA;EACA,WAAA,GAAc,CAAA,aAAc,OAAA,cAAqB,OAAA,UAAiB,QAAA;AAAA,KACnE,EAAA,UACyB,IAAA,gBAAiB,OAAA;AAAA,iBAgE3B,OAAA,CAAA;EACd,eAAA;EACA;AAAA;EAEA,eAAA,GAAkB,QAAA,EAAU,OAAA,CAAQ,QAAA,GAAW,OAAA,cAAqB,OAAA,CAAQ,OAAA;EAC5E,wBAAA,GACE,MAAA,EAAQ,cAAA,CAAe,UAAA,GACvB,OAAA,cACG,OAAA,CAAQ,OAAA;AAAA"}
|
package/dist/browser.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.mjs","names":[],"sources":["../src/browser.tsx"],"sourcesContent":["import { startTransition, StrictMode, use, useState } from \"react\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { rscStream } from \"rsc-html-stream/client\";\n\nimport type { Payload } from \"./generic-payload.ts\";\n\nlet setPayload: (payload: Promise<Payload>) => void;\n\nexport function createServerCallback({\n createFromFetch,\n createTemporaryReferenceSet,\n encodeReply,\n}: {\n createFromFetch: (response: Promise<Response>, options?: object) => Promise<Payload>;\n createTemporaryReferenceSet: () => unknown;\n encodeReply: (v: unknown[], options?: object) => Promise<string | FormData>;\n}) {\n return async (id: string, args: unknown[]) => {\n const url = new URL(window.location.href);\n url.pathname += \".rsc\";\n const temporaryReferences = createTemporaryReferenceSet();\n const payload = await createFromFetch(\n fetch(url, {\n method: \"POST\",\n body: await encodeReply(args, { temporaryReferences }),\n headers: {\n \"x-rsc-action\": id,\n },\n }),\n { temporaryReferences },\n );\n requestAnimationFrame(() => {\n if (payload.type === \"render\") {\n startTransition(() => {\n setPayload(Promise.resolve(payload));\n });\n }\n if (payload.type === \"redirect\") {\n if (window.navigation) {\n requestAnimationFrame(() => {\n window.navigation.navigate(payload.redirect, {\n history: \"replace\",\n });\n });\n } else {\n window.location.href = payload.redirect;\n }\n }\n });\n return payload.returnValue;\n };\n}\n\nlet seenPayloads = new WeakMap<Payload, Promise<void>>();\nfunction Content({ initialPayload }: { initialPayload: Promise<Payload> }) {\n const [promise, _setPayload] = useState(initialPayload);\n setPayload = _setPayload;\n\n const payload = use(promise);\n\n if (payload.type === \"redirect\") {\n if (window.navigation) {\n if (!seenPayloads.has(payload)) {\n const promise = Promise.resolve(\n window.navigation.navigate(payload.redirect, {\n history: \"replace\",\n }).finished,\n ).then(() => {});\n seenPayloads.set(payload, Promise.resolve(promise));\n }\n use(seenPayloads.get(payload)!);\n return null;\n } else {\n window.location.href = payload.redirect;\n return null;\n }\n }\n\n return payload.root;\n}\n\nexport function hydrate({\n createFromFetch,\n createFromReadableStream,\n}: {\n createFromFetch: (response: Promise<Response>, options?: object) => Promise<Payload>;\n createFromReadableStream: (\n stream: ReadableStream<Uint8Array>,\n options?: object,\n ) => Promise<Payload>;\n}) {\n createFromReadableStream(rscStream).then(\n (payload) =>\n startTransition(() => {\n hydrateRoot(\n document,\n <StrictMode>\n <Content initialPayload={Promise.resolve(payload)} />\n </StrictMode>,\n {\n formState: payload.formState,\n },\n );\n }),\n (reason) => console.error(\"Failed to hydrate root\", reason),\n );\n\n let navigationController = new AbortController();\n async function navigate(to: string) {\n const url = new URL(to, window.location.href);\n url.pathname += \".rsc\";\n\n const thisController = new AbortController();\n const responses = fetch(url, { signal: thisController.signal }).then((response) => [\n response,\n response.clone(),\n ]);\n\n startTransition(() => setPayload(createFromFetch(responses.then(([r]) => r))));\n navigationController.abort();\n navigationController = thisController;\n\n const [, response] = await responses;\n if (!response.body) return;\n const reader = response.body.getReader();\n try {\n let chunk = await reader.read();\n while (!chunk.done) {\n chunk = await reader.read();\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n window.navigation?.addEventListener(\"navigate\", (event) => {\n if (!event.canIntercept) {\n return;\n }\n\n if (event.hashChange || event.downloadRequest !== null) {\n return;\n }\n\n const url = new URL(event.destination.url);\n\n if (window.location.origin !== url.origin) {\n window.location.href = url.href;\n return;\n }\n\n event.intercept({\n async handler() {\n await navigate(event.destination.url);\n },\n });\n });\n\n if (import.meta.hot) {\n import.meta.hot.on(\"rsc:update\", (e) => {\n console.log(\"[vite-rsc:update]\", e.file);\n void navigate(location.href);\n });\n }\n}\n"],"mappings":"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"}
|
package/dist/client.d.mts
CHANGED
|
@@ -24,4 +24,5 @@ declare function ClientFrame({
|
|
|
24
24
|
}): _$react_jsx_runtime0.JSX.Element;
|
|
25
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>;
|
|
26
26
|
//#endregion
|
|
27
|
-
export { ClientFrame, FetchFrameProvider, fetchFrame, useFrame };
|
|
27
|
+
export { ClientFrame, FetchFrameProvider, fetchFrame, useFrame };
|
|
28
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/frames.client.tsx"],"mappings":";;;;;KAKK,KAAA;EACH,OAAA;EACA,MAAA;AAAA;AAAA,iBAUc,kBAAA,CAAA;EACd,QAAA;EACA;AAAA;EAEA,QAAA,EAAU,KAAA,CAAM,SAAA;EAChB,UAAA,IAAc,GAAA,EAAK,GAAA,EAAK,MAAA,EAAQ,WAAA,KAAgB,OAAA,CAAQ,KAAA,CAAM,SAAA;AAAA,IAC/D,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAIe,QAAA,CAAA,GAAQ,KAAA;AAAA,iBAmBR,WAAA,CAAA;EAAc,QAAA;EAAU;AAAA;EAAS,QAAA,GAAW,KAAA,CAAM,SAAA;EAAW,GAAA;AAAA,IAAa,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAuCpE,UAAA,CACpB,GAAA,EAAK,GAAA,EACL,MAAA,EAAQ,WAAA,EACR,eAAA,GAAkB,QAAA,EAAU,OAAA,CAAQ,QAAA,GAAW,OAAA,cAAqB,OAAA,CAAQ,OAAA,IAAQ,OAAA,sCAAA,QAAA,CAAT,OAAA,CAAS,SAAA,IAAA,OAAA,CAAA,YAAA,mBAAA,OAAA,CAAA,qBAAA,SAAA,OAAA,CAAA,WAAA"}
|
package/dist/client.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/frames.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, use, useCallback, useMemo, useRef, useState, useTransition } from \"react\";\nimport type { Payload } from \"./generic-payload.ts\";\n\ntype Frame = {\n pending: boolean;\n reload: () => void;\n};\n\nconst FrameContext = createContext<undefined | Frame>(undefined);\nFrameContext.displayName = \"FrameContext\";\n\nconst FetchFrameContext = createContext<\n undefined | ((url: URL, signal: AbortSignal) => Promise<React.ReactNode>)\n>(undefined);\n\nexport function FetchFrameProvider({\n children,\n fetchFrame,\n}: {\n children: React.ReactNode;\n fetchFrame?: (url: URL, signal: AbortSignal) => Promise<React.ReactNode>;\n}) {\n return <FetchFrameContext.Provider value={fetchFrame}>{children}</FetchFrameContext.Provider>;\n}\n\nexport function useFrame() {\n let frame = use(FrameContext);\n\n if (!frame) {\n throw new Error(\"useFrame must be used within a Frame / ClientFrame\");\n }\n\n return frame;\n}\n\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"then\" in value &&\n typeof value.then === \"function\"\n );\n}\n\nexport function ClientFrame({ children, src }: { children?: React.ReactNode; src: string }) {\n const [_content, setContent] = useState<React.ReactNode | Promise<React.ReactNode>>(children);\n const content = isPromise(_content) ? use(_content) : _content;\n\n const [pending, startTransition] = useTransition();\n\n const [lastChildren, setLastChildren] = useState(children);\n if (lastChildren !== children) {\n setLastChildren(children);\n setContent(children);\n }\n\n const controllerRef = useRef<AbortController>(undefined);\n\n const fetchFrame = use(FetchFrameContext);\n\n const reload = useCallback(() => {\n if (!fetchFrame) throw new Error(\"FetchFrameContext is not provided\");\n\n const thisController = new AbortController();\n startTransition(() =>\n setContent(fetchFrame(new URL(src, window.location.href), thisController.signal)),\n );\n controllerRef.current?.abort();\n controllerRef.current = thisController;\n }, [fetchFrame, src]);\n\n const frame = useMemo(() => {\n const result = {\n pending,\n reload,\n };\n\n return result;\n }, [pending, reload]);\n\n return <FrameContext.Provider value={frame}>{content}</FrameContext.Provider>;\n}\n\nexport async function fetchFrame(\n url: URL,\n signal: AbortSignal,\n createFromFetch: (response: Promise<Response>, options?: object) => Promise<Payload>,\n) {\n url.pathname += \".rsc\";\n const payload = await createFromFetch(fetch(url, { signal }));\n if (payload.type === \"redirect\") {\n if (window.navigation) {\n return Promise.resolve(\n window.navigation.navigate(payload.redirect, {\n history: \"replace\",\n }).finished,\n ).then(() => {\n return null as React.ReactNode;\n });\n } else {\n window.location.href = payload.redirect;\n return;\n }\n }\n return payload.root;\n}\n"],"mappings":";;;;AAUA,MAAM,eAAe,cAAiC,KAAA,EAAU;AAChE,aAAa,cAAc;AAE3B,MAAM,oBAAoB,cAExB,KAAA,EAAU;AAEZ,SAAgB,mBAAmB,EACjC,UACA,cAIC;AACD,QAAO,oBAAC,kBAAkB,UAAnB;EAA4B,OAAO;EAAa;EAAsC,CAAA;;AAG/F,SAAgB,WAAW;CACzB,IAAI,QAAQ,IAAI,aAAa;AAE7B,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,qDAAqD;AAGvE,QAAO;;AAGT,SAAS,UAAa,OAA4C;AAChE,QACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,OAAO,MAAM,SAAS;;AAI1B,SAAgB,YAAY,EAAE,UAAU,OAAoD;CAC1F,MAAM,CAAC,UAAU,cAAc,SAAqD,SAAS;CAC7F,MAAM,UAAU,UAAU,SAAS,GAAG,IAAI,SAAS,GAAG;CAEtD,MAAM,CAAC,SAAS,mBAAmB,eAAe;CAElD,MAAM,CAAC,cAAc,mBAAmB,SAAS,SAAS;AAC1D,KAAI,iBAAiB,UAAU;AAC7B,kBAAgB,SAAS;AACzB,aAAW,SAAS;;CAGtB,MAAM,gBAAgB,OAAwB,KAAA,EAAU;CAExD,MAAM,aAAa,IAAI,kBAAkB;CAEzC,MAAM,SAAS,kBAAkB;AAC/B,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,oCAAoC;EAErE,MAAM,iBAAiB,IAAI,iBAAiB;AAC5C,wBACE,WAAW,WAAW,IAAI,IAAI,KAAK,OAAO,SAAS,KAAK,EAAE,eAAe,OAAO,CAAC,CAClF;AACD,gBAAc,SAAS,OAAO;AAC9B,gBAAc,UAAU;IACvB,CAAC,YAAY,IAAI,CAAC;CAErB,MAAM,QAAQ,cAAc;AAM1B,SALe;GACb;GACA;GACD;IAGA,CAAC,SAAS,OAAO,CAAC;AAErB,QAAO,oBAAC,aAAa,UAAd;EAAuB,OAAO;YAAQ;EAAgC,CAAA;;AAG/E,eAAsB,WACpB,KACA,QACA,iBACA;AACA,KAAI,YAAY;CAChB,MAAM,UAAU,MAAM,gBAAgB,MAAM,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC7D,KAAI,QAAQ,SAAS,WACnB,KAAI,OAAO,WACT,QAAO,QAAQ,QACb,OAAO,WAAW,SAAS,QAAQ,UAAU,EAC3C,SAAS,WACV,CAAC,CAAC,SACJ,CAAC,WAAW;AACX,SAAO;GACP;MACG;AACL,SAAO,SAAS,OAAO,QAAQ;AAC/B;;AAGJ,QAAO,QAAQ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic-payload-Bio3B-X_.d.mts","names":[],"sources":["../src/generic-payload.ts"],"mappings":";;;KAEY,OAAA;EAEN,IAAA;EACA,IAAA,EAAM,KAAA,CAAM,SAAA;EACZ,WAAA,GAAc,OAAA;EACd,SAAA,GAAY,cAAA;AAAA;EAGZ,IAAA;EACA,QAAA;EACA,WAAA,GAAc,OAAA;EACd,SAAA;AAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -15,8 +15,8 @@ declare function mapFrames<Frames extends Routes>(router: Router<any>, frames: F
|
|
|
15
15
|
fetchFrame: (url: URL, signal: AbortSignal) => Promise<React.ReactNode>;
|
|
16
16
|
prerender: (body: ReadableStream<Uint8Array>) => Promise<Response>;
|
|
17
17
|
renderToReadableStream: (payload: any, options?: {
|
|
18
|
-
temporaryReferences
|
|
19
|
-
onError
|
|
18
|
+
temporaryReferences?: unknown;
|
|
19
|
+
onError?: (error: unknown) => string | undefined;
|
|
20
20
|
}) => ReadableStream<Uint8Array>;
|
|
21
21
|
}): void;
|
|
22
22
|
declare class UseServerState {
|
|
@@ -30,6 +30,10 @@ declare class RedirectState {
|
|
|
30
30
|
location: string;
|
|
31
31
|
constructor(location: string);
|
|
32
32
|
}
|
|
33
|
+
declare function reactRedirectsMiddleware(renderToReadableStream: (payload: any, options?: {
|
|
34
|
+
temporaryReferences?: unknown;
|
|
35
|
+
onError?: (error: unknown) => string | undefined;
|
|
36
|
+
}) => ReadableStream<Uint8Array>): Middleware;
|
|
33
37
|
declare function useServerMiddleware({
|
|
34
38
|
createTemporaryReferenceSet,
|
|
35
39
|
decodeAction,
|
|
@@ -43,7 +47,7 @@ declare function useServerMiddleware({
|
|
|
43
47
|
decodeReply: (body: string | FormData, options?: object) => Promise<unknown[]>;
|
|
44
48
|
loadServerAction: (id: string) => Promise<Function>;
|
|
45
49
|
}): Middleware;
|
|
46
|
-
declare function redirect(
|
|
50
|
+
declare function redirect(locationOrRedirect: string | Response): void;
|
|
47
51
|
declare function render({
|
|
48
52
|
createTemporaryReferenceSet,
|
|
49
53
|
prerender,
|
|
@@ -64,7 +68,10 @@ declare class NotFoundError extends Error {
|
|
|
64
68
|
constructor(message: string);
|
|
65
69
|
}
|
|
66
70
|
interface Routes extends Record<string, Route | Routes> {}
|
|
67
|
-
type Components<R extends Routes> = { [K in keyof R]: R[K] extends Routes ? Components<R[K]> : React.ComponentType
|
|
71
|
+
type Components<R extends Routes> = { [K in keyof R]: R[K] extends Routes ? Components<R[K]> : React.ComponentType | {
|
|
72
|
+
middleware?: Middleware[];
|
|
73
|
+
component: React.ComponentType;
|
|
74
|
+
} };
|
|
68
75
|
type ProvideFramesProps<Frames extends Routes> = {
|
|
69
76
|
children?: React.ReactNode;
|
|
70
77
|
components: Components<Frames>;
|
|
@@ -83,4 +90,5 @@ declare function Frame({
|
|
|
83
90
|
src: string;
|
|
84
91
|
}): _$react_jsx_runtime0.JSX.Element;
|
|
85
92
|
//#endregion
|
|
86
|
-
export { Frame, NotFoundError, ProvideFrames, ProvideFramesProps, RedirectState, UseServerState, mapFrames, redirect, render, useServerMiddleware };
|
|
93
|
+
export { Frame, NotFoundError, ProvideFrames, ProvideFramesProps, RedirectState, UseServerState, mapFrames, reactRedirectsMiddleware, redirect, render, useServerMiddleware };
|
|
94
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/frames.tsx"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -4,10 +4,10 @@ import { getContext } from "remix/async-context-middleware";
|
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import "remix/route-pattern";
|
|
6
6
|
//#region src/frames.tsx
|
|
7
|
-
function mapFrames(router, frames, { components, middleware }, config) {
|
|
7
|
+
function mapFrames(router, frames, { components, middleware = [] }, config) {
|
|
8
|
+
const { createTemporaryReferenceSet, fetchFrame, prerender, renderToReadableStream } = config;
|
|
8
9
|
for (let [key, frame] of Object.entries(frames)) if (typeof frame.pattern?.test === "function") {
|
|
9
10
|
const handler = ({ request }) => {
|
|
10
|
-
const { createTemporaryReferenceSet, fetchFrame, prerender, renderToReadableStream } = config;
|
|
11
11
|
return render({
|
|
12
12
|
createTemporaryReferenceSet,
|
|
13
13
|
prerender,
|
|
@@ -21,10 +21,15 @@ function mapFrames(router, frames, { components, middleware }, config) {
|
|
|
21
21
|
})
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
|
+
const localMiddleware = typeof components[key] === "function" ? [] : components[key].middleware ?? [];
|
|
24
25
|
const action = {
|
|
25
26
|
action: handler,
|
|
26
27
|
handler,
|
|
27
|
-
middleware
|
|
28
|
+
middleware: [
|
|
29
|
+
reactRedirectsMiddleware(renderToReadableStream),
|
|
30
|
+
...middleware,
|
|
31
|
+
...localMiddleware
|
|
32
|
+
]
|
|
28
33
|
};
|
|
29
34
|
let route = frame.pattern;
|
|
30
35
|
router.route("GET", route.source, action);
|
|
@@ -54,6 +59,17 @@ var RedirectState = class {
|
|
|
54
59
|
this.location = location;
|
|
55
60
|
}
|
|
56
61
|
};
|
|
62
|
+
function reactRedirectsMiddleware(renderToReadableStream) {
|
|
63
|
+
return async ({ request }, next) => {
|
|
64
|
+
const response = await next();
|
|
65
|
+
const url = new URL(request.url);
|
|
66
|
+
let redirect;
|
|
67
|
+
if (isReactRequest(url) && (redirect = getRedirect(response))) return new Response(renderToReadableStream({
|
|
68
|
+
type: "redirect",
|
|
69
|
+
redirect
|
|
70
|
+
}), { headers: { "Content-Type": "text/x-component; charset=utf-8" } });
|
|
71
|
+
};
|
|
72
|
+
}
|
|
57
73
|
function useServerMiddleware({ createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction }) {
|
|
58
74
|
return async ({ request, set }, next) => {
|
|
59
75
|
let formState;
|
|
@@ -83,7 +99,11 @@ function useServerMiddleware({ createTemporaryReferenceSet, decodeAction, decode
|
|
|
83
99
|
return next();
|
|
84
100
|
};
|
|
85
101
|
}
|
|
86
|
-
function redirect(
|
|
102
|
+
function redirect(locationOrRedirect) {
|
|
103
|
+
let location;
|
|
104
|
+
if (typeof locationOrRedirect === "string") location = locationOrRedirect;
|
|
105
|
+
else location = getRedirect(locationOrRedirect);
|
|
106
|
+
if (!location) throw new Error("No redirect location provided");
|
|
87
107
|
getContext().set(RedirectState, new RedirectState(location));
|
|
88
108
|
}
|
|
89
109
|
async function render({ createTemporaryReferenceSet, prerender, renderToReadableStream, request, root }) {
|
|
@@ -114,7 +134,7 @@ async function render({ createTemporaryReferenceSet, prerender, renderToReadable
|
|
|
114
134
|
console.error(error);
|
|
115
135
|
}
|
|
116
136
|
});
|
|
117
|
-
if (new URL(request.url)
|
|
137
|
+
if (isReactRequest(new URL(request.url))) return new Response(body, { headers: { "Content-Type": "text/x-component; charset=utf-8" } });
|
|
118
138
|
return await prerender(body);
|
|
119
139
|
} catch (reason) {
|
|
120
140
|
if (reason instanceof Error && reason.name === "NotFoundError") return new Response("Not Found", { status: 404 });
|
|
@@ -148,7 +168,7 @@ function Frame({ src }) {
|
|
|
148
168
|
const cache = frameCache();
|
|
149
169
|
if (!cache.components || !cache.frames) throw new Error("No frames provided");
|
|
150
170
|
const url = new URL(src, "http://react-server-frame/");
|
|
151
|
-
if (url
|
|
171
|
+
if (isReactRequest(url)) url.pathname = url.pathname.slice(0, -4);
|
|
152
172
|
const Component = match(cache.frames, cache.components, url.href);
|
|
153
173
|
if (!Component) throw new NotFoundError("No matching frame found");
|
|
154
174
|
return /* @__PURE__ */ jsx(ClientFrame, {
|
|
@@ -157,12 +177,20 @@ function Frame({ src }) {
|
|
|
157
177
|
});
|
|
158
178
|
}
|
|
159
179
|
function match(frames, components, href) {
|
|
160
|
-
for (const [id, route] of Object.entries(frames)) if (typeof route.pattern?.test === "function")
|
|
161
|
-
|
|
162
|
-
} else {
|
|
180
|
+
for (const [id, route] of Object.entries(frames)) if (typeof route.pattern?.test === "function" && route.pattern.test(href)) return typeof components?.[id] === "object" && components[id].component ? components[id].component : components[id];
|
|
181
|
+
else {
|
|
163
182
|
let matched = match(route, components?.[id], href);
|
|
164
183
|
if (matched) return matched;
|
|
165
184
|
}
|
|
166
185
|
}
|
|
186
|
+
function isReactRequest(url) {
|
|
187
|
+
return url.pathname.endsWith(".rsc");
|
|
188
|
+
}
|
|
189
|
+
function getRedirect(response) {
|
|
190
|
+
if (response.status < 300 || response.status >= 400) return null;
|
|
191
|
+
return response.headers.get("Location");
|
|
192
|
+
}
|
|
167
193
|
//#endregion
|
|
168
|
-
export { Frame, NotFoundError, ProvideFrames, RedirectState, UseServerState, mapFrames, redirect, render, useServerMiddleware };
|
|
194
|
+
export { Frame, NotFoundError, ProvideFrames, RedirectState, UseServerState, mapFrames, reactRedirectsMiddleware, redirect, render, useServerMiddleware };
|
|
195
|
+
|
|
196
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/frames.tsx"],"sourcesContent":["import { cache } from \"react\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { getContext } from \"remix/async-context-middleware\";\nimport type { Middleware, RequestHandler, Router } from \"remix/fetch-router\";\nimport type { Route } from \"remix/fetch-router/routes\";\n\nimport { ClientFrame, FetchFrameProvider } from \"./frames.client.tsx\";\nimport type { Payload } from \"./generic-payload.ts\";\nimport { RoutePattern } from \"remix/route-pattern\";\n\nexport function mapFrames<Frames extends Routes>(\n router: Router<any>,\n frames: Frames,\n { components, middleware = [] }: { middleware?: Middleware[]; components: Components<Frames> },\n config: {\n createTemporaryReferenceSet: () => unknown;\n fetchFrame: (url: URL, signal: AbortSignal) => Promise<React.ReactNode>;\n prerender: (body: ReadableStream<Uint8Array>) => Promise<Response>;\n renderToReadableStream: (\n payload: any,\n options?: {\n temporaryReferences?: unknown;\n onError?: (error: unknown) => string | undefined;\n },\n ) => ReadableStream<Uint8Array>;\n },\n) {\n const { createTemporaryReferenceSet, fetchFrame, prerender, renderToReadableStream } = config;\n\n for (let [key, frame] of Object.entries(frames)) {\n if (typeof (frame as Route).pattern?.test === \"function\") {\n const handler: RequestHandler = ({ request }) => {\n return render({\n createTemporaryReferenceSet,\n prerender,\n renderToReadableStream,\n request,\n root: (\n <ProvideFrames fetchFrame={fetchFrame} frames={frames} components={components}>\n <Frame src={request.url} />\n </ProvideFrames>\n ),\n });\n };\n\n const localMiddleware =\n typeof components[key] === \"function\"\n ? []\n : ((components[key].middleware ?? []) as Middleware[]);\n\n const action = {\n action: handler,\n handler,\n middleware: [\n reactRedirectsMiddleware(renderToReadableStream),\n ...middleware,\n ...localMiddleware,\n ],\n };\n\n let route = frame.pattern as RoutePattern<string>;\n router.route(\"GET\", route.source, action);\n router.route(\"GET\", route.source + \".rsc\", action);\n router.route(\"POST\", route.source, action);\n router.route(\"POST\", route.source + \".rsc\", action);\n } else {\n mapFrames(\n router,\n frame as Routes,\n { components: components[key] as Components<Routes>, middleware },\n config,\n );\n }\n }\n}\n\nexport class UseServerState {\n formState?: ReactFormState;\n returnValue?: Promise<unknown>;\n temporaryReferences?: unknown;\n status?: number;\n\n constructor(\n formState: ReactFormState | undefined,\n returnValue: Promise<unknown> | undefined,\n temporaryReferences: unknown,\n status: number | undefined,\n ) {\n this.formState = formState;\n this.returnValue = returnValue;\n this.temporaryReferences = temporaryReferences;\n this.status = status;\n }\n}\n\nexport class RedirectState {\n location: string;\n constructor(location: string) {\n this.location = location;\n }\n}\n\nexport function reactRedirectsMiddleware(\n renderToReadableStream: (\n payload: any,\n options?: {\n temporaryReferences?: unknown;\n onError?: (error: unknown) => string | undefined;\n },\n ) => ReadableStream<Uint8Array>,\n): Middleware {\n return async ({ request }, next) => {\n const response = await next();\n const url = new URL(request.url);\n let redirect: string | null;\n if (isReactRequest(url) && (redirect = getRedirect(response))) {\n const payload: Payload = {\n type: \"redirect\",\n redirect,\n };\n return new Response(renderToReadableStream(payload), {\n headers: {\n \"Content-Type\": \"text/x-component; charset=utf-8\",\n },\n });\n }\n };\n}\n\nexport function useServerMiddleware({\n createTemporaryReferenceSet,\n decodeAction,\n decodeFormState,\n decodeReply,\n loadServerAction,\n}: {\n createTemporaryReferenceSet: () => unknown;\n decodeAction: (formData: FormData) => Promise<() => Promise<void>>;\n decodeFormState: (actionResult: unknown, body: FormData) => Promise<ReactFormState | undefined>;\n decodeReply: (body: string | FormData, options?: object) => Promise<unknown[]>;\n loadServerAction: (id: string) => Promise<Function>;\n}): Middleware {\n return async ({ request, set }, next) => {\n let formState: ReactFormState | undefined;\n let returnValue: Promise<unknown> | undefined;\n let temporaryReferences: unknown;\n let actionStatus: number | undefined;\n\n if (request.method === \"POST\") {\n const actionId = request.headers.get(\"x-rsc-action\");\n\n if (actionId) {\n try {\n const contentType = request.headers.get(\"content-type\");\n const body = contentType?.startsWith(\"multipart/form-data\")\n ? await request.formData()\n : await request.text();\n temporaryReferences = createTemporaryReferenceSet();\n const args = await decodeReply(body, { temporaryReferences });\n const action = await loadServerAction(actionId);\n returnValue = action.apply(null, args);\n await returnValue;\n } catch (e) {\n actionStatus = 500;\n returnValue = Promise.reject(e);\n }\n } else {\n try {\n const formData = await request.formData();\n const decodedAction = await decodeAction(formData);\n const result = await decodedAction();\n formState = await decodeFormState(result, formData);\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n set(\n UseServerState,\n new UseServerState(formState, returnValue, temporaryReferences, actionStatus),\n );\n return next();\n };\n}\n\nexport function redirect(locationOrRedirect: string | Response) {\n let location: string | null;\n if (typeof locationOrRedirect === \"string\") {\n location = locationOrRedirect;\n } else {\n location = getRedirect(locationOrRedirect);\n }\n\n if (!location) {\n throw new Error(\"No redirect location provided\");\n }\n\n const ctx = getContext();\n ctx.set(RedirectState, new RedirectState(location));\n}\n\nexport async function render({\n createTemporaryReferenceSet,\n prerender,\n renderToReadableStream,\n request,\n root,\n}: {\n createTemporaryReferenceSet: () => unknown;\n prerender: (body: ReadableStream<Uint8Array>) => Promise<Response>;\n renderToReadableStream: (\n payload: any,\n options?: {\n temporaryReferences: unknown;\n onError: (error: unknown) => string | undefined;\n },\n ) => ReadableStream<Uint8Array>;\n request: Request;\n root: React.ReactNode;\n}) {\n const ctx = getContext();\n let redirect: RedirectState | undefined;\n try {\n redirect = ctx.get(RedirectState);\n } catch {}\n let state: UseServerState | undefined;\n try {\n state = ctx.get(UseServerState);\n } catch {}\n\n try {\n const payload: Payload = redirect\n ? {\n type: \"redirect\",\n redirect: redirect.location,\n returnValue: state?.returnValue,\n }\n : {\n type: \"render\",\n root,\n returnValue: state?.returnValue,\n formState: state?.formState,\n };\n\n const temporaryReferences = state?.temporaryReferences ?? createTemporaryReferenceSet();\n\n const body = renderToReadableStream(payload, {\n temporaryReferences,\n onError(error: unknown) {\n if (error instanceof NotFoundError) {\n return \"404\";\n }\n if (request.signal.aborted) {\n return;\n }\n console.error(error);\n },\n });\n\n const url = new URL(request.url);\n if (isReactRequest(url)) {\n return new Response(body, {\n headers: {\n \"Content-Type\": \"text/x-component; charset=utf-8\",\n },\n });\n }\n\n return await prerender(body);\n } catch (reason) {\n if (reason instanceof Error && reason.name === \"NotFoundError\") {\n return new Response(\"Not Found\", { status: 404 });\n }\n\n if (!request.signal.aborted) {\n console.error(reason);\n }\n\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n}\n\nconst frameCache = cache(\n (): {\n frames?: Record<string, Route>;\n components?: Record<string, React.ComponentType>;\n } => ({}),\n);\n\nexport class NotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\ninterface Routes extends Record<string, Route | Routes> {}\n\ntype Components<R extends Routes> = {\n [K in keyof R]: R[K] extends Routes\n ? Components<R[K]>\n :\n | React.ComponentType\n | {\n middleware?: Middleware[];\n component: React.ComponentType;\n };\n};\n\nexport type ProvideFramesProps<Frames extends Routes> = {\n children?: React.ReactNode;\n components: Components<Frames>;\n fetchFrame: (url: URL, signal: AbortSignal) => Promise<React.ReactNode>;\n frames: Frames;\n};\n\nexport function ProvideFrames<Frames extends Routes>({\n children,\n components,\n fetchFrame,\n frames,\n}: ProvideFramesProps<Frames>) {\n const cache = frameCache();\n\n cache.components = { ...cache.components, ...components };\n cache.frames = { ...cache.frames, ...frames };\n\n return <FetchFrameProvider fetchFrame={fetchFrame}>{children}</FetchFrameProvider>;\n}\n\nexport function Frame({ src }: { src: string }) {\n const cache = frameCache();\n if (!cache.components || !cache.frames) throw new Error(\"No frames provided\");\n\n const url = new URL(src, \"http://react-server-frame/\");\n if (isReactRequest(url)) {\n url.pathname = url.pathname.slice(0, -4);\n }\n\n const Component = match(cache.frames, cache.components, url.href);\n if (!Component) throw new NotFoundError(\"No matching frame found\");\n\n return (\n <ClientFrame src={url.pathname + url.search}>\n <Component />\n </ClientFrame>\n );\n}\n\nfunction match(\n frames: Routes,\n components: Components<Routes>,\n href: string,\n): React.ComponentType | undefined {\n for (const [id, route] of Object.entries(frames)) {\n if (\n typeof (route as Route).pattern?.test === \"function\" &&\n (route as Route).pattern.test(href)\n ) {\n return typeof components?.[id] === \"object\" && components[id].component\n ? components[id].component\n : (components[id] as React.ComponentType);\n } else {\n let matched = match(route as Routes, components?.[id] as unknown as Components<Routes>, href);\n if (matched) return matched;\n }\n }\n}\n\nfunction isReactRequest(url: URL) {\n return url.pathname.endsWith(\".rsc\");\n}\n\nfunction getRedirect(response: Response) {\n if (response.status < 300 || response.status >= 400) return null;\n return response.headers.get(\"Location\");\n}\n"],"mappings":"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"}
|
|
@@ -3,4 +3,5 @@ import * as _$react from "react";
|
|
|
3
3
|
//#region src/vite/fetch-frame.d.ts
|
|
4
4
|
declare function fetchFrame(url: URL, signal: AbortSignal): Promise<string | number | bigint | boolean | Iterable<_$react.ReactNode> | _$react.ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | _$react.ReactPortal | null | undefined>;
|
|
5
5
|
//#endregion
|
|
6
|
-
export { fetchFrame };
|
|
6
|
+
export { fetchFrame };
|
|
7
|
+
//# sourceMappingURL=fetch-frame.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-frame.d.mts","names":[],"sources":["../../src/vite/fetch-frame.ts"],"mappings":";;;iBAQsB,UAAA,CAAW,GAAA,EAAK,GAAA,EAAK,MAAA,EAAQ,WAAA,GAAW,OAAA,sCAAA,QAAA,CAAA,OAAA,CAAA,SAAA,IAAA,OAAA,CAAA,YAAA,mBAAA,OAAA,CAAA,qBAAA,SAAA,OAAA,CAAA,WAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-frame.mjs","names":["_fetchFrame"],"sources":["../../src/vite/fetch-frame.ts"],"sourcesContent":["\"use client\";\n\nimport { fetchFrame as _fetchFrame } from \"../frames.client.tsx\";\n\nif (typeof document !== \"undefined\") {\n void import(\"@vitejs/plugin-rsc/browser\");\n}\n\nexport async function fetchFrame(url: URL, signal: AbortSignal) {\n const { createFromFetch } = await import(\"@vitejs/plugin-rsc/browser\");\n return _fetchFrame(url, signal, createFromFetch);\n}\n"],"mappings":";;;AAIA,IAAI,OAAO,aAAa,YACjB,QAAO;AAGd,eAAsB,WAAW,KAAU,QAAqB;CAC9D,MAAM,EAAE,oBAAoB,MAAM,OAAO;AACzC,QAAOA,aAAY,KAAK,QAAQ,gBAAgB"}
|
package/dist/vite/frames.d.mts
CHANGED
|
@@ -10,4 +10,5 @@ declare function useServerMiddleware(): Middleware;
|
|
|
10
10
|
declare function render(request: Request, root: React.ReactNode): Promise<Response>;
|
|
11
11
|
declare function ProvideFrames(props: Omit<React.ComponentProps<typeof ProvideFrames$1>, "fetchFrame">): _$react_jsx_runtime0.JSX.Element;
|
|
12
12
|
//#endregion
|
|
13
|
-
export { ProvideFrames, mapFrames, render, useServerMiddleware };
|
|
13
|
+
export { ProvideFrames, mapFrames, render, useServerMiddleware };
|
|
14
|
+
//# sourceMappingURL=frames.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frames.d.mts","names":[],"sources":["../../src/vite/frames.tsx"],"mappings":";;;;;;UAoBU,MAAA,SAAe,MAAA,SAAe,KAAA,GAAQ,MAAA;AAAA,iBAEhC,SAAA,gBAAyB,MAAA,CAAA,CACvC,MAAA,EAAQ,UAAA,QAAkB,WAAA,CAAW,MAAA,OACrC,MAAA,EAAQ,UAAA,QAAkB,WAAA,CAAW,MAAA,OACrC,OAAA,EAAS,UAAA,QAAkB,WAAA,CAAW,MAAA;AAAA,iBAkBxB,mBAAA,CAAA,GAAuB,UAAA;AAAA,iBAUjB,MAAA,CAAO,OAAA,EAAS,OAAA,EAAS,IAAA,EAAM,KAAA,CAAM,SAAA,GAAS,OAAA,CAAA,QAAA;AAAA,iBAiBpD,aAAA,CACd,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,eAAA,mBAA8B,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/vite/frames.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frames.mjs","names":["_mapFrames","_useServerMiddleware","_render","_ProvideFrames"],"sources":["../../src/vite/frames.tsx"],"sourcesContent":["import {\n createTemporaryReferenceSet,\n decodeAction,\n decodeFormState,\n decodeReply,\n loadServerAction,\n renderToReadableStream,\n} from \"@vitejs/plugin-rsc/rsc\";\nimport type { Middleware } from \"remix/fetch-router\";\nimport type { Route } from \"remix/fetch-router/routes\";\n\nimport {\n mapFrames as _mapFrames,\n ProvideFrames as _ProvideFrames,\n render as _render,\n useServerMiddleware as _useServerMiddleware,\n} from \"../frames.tsx\";\n\nimport { fetchFrame } from \"./fetch-frame.ts\";\n\ninterface Routes extends Record<string, Route | Routes> {}\n\nexport function mapFrames<Frames extends Routes>(\n router: Parameters<typeof _mapFrames<Frames>>[0],\n frames: Parameters<typeof _mapFrames<Frames>>[1],\n actions: Parameters<typeof _mapFrames<Frames>>[2],\n) {\n return _mapFrames<Frames>(router, frames, actions, {\n createTemporaryReferenceSet,\n fetchFrame,\n prerender: async (...args) => {\n const ssr = await import.meta.viteRsc.import<typeof import(\"./entry.ssr.tsx\")>(\n \"./entry.ssr.tsx\",\n {\n environment: \"ssr\",\n },\n );\n return ssr.prerender(...args);\n },\n renderToReadableStream,\n });\n}\n\nexport function useServerMiddleware(): Middleware {\n return _useServerMiddleware({\n createTemporaryReferenceSet,\n decodeAction,\n decodeFormState,\n decodeReply,\n loadServerAction,\n });\n}\n\nexport async function render(request: Request, root: React.ReactNode) {\n const ssr = await import.meta.viteRsc.import<typeof import(\"./entry.ssr.tsx\")>(\n \"./entry.ssr.tsx\",\n {\n environment: \"ssr\",\n },\n );\n\n return _render({\n createTemporaryReferenceSet,\n prerender: ssr.prerender,\n renderToReadableStream,\n request,\n root,\n });\n}\n\nexport function ProvideFrames(\n props: Omit<React.ComponentProps<typeof _ProvideFrames>, \"fetchFrame\">,\n) {\n return <_ProvideFrames {...props} fetchFrame={fetchFrame} />;\n}\n"],"mappings":";;;;;AAsBA,SAAgB,UACd,QACA,QACA,SACA;AACA,QAAOA,YAAmB,QAAQ,QAAQ,SAAS;EACjD;EACA;EACA,WAAW,OAAO,GAAG,SAAS;AAO5B,WANY,MAAM,OAAO,KAAK,QAAQ,OACpC,mBACA,EACE,aAAa,OACd,CACF,EACU,UAAU,GAAG,KAAK;;EAE/B;EACD,CAAC;;AAGJ,SAAgB,sBAAkC;AAChD,QAAOC,sBAAqB;EAC1B;EACA;EACA;EACA;EACA;EACD,CAAC;;AAGJ,eAAsB,OAAO,SAAkB,MAAuB;AAQpE,QAAOC,SAAQ;EACb;EACA,YATU,MAAM,OAAO,KAAK,QAAQ,OACpC,mBACA,EACE,aAAa,OACd,CACF,EAIgB;EACf;EACA;EACA;EACD,CAAC;;AAGJ,SAAgB,cACd,OACA;AACA,QAAO,oBAACC,iBAAD;EAAgB,GAAI;EAAmB;EAAc,CAAA"}
|
package/dist/vite/plugin.d.mts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../../src/vite/plugin.ts"],"mappings":";;;iBASgB,gBAAA,CAAA;EAAmB;AAAA;EAAiC,KAAA;AAAA"}
|
package/dist/vite/plugin.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.mjs","names":[],"sources":["../../src/vite/plugin.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport * as Vite from \"vite\";\n\nfunction getEntry(file: string) {\n return Vite.normalizePath(path.join(path.dirname(fileURLToPath(import.meta.url)), file));\n}\n\nexport function reactServerFrame({ entry = \"/src/entry.server\" }: { entry?: string } = {}) {\n return {\n name: \"framework\",\n config(userConfig) {\n return Vite.mergeConfig(\n {\n environments: {\n client: {\n build: {\n rolldownOptions: {\n input: {\n index: getEntry(\"entry.client.tsx\"),\n },\n },\n },\n },\n rsc: {\n build: {\n rolldownOptions: {\n input: {\n index: entry,\n },\n },\n },\n },\n ssr: {\n build: {\n rolldownOptions: {\n input: {\n index: getEntry(\"entry.ssr.tsx\"),\n },\n },\n },\n },\n },\n } satisfies Vite.UserConfig,\n userConfig,\n true,\n );\n },\n } satisfies Vite.Plugin;\n}\n"],"mappings":";;;;AAKA,SAAS,SAAS,MAAc;AAC9B,QAAO,KAAK,cAAc,KAAK,KAAK,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EAAE,KAAK,CAAC;;AAG1F,SAAgB,iBAAiB,EAAE,QAAQ,wBAA4C,EAAE,EAAE;AACzF,QAAO;EACL,MAAM;EACN,OAAO,YAAY;AACjB,UAAO,KAAK,YACV,EACE,cAAc;IACZ,QAAQ,EACN,OAAO,EACL,iBAAiB,EACf,OAAO,EACL,OAAO,SAAS,mBAAmB,EACpC,EACF,EACF,EACF;IACD,KAAK,EACH,OAAO,EACL,iBAAiB,EACf,OAAO,EACL,OAAO,OACR,EACF,EACF,EACF;IACD,KAAK,EACH,OAAO,EACL,iBAAiB,EACf,OAAO,EACL,OAAO,SAAS,gBAAgB,EACjC,EACF,EACF,EACF;IACF,EACF,EACD,YACA,KACD;;EAEJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-server-frame",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "A new type of RSC routing.",
|
|
5
5
|
"homepage": "https://github.com/jacob-ebey/react-server-frame#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"react": "canary",
|
|
44
44
|
"react-dom": "canary",
|
|
45
45
|
"react-server-dom-webpack": "canary",
|
|
46
|
-
"remix": "
|
|
46
|
+
"remix": "remix-run/remix#preview/main&path:packages/remix",
|
|
47
47
|
"typescript": "^6.0.2",
|
|
48
48
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
49
49
|
"vite-plus": "latest"
|