react-server-frame 0.0.4 → 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 +39 -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":";;;;;AAMA,IAAI;AAEJ,SAAgB,qBAAqB,EACnC,iBACA,6BACA,eAKC;AACD,QAAO,OAAO,IAAY,SAAoB;EAC5C,MAAM,MAAM,IAAI,IAAI,OAAO,SAAS,KAAK;AACzC,MAAI,YAAY;EAChB,MAAM,sBAAsB,6BAA6B;EACzD,MAAM,UAAU,MAAM,gBACpB,MAAM,KAAK;GACT,QAAQ;GACR,MAAM,MAAM,YAAY,MAAM,EAAE,qBAAqB,CAAC;GACtD,SAAS,EACP,gBAAgB,IACjB;GACF,CAAC,EACF,EAAE,qBAAqB,CACxB;AACD,8BAA4B;AAC1B,OAAI,QAAQ,SAAS,SACnB,uBAAsB;AACpB,eAAW,QAAQ,QAAQ,QAAQ,CAAC;KACpC;AAEJ,OAAI,QAAQ,SAAS,WACnB,KAAI,OAAO,WACT,6BAA4B;AAC1B,WAAO,WAAW,SAAS,QAAQ,UAAU,EAC3C,SAAS,WACV,CAAC;KACF;OAEF,QAAO,SAAS,OAAO,QAAQ;IAGnC;AACF,SAAO,QAAQ;;;AAInB,IAAI,+BAAe,IAAI,SAAiC;AACxD,SAAS,QAAQ,EAAE,kBAAwD;CACzE,MAAM,CAAC,SAAS,eAAe,SAAS,eAAe;AACvD,cAAa;CAEb,MAAM,UAAU,IAAI,QAAQ;AAE5B,KAAI,QAAQ,SAAS,WACnB,KAAI,OAAO,YAAY;AACrB,MAAI,CAAC,aAAa,IAAI,QAAQ,EAAE;GAC9B,MAAM,UAAU,QAAQ,QACtB,OAAO,WAAW,SAAS,QAAQ,UAAU,EAC3C,SAAS,WACV,CAAC,CAAC,SACJ,CAAC,WAAW,GAAG;AAChB,gBAAa,IAAI,SAAS,QAAQ,QAAQ,QAAQ,CAAC;;AAErD,MAAI,aAAa,IAAI,QAAQ,CAAE;AAC/B,SAAO;QACF;AACL,SAAO,SAAS,OAAO,QAAQ;AAC/B,SAAO;;AAIX,QAAO,QAAQ;;AAGjB,SAAgB,QAAQ,EACtB,iBACA,4BAOC;AACD,0BAAyB,UAAU,CAAC,MACjC,YACC,sBAAsB;AACpB,cACE,UACA,oBAAC,YAAD,EAAA,UACE,oBAAC,SAAD,EAAS,gBAAgB,QAAQ,QAAQ,QAAQ,EAAI,CAAA,EAC1C,CAAA,EACb,EACE,WAAW,QAAQ,WACpB,CACF;GACD,GACH,WAAW,QAAQ,MAAM,0BAA0B,OAAO,CAC5D;CAED,IAAI,uBAAuB,IAAI,iBAAiB;CAChD,eAAe,SAAS,IAAY;EAClC,MAAM,MAAM,IAAI,IAAI,IAAI,OAAO,SAAS,KAAK;AAC7C,MAAI,YAAY;EAEhB,MAAM,iBAAiB,IAAI,iBAAiB;EAC5C,MAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,eAAe,QAAQ,CAAC,CAAC,MAAM,aAAa,CACjF,UACA,SAAS,OAAO,CACjB,CAAC;AAEF,wBAAsB,WAAW,gBAAgB,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC9E,uBAAqB,OAAO;AAC5B,yBAAuB;EAEvB,MAAM,GAAG,YAAY,MAAM;AAC3B,MAAI,CAAC,SAAS,KAAM;EACpB,MAAM,SAAS,SAAS,KAAK,WAAW;AACxC,MAAI;GACF,IAAI,QAAQ,MAAM,OAAO,MAAM;AAC/B,UAAO,CAAC,MAAM,KACZ,SAAQ,MAAM,OAAO,MAAM;YAErB;AACR,UAAO,aAAa;;;AAIxB,QAAO,YAAY,iBAAiB,aAAa,UAAU;AACzD,MAAI,CAAC,MAAM,aACT;AAGF,MAAI,MAAM,cAAc,MAAM,oBAAoB,KAChD;EAGF,MAAM,MAAM,IAAI,IAAI,MAAM,YAAY,IAAI;AAE1C,MAAI,OAAO,SAAS,WAAW,IAAI,QAAQ;AACzC,UAAO,SAAS,OAAO,IAAI;AAC3B;;AAGF,QAAM,UAAU,EACd,MAAM,UAAU;AACd,SAAM,SAAS,MAAM,YAAY,IAAI;KAExC,CAAC;GACF;AAEF,KAAI,OAAO,KAAK,IACd,QAAO,KAAK,IAAI,GAAG,eAAe,MAAM;AACtC,UAAQ,IAAI,qBAAqB,EAAE,KAAK;AACnC,WAAS,SAAS,KAAK;GAC5B"}
|
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,9 +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 = {
|
|
26
|
+
action: handler,
|
|
25
27
|
handler,
|
|
26
|
-
middleware
|
|
28
|
+
middleware: [
|
|
29
|
+
reactRedirectsMiddleware(renderToReadableStream),
|
|
30
|
+
...middleware,
|
|
31
|
+
...localMiddleware
|
|
32
|
+
]
|
|
27
33
|
};
|
|
28
34
|
let route = frame.pattern;
|
|
29
35
|
router.route("GET", route.source, action);
|
|
@@ -53,6 +59,17 @@ var RedirectState = class {
|
|
|
53
59
|
this.location = location;
|
|
54
60
|
}
|
|
55
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
|
+
}
|
|
56
73
|
function useServerMiddleware({ createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction }) {
|
|
57
74
|
return async ({ request, set }, next) => {
|
|
58
75
|
let formState;
|
|
@@ -82,7 +99,11 @@ function useServerMiddleware({ createTemporaryReferenceSet, decodeAction, decode
|
|
|
82
99
|
return next();
|
|
83
100
|
};
|
|
84
101
|
}
|
|
85
|
-
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");
|
|
86
107
|
getContext().set(RedirectState, new RedirectState(location));
|
|
87
108
|
}
|
|
88
109
|
async function render({ createTemporaryReferenceSet, prerender, renderToReadableStream, request, root }) {
|
|
@@ -113,7 +134,7 @@ async function render({ createTemporaryReferenceSet, prerender, renderToReadable
|
|
|
113
134
|
console.error(error);
|
|
114
135
|
}
|
|
115
136
|
});
|
|
116
|
-
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" } });
|
|
117
138
|
return await prerender(body);
|
|
118
139
|
} catch (reason) {
|
|
119
140
|
if (reason instanceof Error && reason.name === "NotFoundError") return new Response("Not Found", { status: 404 });
|
|
@@ -147,7 +168,7 @@ function Frame({ src }) {
|
|
|
147
168
|
const cache = frameCache();
|
|
148
169
|
if (!cache.components || !cache.frames) throw new Error("No frames provided");
|
|
149
170
|
const url = new URL(src, "http://react-server-frame/");
|
|
150
|
-
if (url
|
|
171
|
+
if (isReactRequest(url)) url.pathname = url.pathname.slice(0, -4);
|
|
151
172
|
const Component = match(cache.frames, cache.components, url.href);
|
|
152
173
|
if (!Component) throw new NotFoundError("No matching frame found");
|
|
153
174
|
return /* @__PURE__ */ jsx(ClientFrame, {
|
|
@@ -156,12 +177,20 @@ function Frame({ src }) {
|
|
|
156
177
|
});
|
|
157
178
|
}
|
|
158
179
|
function match(frames, components, href) {
|
|
159
|
-
for (const [id, route] of Object.entries(frames)) if (typeof route.pattern?.test === "function")
|
|
160
|
-
|
|
161
|
-
} 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 {
|
|
162
182
|
let matched = match(route, components?.[id], href);
|
|
163
183
|
if (matched) return matched;
|
|
164
184
|
}
|
|
165
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
|
+
}
|
|
166
193
|
//#endregion
|
|
167
|
-
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"
|