@bobtail.software/b-ssr 1.0.30 → 1.0.32

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 @@
1
+ "use strict";var g=Object.create;var S=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var G=(e,r)=>{for(var d in r)S(e,d,{get:r[d],enumerable:!0})},T=(e,r,d,f)=>{if(r&&typeof r=="object"||typeof r=="function")for(let m of O(r))!D.call(e,m)&&m!==d&&S(e,m,{get:()=>r[m],enumerable:!(f=x(r,m))||f.enumerable});return e};var R=(e,r,d)=>(d=e!=null?g(I(e)):{},T(r||!e||!e.__esModule?S(d,"default",{value:e,enumerable:!0}):d,e)),k=e=>T(S({},"__esModule",{value:!0}),e);var C={};G(C,{default:()=>A});module.exports=k(C);var H=require("@fastify/multipart"),v=R(require("fastify-plugin"),1),w=R(require("path"),1),F=async(e,r)=>{if(!e.isMultipart())return r.status(415).send({statusCode:415,error:"Unsupported Media Type",message:"Multipart/form-data expected"});let d=e.parts(),f={};for await(let m of d)if(m.type==="field")f[m.fieldname]=m.value;else{let t=Symbol.for("file-stream");e[t]=m}e.body=f},P=async(e,r)=>{let d=t=>{if(r.errorHandler){let n=r.errorHandler(t);if(n)return n}return{message:"Internal Server Error",statusCode:500}};if(e.hasDecorator("viteInitDone")&&e.viteInitDone)return;if(!e.hasDecorator("multipartErrors"))try{let t=await import("@fastify/multipart");await e.register(t.default)}catch(t){if(t.code!=="FST_ERR_DEC_ALREADY_PRESENT")throw t}let f=process.env.NODE_ENV==="production";if(!f){if(!e.hasDecorator("use"))try{let o=await import("@fastify/middie");await e.register(o.default,{hook:"onRequest"})}catch(o){if(o.code!=="FST_ERR_DEC_ALREADY_PRESENT")throw o}let t=await import("vite"),n=r.viteConfig||{},l=await t.createServer({root:r.root,appType:"custom",...n,server:{hmr:{port:24678},...n.server,middlewareMode:!0}});e.use(l.middlewares),e.hasDecorator("viteServer")||e.decorate("viteServer",l),console.log("\u{1F680} [Fastify-SSR] Vite Dev Server Ready")}e.decorate("viteInitDone",!0);let m=async(t,n,l)=>{try{let o=t.raw.url;if(w.default.extname(o)!==""){n.status(404).send(`File not found: ${o}`);return}let u="";!f&&e.viteServer&&(u=await e.viteServer.transformIndexHtml(o,"<html><head></head><body></body></html>"),u=u.substring(u.indexOf("<head>")+6,u.indexOf("</head>")));let h=f?await import(r.prodEntryFile):await e.viteServer.ssrLoadModule(r.devEntryFile),s=h.render||h.default;if(typeof s!="function")throw new Error(`Entry file ${r.devEntryFile} must export a 'render' function.`);await s({req:t,reply:n,head:u,data:l})}catch(o){e.viteServer?.ssrFixStacktrace(o),console.error("[SSR Error]:",o),n.sent||n.status(500).send("Internal Server Error")}};e.decorate("addRpcRoute",function(t,n){let{handler:l,schema:o,...u}=n,h=`/rpc${t}`,s={...u,schema:o};if(o?.consumes?.includes("multipart/form-data")){let a=s.preValidation;s.preValidation=a?Array.isArray(a)?[F,...a]:[F,a]:F}this.route({method:"POST",url:h,...s,handler:async(a,i)=>{try{let p=await l.call(this,a,i);return i.sent?void 0:p}catch(p){if(console.error(`[RPC Error] ${h}:`,p),!i.sent){let{statusCode:y,message:E}=d(p);i.status(y).send({error:{message:E}})}}}})}),e.decorate("addRenderRoute",function(t,n){let{handler:l,schema:o,...u}=n||{},h=async(s,c,a)=>{try{let i=await l?.call(this,s,c);return a?i:m(s,c,i)}catch(i){if(console.error(`[Render Error] ${t}:`,i),!c.sent){let{statusCode:p,message:y}=d(i);if(a)c.status(p).send({error:{message:y}});else return m(s,c,{ssrError:{statusCode:500,message:"Internal Error"}})}}};if(this.route({method:"GET",url:t,schema:o,...u,handler:(s,c)=>h(s,c,!1)}),t!=="*"&&t!=="/*"){this.route({method:"GET",url:`/loader${t}`,schema:o,...u,handler:(a,i)=>h(a,i,!0)});let s=t.endsWith("/")?"*":"/*",c=`${t}${s}`;this.route({method:"GET",url:c,schema:o,...u,handler:(a,i)=>h(a,i,!1)})}}),e.decorate("addLoaderRoute",function(t,n){let{handler:l,schema:o,...u}=n,h=`/api${t}`;this.route({method:"GET",url:h,schema:o,...u,handler:async(s,c)=>{try{let a=await l.call(this,s,c);return c.sent?void 0:a}catch(a){if(console.error(`[Loader API Error] ${h}:`,a),!c.sent){let{statusCode:i,message:p}=d(a);c.status(i).send({error:{message:p}})}}}})})},A=(0,v.default)(P,{name:"fastify-b-ssr"});
@@ -0,0 +1,56 @@
1
+ import { FastifySchema, RouteGenericInterface, RouteOptions, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
2
+ import { ZodTypeProvider, FastifyPluginAsyncZod } from 'fastify-type-provider-zod';
3
+ import { ViteDevServer, InlineConfig } from 'vite';
4
+ import { ZodType, z } from 'zod';
5
+
6
+ type InferZod<T> = T extends ZodType ? z.infer<T> : unknown;
7
+ type BaseRouteOptions<TGeneric extends RouteGenericInterface> = Omit<RouteOptions<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, TGeneric, unknown, FastifySchema, ZodTypeProvider>, 'handler' | 'method' | 'url' | 'schema'>;
8
+ type AddRpcRouteOptions<TRpcSchema extends FastifySchema> = BaseRouteOptions<RouteGenericForSchema<TRpcSchema>> & {
9
+ handler: (this: FastifyInstance, req: FastifyRequest<RouteGenericForSchema<TRpcSchema>>, reply: FastifyReply<RouteGenericForSchema<TRpcSchema>>) => Promise<unknown> | unknown;
10
+ schema?: TRpcSchema;
11
+ prefix?: string;
12
+ };
13
+ type AddRenderRouteOptions<TSchema extends FastifySchema, TRpcSchema extends FastifySchema> = BaseRouteOptions<RouteGenericForSchema<TSchema>> & {
14
+ handler?: (this: FastifyInstance, req: FastifyRequest<RouteGenericForSchema<TSchema>>, reply: FastifyReply<RouteGenericForSchema<TSchema>>) => Promise<unknown> | unknown;
15
+ prefix?: string;
16
+ };
17
+ type AddLoaderRouteOptions<TSchema extends FastifySchema> = BaseRouteOptions<RouteGenericForSchema<TSchema>> & {
18
+ handler: (this: FastifyInstance, req: FastifyRequest<RouteGenericForSchema<TSchema>>, reply: FastifyReply<RouteGenericForSchema<TSchema>>) => Promise<unknown> | unknown;
19
+ schema?: TSchema;
20
+ prefix?: string;
21
+ };
22
+ interface RouteGenericForSchema<TSchema extends FastifySchema> extends RouteGenericInterface {
23
+ Body: InferZod<TSchema['body']>;
24
+ Querystring: InferZod<TSchema['querystring']>;
25
+ Params: InferZod<TSchema['params']>;
26
+ Headers: InferZod<TSchema['headers']>;
27
+ }
28
+ interface FastifyReactSsrOptions {
29
+ /** Raíz del proyecto (donde está vite.config.ts). Generalmente `process.cwd()` o `__dirname` */
30
+ root: string;
31
+ /** Ruta al archivo de entrada SSR en desarrollo (ej: '/src/entry-ssr-server.tsx') */
32
+ devEntryFile: string;
33
+ /** Ruta absoluta al archivo compilado del servidor SSR en producción */
34
+ prodEntryFile: string;
35
+ /** Configuración extra para Vite (opcional) */
36
+ viteConfig?: InlineConfig;
37
+ /** Manejador de errores personalizado */
38
+ errorHandler?: (error: unknown) => {
39
+ message: string;
40
+ statusCode: number;
41
+ } | null | undefined;
42
+ }
43
+ declare module 'fastify' {
44
+ interface FastifyInstance {
45
+ viteServer?: ViteDevServer;
46
+ viteInitDone?: boolean;
47
+ addRenderRoute: <TSchema extends FastifySchema, TRpcSchema extends FastifySchema = TSchema>(url: string, options?: AddRenderRouteOptions<TSchema, TRpcSchema> & {
48
+ schema?: TSchema;
49
+ }) => void;
50
+ addRpcRoute: <TRpcSchema extends FastifySchema>(url: string, options: AddRpcRouteOptions<TRpcSchema>) => void;
51
+ addLoaderRoute: <TSchema extends FastifySchema>(url: string, options: AddLoaderRouteOptions<TSchema>) => void;
52
+ }
53
+ }
54
+ declare const _default: FastifyPluginAsyncZod<FastifyReactSsrOptions>;
55
+
56
+ export { type AddLoaderRouteOptions, type AddRenderRouteOptions, type AddRpcRouteOptions, type BaseRouteOptions, type FastifyReactSsrOptions, type RouteGenericForSchema, _default as default };
@@ -0,0 +1 @@
1
+ "use strict";var y=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var T=(e,n)=>{for(var t in n)y(e,t,{get:n[t],enumerable:!0})},x=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of m(n))!R.call(e,s)&&s!==t&&y(e,s,{get:()=>n[s],enumerable:!(i=b(n,s))||i.enumerable});return e};var k=e=>x(y({},"__esModule",{value:!0}),e);var E={};T(E,{ApiClientError:()=>g,createClientRpc:()=>C});module.exports=k(E);var g=class extends Error{status;statusText;body;constructor(n,t,i,s){super(n),this.name="ApiClientError",this.status=t,this.statusText=i,this.body=s}};function A(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function O(e,n){let t=e;for(let s in n)if(Object.prototype.hasOwnProperty.call(n,s)){let l=n[s];if(l==null)continue;let u=encodeURIComponent(String(l)),d=new RegExp(`:${A(s)}(\\??)`,"g");t=t.replace(d,u)}t=t.replace(/\/:[a-zA-Z0-9_]+\?/g,"");let i=t.match(/:[a-zA-Z0-9_]+/g);if(i)throw new Error(`Error al compilar la URL. Faltan par\xE1metros requeridos: ${i.join(", ")}`);return t}function C({method:e,url:n,isMultipart:t}){return async i=>{let{params:s={},query:l={},body:u,signal:d}=i,h=O(n,s),w=new URL(h,window.location.origin);l&&Object.entries(l).forEach(([a,r])=>{r!=null&&w.searchParams.append(a,String(r))});let p={method:e,headers:{},credentials:"include",signal:d};if(e==="POST")if(t){let a=new FormData,r=u?{...u}:{};"file"in r&&r.file instanceof File&&(a.append("file",r.file),delete r.file),Object.entries(r).forEach(([c,f])=>{a.append(c,String(f))}),p.body=a}else p.headers["Content-Type"]="application/json",p.headers.Accept="application/json",p.body=JSON.stringify(u||{});let o=await fetch(w.toString(),p);if(!o.ok){let a=`Request failed with status ${o.status} (${o.statusText})`,r=null,c="";try{r=await o.json(),c=r?.error?.message||r?.message}catch{try{c=await o.text(),r=c}catch{}}let f=c?`${a}: ${c}`:a;throw new g(f,o.status,o.statusText,r)}if(!(o.headers.get("Content-Length")==="0"||o.status===204))return o.json()}}0&&(module.exports={ApiClientError,createClientRpc});
@@ -0,0 +1,28 @@
1
+ declare class ApiClientError extends Error {
2
+ readonly status: number;
3
+ readonly statusText: string;
4
+ readonly body: unknown;
5
+ constructor(message: string, status: number, statusText: string, body: unknown);
6
+ }
7
+ type ClientArgs<TArgs extends {
8
+ params?: unknown;
9
+ query?: unknown;
10
+ body?: unknown;
11
+ }> = TArgs & {
12
+ signal?: AbortSignal;
13
+ };
14
+ interface RpcClientOptions {
15
+ url: string;
16
+ method: 'POST' | 'GET';
17
+ isMultipart?: boolean;
18
+ }
19
+ /**
20
+ * Crea una función RPC del lado del cliente que realiza una llamada fetch.
21
+ */
22
+ declare function createClientRpc<TArgs extends {
23
+ params?: unknown;
24
+ query?: unknown;
25
+ body?: unknown;
26
+ }, TReturn>({ method, url, isMultipart }: RpcClientOptions): (args: ClientArgs<TArgs>) => Promise<TReturn>;
27
+
28
+ export { ApiClientError, type RpcClientOptions, createClientRpc };
@@ -0,0 +1 @@
1
+ "use strict";var s=Object.create;var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var R=(t,o)=>{for(var e in o)a(t,e,{get:o[e],enumerable:!0})},m=(t,o,e,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of f(o))!y.call(t,n)&&n!==e&&a(t,n,{get:()=>o[n],enumerable:!(r=u(o,n))||r.enumerable});return t};var _=(t,o,e)=>(e=t!=null?s(l(t)):{},m(o||!t||!t.__esModule?a(e,"default",{value:t,enumerable:!0}):e,t)),S=t=>m(a({},"__esModule",{value:!0}),t);var E={};R(E,{hydrateClient:()=>D});module.exports=S(E);var i=require("@tanstack/react-router/ssr/client"),p=_(require("react"),1),d=require("react-dom/client"),c=require("react/jsx-runtime");function D(t){let o=t(),e=window.__SSR_DATA__;e&&o.update({context:{...o.options.context,loaderData:e}});let r=document.getElementById("root")||document.getElementById("app");r&&!r.innerHTML?(0,d.createRoot)(r).render((0,c.jsx)(p.default.StrictMode,{children:(0,c.jsx)(i.RouterClient,{router:o})})):r&&(0,d.hydrateRoot)(document,(0,c.jsx)(i.RouterClient,{router:o}))}0&&(module.exports={hydrateClient});
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Hidrata la aplicación en el cliente.
3
+ * @param createRouterFn Función que crea el router
4
+ */
5
+ declare function hydrateClient(createRouterFn: () => any): void;
6
+
7
+ export { hydrateClient };
@@ -0,0 +1 @@
1
+ "use strict";var h=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var q=(e,t)=>{for(var r in t)h(e,r,{get:t[r],enumerable:!0})},F=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of p(t))!m.call(e,n)&&n!==r&&h(e,n,{get:()=>t[n],enumerable:!(o=l(t,n))||o.enumerable});return e};var w=e=>F(h({},"__esModule",{value:!0}),e);var v={};q(v,{createServerHandler:()=>g});module.exports=w(v);var a=require("@tanstack/react-router/ssr/server"),y=require("react/jsx-runtime");function x(e){let t=e.protocol,r=e.hostname,o=`${t}://${r}`,n=new URL(e.url,o||"http://localhost:3000").href,i=new Headers;for(let[d,u]of Object.entries(e.headers))u&&i.set(d,Array.isArray(u)?u.join(", "):u);return new Request(n,{method:e.method,headers:i})}function g(e){return async function({req:r,reply:o,head:n,data:i}){let d=x(r),f=await(0,a.createRequestHandler)({request:d,createRouter:()=>{let s=e(),c=s.options.context||{};return s.update({context:{...c,head:n,req:r,reply:o,loaderData:i}}),s}})(({request:s,responseHeaders:c,router:R})=>(0,a.renderRouterToStream)({request:s,responseHeaders:c,router:R,children:(0,y.jsx)(a.RouterServer,{router:R})}));return o.status(f.status),f.headers.forEach((s,c)=>{o.header(c,s)}),o.send(f.body)}}0&&(module.exports={createServerHandler});
@@ -0,0 +1,17 @@
1
+ import { FastifyRequest, FastifyReply } from 'fastify';
2
+
3
+ interface RenderOptions {
4
+ req: FastifyRequest;
5
+ reply: FastifyReply;
6
+ head: string;
7
+ data?: unknown;
8
+ }
9
+ /**
10
+ * Crea el handler de renderizado SSR para TanStack Router.
11
+ *
12
+ * @param createRouterFn Función que devuelve una instancia del Router
13
+ * @returns Una función `render` lista para ser exportada en entry-server.tsx
14
+ */
15
+ declare function createServerHandler(createRouterFn: () => any): ({ req, reply, head, data }: RenderOptions) => Promise<never>;
16
+
17
+ export { type RenderOptions, createServerHandler };