rari 0.7.3 → 0.7.5

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/client.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, T as MetadataResult, _ as GenerateStaticParams, a as LoadingSpinner, b as LoadingEntry, c as createErrorBoundary, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, n as DefaultLoading, o as NotFound, p as AppRouteMatch, r as ErrorBoundary, s as RuntimeClient, t as DefaultError, u as createLoadingBoundary, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry } from "./runtime-client-C2xNyif4.mjs";
1
+ import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, T as MetadataResult, _ as GenerateStaticParams, a as LoadingSpinner, b as LoadingEntry, c as createErrorBoundary, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, n as DefaultLoading, o as NotFound, p as AppRouteMatch, r as ErrorBoundary, s as RuntimeClient, t as DefaultError, u as createLoadingBoundary, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry } from "./runtime-client-BV3qaQrj.mjs";
2
2
  import * as React from "react";
3
3
  import { Component, ErrorInfo, ReactNode } from "react";
4
4
  import * as react_jsx_runtime0 from "react/jsx-runtime";
package/dist/client.mjs CHANGED
@@ -222,7 +222,8 @@ function isExternalUrl(url, currentOrigin) {
222
222
  }
223
223
  function extractPathname(url) {
224
224
  try {
225
- return new URL(url, window.location.origin).pathname;
225
+ const urlObj = new URL(url, window.location.origin);
226
+ return urlObj.pathname + urlObj.hash;
226
227
  } catch {
227
228
  return url;
228
229
  }
@@ -856,8 +857,21 @@ function ClientRouter({ children, initialRoute }) {
856
857
  console.error("[ClientRouter] Invalid navigation target:", href);
857
858
  return;
858
859
  }
859
- const targetPath = normalizePath(href);
860
- if (targetPath === currentRouteRef.current && !options.replace) return;
860
+ const [pathWithoutHash, hash] = href.includes("#") ? href.split("#") : [href, ""];
861
+ const targetPath = normalizePath(pathWithoutHash);
862
+ if (targetPath === currentRouteRef.current && !options.replace) {
863
+ if (hash) {
864
+ const element = document.getElementById(hash);
865
+ if (element) {
866
+ element.scrollIntoView({
867
+ behavior: "smooth",
868
+ block: "start"
869
+ });
870
+ window.history.pushState(window.history.state, "", `${targetPath}#${hash}`);
871
+ }
872
+ }
873
+ return;
874
+ }
861
875
  const existingPending = pendingNavigationsRef.current.get(targetPath);
862
876
  if (existingPending) return existingPending.promise;
863
877
  const routeInfo = await getRouteInfo(targetPath);
@@ -881,8 +895,9 @@ function ClientRouter({ children, initialRoute }) {
881
895
  timestamp: Date.now(),
882
896
  key: historyKey
883
897
  };
884
- if (options.replace) window.history.replaceState(historyState, "", targetPath);
885
- else window.history.pushState(historyState, "", targetPath);
898
+ const urlWithHash = hash ? `${targetPath}#${hash}` : targetPath;
899
+ if (options.replace) window.history.replaceState(historyState, "", urlWithHash);
900
+ else window.history.pushState(historyState, "", urlWithHash);
886
901
  const fetchUrl = (window.location.origin.includes(":5173") ? "http://localhost:3000" : window.location.origin) + targetPath;
887
902
  const response = await fetch(fetchUrl, {
888
903
  headers: { Accept: "text/x-component" },
@@ -891,16 +906,19 @@ function ClientRouter({ children, initialRoute }) {
891
906
  if (!response.ok) throw new Error(`Failed to fetch: ${response.status}`);
892
907
  const finalPath = new URL(response.url).pathname;
893
908
  const actualTargetPath = finalPath !== targetPath ? finalPath : targetPath;
894
- if (finalPath !== targetPath) window.history.replaceState({
895
- route: finalPath,
896
- navigationId,
897
- scrollPosition: {
898
- x: window.scrollX,
899
- y: window.scrollY
900
- },
901
- timestamp: Date.now(),
902
- key: options.historyKey || generateHistoryKey()
903
- }, "", finalPath);
909
+ if (finalPath !== targetPath) {
910
+ const finalUrlWithHash = hash ? `${finalPath}#${hash}` : finalPath;
911
+ window.history.replaceState({
912
+ route: finalPath,
913
+ navigationId,
914
+ scrollPosition: {
915
+ x: window.scrollX,
916
+ y: window.scrollY
917
+ },
918
+ timestamp: Date.now(),
919
+ key: options.historyKey || generateHistoryKey()
920
+ }, "", finalUrlWithHash);
921
+ }
904
922
  if (abortController.signal.aborted) {
905
923
  cleanupAbortedNavigation(actualTargetPath, navigationId);
906
924
  return;
@@ -971,6 +989,17 @@ function ClientRouter({ children, initialRoute }) {
971
989
  if (options.historyKey) requestAnimationFrame(() => {
972
990
  statePreserverRef.current.restoreState(actualTargetPath);
973
991
  });
992
+ else if (hash) requestAnimationFrame(() => {
993
+ const scrollToHash = (attempts = 0) => {
994
+ const element = document.getElementById(hash);
995
+ if (element) element.scrollIntoView({
996
+ behavior: "smooth",
997
+ block: "start"
998
+ });
999
+ else if (attempts < 10) setTimeout(() => scrollToHash(attempts + 1), 50);
1000
+ };
1001
+ scrollToHash();
1002
+ });
974
1003
  }
975
1004
  pendingNavigationsRef.current.delete(targetPath);
976
1005
  processNavigationQueueRef.current?.();
@@ -1030,6 +1059,19 @@ function ClientRouter({ children, initialRoute }) {
1030
1059
  const href = anchor.getAttribute("href");
1031
1060
  if (!href) return;
1032
1061
  if (isExternalUrl(href)) return;
1062
+ if (href.startsWith("#")) {
1063
+ event.preventDefault();
1064
+ const hash = href.slice(1);
1065
+ const element = document.getElementById(hash);
1066
+ if (element) {
1067
+ element.scrollIntoView({
1068
+ behavior: "smooth",
1069
+ block: "start"
1070
+ });
1071
+ window.history.pushState(window.history.state, "", href);
1072
+ }
1073
+ return;
1074
+ }
1033
1075
  event.preventDefault();
1034
1076
  debouncedNavigate(extractPathname(href), { replace: false });
1035
1077
  };
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime1 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/image/constants.d.ts
4
4
  type ImageFormat = 'avif' | 'webp';
@@ -61,6 +61,6 @@ declare function Image({
61
61
  loader,
62
62
  overrideSrc,
63
63
  decoding
64
- }: ImageProps): react_jsx_runtime1.JSX.Element;
64
+ }: ImageProps): react_jsx_runtime0.JSX.Element;
65
65
  //#endregion
66
66
  export { DEFAULT_DEVICE_SIZES, DEFAULT_FORMATS, DEFAULT_IMAGE_SIZES, DEFAULT_MAX_CACHE_SIZE, DEFAULT_MINIMUM_CACHE_TTL, DEFAULT_QUALITY_LEVELS, Image, type ImageProps, type StaticImageData };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-C2xNyif4.mjs";
2
- import { C as ApiRouteHandlers, D as RobotsRule, E as Robots, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-O3u7f8Q_.mjs";
1
+ import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-BV3qaQrj.mjs";
2
+ import { C as ApiRouteHandlers, D as RobotsRule, E as Robots, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-BrjcNDVC.mjs";
3
3
  import "./runtime-executor-NBcG4boA.mjs";
4
4
  export { ApiResponse, ApiRouteHandlers, AppRouteEntry, AppRouteManifest, AppRouteMatch, CookieOptions, ErrorEntry, ErrorProps, GenerateMetadata, GenerateStaticParams, HttpRuntimeClient, LayoutEntry, LayoutProps, LoadingEntry, MetadataResult, NotFoundEntry, PageProps, ProxyConfig, ProxyFunction, ProxyMatcher, ProxyModule, ProxyPluginOptions, ProxyResult, RariFetchEvent, RariRequest, RariResponse, RariURL, Request, RequestCookies, Response, ResponseCookies, type Robots, type RobotsRule, RouteContext, RouteHandler, RouteSegment, RouteSegmentType, RuntimeClient, ServerPropsResult, StaticParamsResult, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { a as rariProxy, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, s as ApiResponse, t as defineRariConfig } from "./vite-DJhQmKAk.mjs";
1
+ import { a as rariProxy, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, s as ApiResponse, t as defineRariConfig } from "./vite-BWd99saK.mjs";
2
2
  import { t as RariRequest } from "./RariRequest-DM6Q4JDB.mjs";
3
3
  import { c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, m as extractServerPropsWithCache, p as extractServerProps, u as clearPropsCache } from "./runtime-client-B7wmvKD3.mjs";
4
- import { t as generateAppRouteManifest } from "./routes-B_KAzmbj.mjs";
4
+ import { t as generateAppRouteManifest } from "./routes-BHZ20uQX.mjs";
5
5
  import "./image-CL9iVW32.mjs";
6
- import "./server-build-DadtZ6wc.mjs";
6
+ import "./server-build-VeqQZBax.mjs";
7
7
 
8
8
  export { ApiResponse, HttpRuntimeClient, RariRequest, RariResponse, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
@@ -4,12 +4,6 @@ import { ReactElement } from "react";
4
4
  interface ImageResponseOptions {
5
5
  width?: number;
6
6
  height?: number;
7
- fonts?: Array<{
8
- name: string;
9
- data: ArrayBuffer;
10
- weight?: number;
11
- style?: 'normal' | 'italic';
12
- }>;
13
7
  }
14
8
  interface ImageResponseSize {
15
9
  width: number;
package/dist/og/index.mjs CHANGED
@@ -6,8 +6,7 @@ var ImageResponse = class {
6
6
  this.element = element;
7
7
  this.options = {
8
8
  width: options.width || 1200,
9
- height: options.height || 630,
10
- fonts: options.fonts || []
9
+ height: options.height || 630
11
10
  };
12
11
  }
13
12
  toJSON() {
@@ -234,11 +234,19 @@ var AppRouteGenerator = class {
234
234
  }
235
235
  sortRoutes(routes) {
236
236
  return routes.sort((a, b) => {
237
- if (!a.isDynamic && b.isDynamic) return -1;
238
- if (a.isDynamic && !b.isDynamic) return 1;
237
+ const getSpecificity = (route) => {
238
+ if (!route.isDynamic) return 0;
239
+ const hasCatchAll = route.segments.some((s) => s.type === "catch-all");
240
+ if (route.segments.some((s) => s.type === "optional-catch-all")) return 3;
241
+ if (hasCatchAll) return 2;
242
+ return 1;
243
+ };
244
+ const aSpec = getSpecificity(a);
245
+ const bSpec = getSpecificity(b);
246
+ if (aSpec !== bSpec) return aSpec - bSpec;
239
247
  const aDepth = a.path.split("/").length;
240
248
  const bDepth = b.path.split("/").length;
241
- if (aDepth !== bDepth) return aDepth - bDepth;
249
+ if (aDepth !== bDepth) return bDepth - aDepth;
242
250
  return a.path.localeCompare(b.path);
243
251
  });
244
252
  }
@@ -0,0 +1,3 @@
1
+ import { t as generateAppRouteManifest } from "./routes-BHZ20uQX.mjs";
2
+
3
+ export { generateAppRouteManifest };
@@ -41,14 +41,6 @@ interface MetadataResult {
41
41
  index?: boolean;
42
42
  follow?: boolean;
43
43
  nocache?: boolean;
44
- googleBot?: {
45
- 'index'?: boolean;
46
- 'follow'?: boolean;
47
- 'noimageindex'?: boolean;
48
- 'max-video-preview'?: number;
49
- 'max-image-preview'?: 'none' | 'standard' | 'large';
50
- 'max-snippet'?: number;
51
- };
52
44
  };
53
45
  icons?: {
54
46
  icon?: Array<{
@@ -80,24 +72,8 @@ interface MetadataResult {
80
72
  statusBarStyle?: 'default' | 'black' | 'black-translucent';
81
73
  capable?: boolean;
82
74
  };
83
- viewport?: {
84
- width?: string | number;
85
- height?: string | number;
86
- initialScale?: number;
87
- maximumScale?: number;
88
- minimumScale?: number;
89
- userScalable?: boolean;
90
- };
91
- verification?: {
92
- google?: string;
93
- yandex?: string;
94
- yahoo?: string;
95
- other?: Record<string, string>;
96
- };
97
- alternates?: {
98
- canonical?: string;
99
- languages?: Record<string, string>;
100
- };
75
+ viewport?: string;
76
+ canonical?: string;
101
77
  }
102
78
  type StaticParamsResult = Array<Record<string, string | string[]>>;
103
79
  declare function extractServerProps(componentPath: string, params: Record<string, string>, searchParams: Record<string, string>): Promise<ServerPropsResult>;
@@ -0,0 +1,3 @@
1
+ import { n as createServerBuildPlugin, r as scanDirectory, t as ServerComponentBuilder } from "./server-build-VeqQZBax.mjs";
2
+
3
+ export { ServerComponentBuilder, scanDirectory };
@@ -54,8 +54,10 @@ var ServerComponentBuilder = class {
54
54
  manifestPath: options.manifestPath || "server/manifest.json",
55
55
  minify: options.minify ?? process.env.NODE_ENV === "production",
56
56
  alias: options.alias || {},
57
+ define: options.define,
57
58
  csp: options.csp,
58
- rateLimit: options.rateLimit
59
+ rateLimit: options.rateLimit,
60
+ spamBlocker: options.spamBlocker
59
61
  };
60
62
  }
61
63
  isServerComponent(filePath) {
@@ -242,7 +244,8 @@ const ${importName} = (props) => {
242
244
  jsxFragment: "React.Fragment",
243
245
  define: {
244
246
  "global": "globalThis",
245
- "process.env.NODE_ENV": "\"production\""
247
+ "process.env.NODE_ENV": "\"production\"",
248
+ ...this.options.define
246
249
  },
247
250
  loader: {
248
251
  ".ts": "ts",
@@ -427,7 +430,8 @@ const ${importName} = (props) => {
427
430
  version: "1.0.0",
428
431
  buildTime: (/* @__PURE__ */ new Date()).toISOString(),
429
432
  csp: this.options.csp,
430
- rateLimit: this.options.rateLimit
433
+ rateLimit: this.options.rateLimit,
434
+ spamBlocker: this.options.spamBlocker
431
435
  };
432
436
  for (const [filePath, component] of this.serverComponents) {
433
437
  const relativePath = path.relative(this.projectRoot, filePath);
@@ -505,7 +509,8 @@ const ${importName} = (props) => {
505
509
  jsxFragment: "React.Fragment",
506
510
  define: {
507
511
  "global": "globalThis",
508
- "process.env.NODE_ENV": "\"production\""
512
+ "process.env.NODE_ENV": "\"production\"",
513
+ ...this.options.define
509
514
  },
510
515
  loader: {
511
516
  ".ts": "ts",
@@ -978,7 +983,8 @@ function registerClientReference(clientReference, id, exportName) {
978
983
  version: "1.0.0",
979
984
  buildTime: (/* @__PURE__ */ new Date()).toISOString(),
980
985
  csp: this.options.csp,
981
- rateLimit: this.options.rateLimit
986
+ rateLimit: this.options.rateLimit,
987
+ spamBlocker: this.options.spamBlocker
982
988
  };
983
989
  this.manifestCache = manifest;
984
990
  }
@@ -1,6 +1,6 @@
1
1
  import { t as __require } from "./chunk-DViRIILg.mjs";
2
2
  import { a as DEFAULT_MAX_CACHE_SIZE, i as DEFAULT_IMAGE_SIZES, n as DEFAULT_DEVICE_SIZES, o as DEFAULT_MINIMUM_CACHE_TTL, r as DEFAULT_FORMATS, s as DEFAULT_QUALITY_LEVELS } from "./image-CL9iVW32.mjs";
3
- import { n as createServerBuildPlugin } from "./server-build-DadtZ6wc.mjs";
3
+ import { n as createServerBuildPlugin } from "./server-build-VeqQZBax.mjs";
4
4
  import fs, { promises, stat, unwatchFile, watch, watchFile } from "node:fs";
5
5
  import * as sp from "node:path";
6
6
  import path, { join, relative, resolve, sep } from "node:path";
@@ -1952,7 +1952,7 @@ function rariRouter(options = {}) {
1952
1952
  const currentRouteFiles = await scanRouteFiles(appDir);
1953
1953
  const currentHash = computeRouteStructureHash(currentRouteFiles);
1954
1954
  if (!forceRegenerate && routeStructureHash === currentHash && cachedManifestContent) return cachedManifestContent;
1955
- const { generateAppRouteManifest } = await import("./routes-BoXHLBse.mjs");
1955
+ const { generateAppRouteManifest } = await import("./routes-DjIf7Qiq.mjs");
1956
1956
  const manifest = await generateAppRouteManifest(appDir, { extensions: opts.extensions });
1957
1957
  const manifestContent = JSON.stringify(manifest, null, 2);
1958
1958
  const outDir = path.resolve(root, opts.outDir);
@@ -2846,14 +2846,15 @@ const ${componentName$1} = registerClientReference(
2846
2846
  let serverComponentBuilder = null;
2847
2847
  const discoverAndRegisterComponents = async () => {
2848
2848
  try {
2849
- const { ServerComponentBuilder, scanDirectory } = await import("./server-build-D005lG4Y.mjs");
2849
+ const { ServerComponentBuilder, scanDirectory } = await import("./server-build-C9oLpeMw.mjs");
2850
2850
  const builder = new ServerComponentBuilder(projectRoot, {
2851
2851
  outDir: "dist",
2852
2852
  serverDir: "server",
2853
2853
  manifestPath: "server/manifest.json",
2854
2854
  alias: resolvedAlias,
2855
2855
  csp: options.csp,
2856
- rateLimit: options.rateLimit
2856
+ rateLimit: options.rateLimit,
2857
+ spamBlocker: options.spamBlocker
2857
2858
  });
2858
2859
  serverComponentBuilder = builder;
2859
2860
  if (!hmrCoordinator && serverComponentBuilder) {
@@ -3010,14 +3011,15 @@ const ${componentName$1} = registerClientReference(
3010
3011
  const handleServerComponentHMR = async (filePath) => {
3011
3012
  try {
3012
3013
  if (!isServerComponent(filePath)) return;
3013
- const { ServerComponentBuilder } = await import("./server-build-D005lG4Y.mjs");
3014
+ const { ServerComponentBuilder } = await import("./server-build-C9oLpeMw.mjs");
3014
3015
  const builder = new ServerComponentBuilder(projectRoot, {
3015
3016
  outDir: "dist",
3016
3017
  serverDir: "server",
3017
3018
  manifestPath: "server/manifest.json",
3018
3019
  alias: resolvedAlias,
3019
3020
  csp: options.csp,
3020
- rateLimit: options.rateLimit
3021
+ rateLimit: options.rateLimit,
3022
+ spamBlocker: options.spamBlocker
3021
3023
  });
3022
3024
  builder.addServerComponent(filePath);
3023
3025
  const components = await builder.getTransformedComponentsForDevelopment();
@@ -3321,7 +3323,8 @@ globalThis['~clientComponentPaths']["${ext.path}"] = "${exportName}";`;
3321
3323
  }, createServerBuildPlugin({
3322
3324
  ...options.serverBuild,
3323
3325
  csp: options.csp,
3324
- rateLimit: options.rateLimit
3326
+ rateLimit: options.rateLimit,
3327
+ spamBlocker: options.spamBlocker
3325
3328
  })];
3326
3329
  if (options.proxy !== false) plugins.push(rariProxy(options.proxy || {}));
3327
3330
  if (options.router !== false) plugins.push(rariRouter(options.router || {}));
@@ -1,4 +1,4 @@
1
- import { f as AppRouteManifest } from "./runtime-client-C2xNyif4.mjs";
1
+ import { f as AppRouteManifest } from "./runtime-client-BV3qaQrj.mjs";
2
2
  import { Plugin, UserConfig } from "rolldown-vite";
3
3
 
4
4
  //#region src/types/metadata-route.d.ts
@@ -212,6 +212,7 @@ interface ServerBuildOptions {
212
212
  manifestPath?: string;
213
213
  minify?: boolean;
214
214
  alias?: Record<string, string>;
215
+ define?: Record<string, string>;
215
216
  csp?: {
216
217
  scriptSrc?: string[];
217
218
  styleSrc?: string[];
@@ -226,6 +227,9 @@ interface ServerBuildOptions {
226
227
  burstSize?: number;
227
228
  revalidateRequestsPerMinute?: number;
228
229
  };
230
+ spamBlocker?: {
231
+ enabled?: boolean;
232
+ };
229
233
  }
230
234
  //#endregion
231
235
  //#region src/vite/index.d.ts
@@ -272,6 +276,9 @@ interface RariOptions {
272
276
  burstSize?: number;
273
277
  revalidateRequestsPerMinute?: number;
274
278
  };
279
+ spamBlocker?: {
280
+ enabled?: boolean;
281
+ };
275
282
  }
276
283
  declare function defineRariOptions(config: RariOptions): RariOptions;
277
284
  declare function rari(options?: RariOptions): Plugin[];
package/dist/vite.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-C2xNyif4.mjs";
2
- import { C as ApiRouteHandlers, D as RobotsRule, E as Robots, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-O3u7f8Q_.mjs";
1
+ import { A as extractMetadata, C as RouteSegment, D as StaticParamsResult, E as ServerPropsResult, M as extractServerPropsWithCache, N as extractStaticParams, O as clearPropsCache, P as hasServerSideDataFetching, S as PageProps, T as MetadataResult, _ as GenerateStaticParams, b as LoadingEntry, d as AppRouteEntry, f as AppRouteManifest, g as GenerateMetadata, h as ErrorProps, i as HttpRuntimeClient, j as extractServerProps, k as clearPropsCacheForComponent, l as createHttpRuntimeClient, m as ErrorEntry, p as AppRouteMatch, s as RuntimeClient, v as LayoutEntry, w as RouteSegmentType, x as NotFoundEntry, y as LayoutProps } from "./runtime-client-BV3qaQrj.mjs";
2
+ import { C as ApiRouteHandlers, D as RobotsRule, E as Robots, S as ApiResponse, T as RouteHandler, _ as ProxyResult, a as rari, b as RequestCookies, c as ProxyPluginOptions, d as RariRequest, f as CookieOptions, g as ProxyModule, h as ProxyMatcher, i as defineRariOptions, l as rariProxy, m as ProxyFunction, n as Response, o as rariRouter, p as ProxyConfig, r as defineRariConfig, s as generateAppRouteManifest, t as Request, u as RariResponse, v as RariFetchEvent, w as RouteContext, x as ResponseCookies, y as RariURL } from "./vite-BrjcNDVC.mjs";
3
3
  import "./runtime-executor-NBcG4boA.mjs";
4
4
  export { ApiResponse, ApiRouteHandlers, AppRouteEntry, AppRouteManifest, AppRouteMatch, CookieOptions, ErrorEntry, ErrorProps, GenerateMetadata, GenerateStaticParams, HttpRuntimeClient, LayoutEntry, LayoutProps, LoadingEntry, MetadataResult, NotFoundEntry, PageProps, ProxyConfig, ProxyFunction, ProxyMatcher, ProxyModule, ProxyPluginOptions, ProxyResult, RariFetchEvent, RariRequest, RariResponse, RariURL, Request, RequestCookies, Response, ResponseCookies, Robots, RobotsRule, RouteContext, RouteHandler, RouteSegment, RouteSegmentType, RuntimeClient, ServerPropsResult, StaticParamsResult, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
package/dist/vite.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { a as rariProxy, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, s as ApiResponse, t as defineRariConfig } from "./vite-DJhQmKAk.mjs";
1
+ import { a as rariProxy, i as rariRouter, n as defineRariOptions, o as RariResponse, r as rari, s as ApiResponse, t as defineRariConfig } from "./vite-BWd99saK.mjs";
2
2
  import { t as RariRequest } from "./RariRequest-DM6Q4JDB.mjs";
3
3
  import { c as createHttpRuntimeClient, d as clearPropsCacheForComponent, f as extractMetadata, g as hasServerSideDataFetching, h as extractStaticParams, i as HttpRuntimeClient, m as extractServerPropsWithCache, p as extractServerProps, u as clearPropsCache } from "./runtime-client-B7wmvKD3.mjs";
4
- import { t as generateAppRouteManifest } from "./routes-B_KAzmbj.mjs";
4
+ import { t as generateAppRouteManifest } from "./routes-BHZ20uQX.mjs";
5
5
  import "./image-CL9iVW32.mjs";
6
- import "./server-build-DadtZ6wc.mjs";
6
+ import "./server-build-VeqQZBax.mjs";
7
7
 
8
8
  export { ApiResponse, HttpRuntimeClient, RariRequest, RariResponse, clearPropsCache, clearPropsCacheForComponent, createHttpRuntimeClient, defineRariConfig, defineRariOptions, extractMetadata, extractServerProps, extractServerPropsWithCache, extractStaticParams, generateAppRouteManifest, hasServerSideDataFetching, rari, rariProxy, rariRouter };
package/package.json CHANGED
@@ -1,112 +1,111 @@
1
1
  {
2
2
  "name": "rari",
3
- "type": "module",
4
- "version": "0.7.3",
5
- "description": "Runtime Accelerated Rendering Infrastructure (Rari)",
3
+ "version": "0.7.5",
6
4
  "author": "Ryan Skinner",
7
- "license": "MIT",
8
- "homepage": "https://github.com/rari-build/rari#readme",
9
- "repository": {
10
- "type": "git",
11
- "url": "https://github.com/rari-build/rari.git",
12
- "directory": "packages/rari"
5
+ "bin": {
6
+ "rari": "./dist/cli.mjs"
13
7
  },
14
8
  "bugs": {
15
9
  "url": "https://github.com/rari-build/rari/issues"
16
10
  },
17
- "keywords": [
18
- "react",
19
- "server-components",
20
- "rsc",
21
- "rust",
22
- "vite",
23
- "framework",
24
- "performance",
25
- "ssr",
26
- "typescript",
27
- "deno",
28
- "v8",
29
- "streaming",
30
- "fast",
31
- "zero-config",
32
- "full-stack",
33
- "web-framework"
34
- ],
11
+ "dependencies": {
12
+ "acorn": "^8.15.0",
13
+ "esbuild": "^0.27.2",
14
+ "picocolors": "^1.1.1"
15
+ },
16
+ "description": "Runtime Accelerated Rendering Infrastructure (Rari)",
17
+ "devDependencies": {
18
+ "@types/node": "^25.0.9",
19
+ "@types/react": "^19.2.8",
20
+ "@typescript/native-preview": "^7.0.0-dev.20260118.1",
21
+ "chokidar": "^5.0.0",
22
+ "oxlint": "^1.39.0",
23
+ "rolldown-vite": "^7.3.1",
24
+ "tsdown": "^0.18.4"
25
+ },
26
+ "engines": {
27
+ "node": ">=20.0.0"
28
+ },
35
29
  "exports": {
36
30
  ".": {
37
- "types": "./dist/vite.d.mts",
38
31
  "browser": "./dist/client.mjs",
32
+ "default": "./dist/vite.mjs",
39
33
  "node": "./dist/vite.mjs",
40
- "default": "./dist/vite.mjs"
34
+ "types": "./dist/vite.d.mts"
41
35
  },
42
36
  "./client": {
43
- "types": "./dist/client.d.mts",
44
- "default": "./dist/client.mjs"
45
- },
46
- "./vite": {
47
- "types": "./dist/vite.d.mts",
48
- "default": "./dist/vite.mjs"
37
+ "default": "./dist/client.mjs",
38
+ "types": "./dist/client.d.mts"
49
39
  },
50
40
  "./image": {
51
- "types": "./dist/image/index.d.mts",
52
- "default": "./dist/image/index.mjs"
53
- },
54
- "./og": {
55
- "types": "./dist/og/index.d.mts",
56
- "default": "./dist/og/index.mjs"
41
+ "default": "./dist/image/index.mjs",
42
+ "types": "./dist/image/index.d.mts"
57
43
  },
58
44
  "./mdx": {
59
- "types": "./dist/mdx.d.mts",
60
- "default": "./dist/mdx.mjs"
45
+ "default": "./dist/mdx.mjs",
46
+ "types": "./dist/mdx.d.mts"
47
+ },
48
+ "./og": {
49
+ "default": "./dist/og/index.mjs",
50
+ "types": "./dist/og/index.d.mts"
61
51
  },
52
+ "./package.json": "./package.json",
62
53
  "./runtime/actions": {
63
- "types": "./dist/runtime/actions.d.mts",
64
- "default": "./dist/runtime/actions.mjs"
54
+ "default": "./dist/runtime/actions.mjs",
55
+ "types": "./dist/runtime/actions.d.mts"
65
56
  },
66
- "./package.json": "./package.json"
67
- },
68
- "types": "dist/index.d.mts",
69
- "bin": {
70
- "rari": "./dist/cli.mjs"
57
+ "./vite": {
58
+ "default": "./dist/vite.mjs",
59
+ "types": "./dist/vite.d.mts"
60
+ }
71
61
  },
72
62
  "files": [
73
63
  "dist",
74
64
  "src"
75
65
  ],
76
- "engines": {
77
- "node": ">=20.0.0"
78
- },
79
- "scripts": {
80
- "build": "pnpm clean && pnpm typecheck && tsdown",
81
- "typecheck": "tsgo",
82
- "clean": "rm -rf dist",
83
- "lint": "oxlint && eslint",
84
- "lint:fix": "oxlint --fix && eslint --fix"
66
+ "homepage": "https://github.com/rari-build/rari#readme",
67
+ "keywords": [
68
+ "react",
69
+ "server-components",
70
+ "rsc",
71
+ "rust",
72
+ "vite",
73
+ "framework",
74
+ "performance",
75
+ "ssr",
76
+ "typescript",
77
+ "deno",
78
+ "v8",
79
+ "streaming",
80
+ "fast",
81
+ "zero-config",
82
+ "full-stack",
83
+ "web-framework"
84
+ ],
85
+ "license": "MIT",
86
+ "optionalDependencies": {
87
+ "rari-darwin-arm64": "0.7.5",
88
+ "rari-darwin-x64": "0.7.5",
89
+ "rari-linux-arm64": "0.7.5",
90
+ "rari-linux-x64": "0.7.5",
91
+ "rari-win32-x64": "0.7.5"
85
92
  },
86
93
  "peerDependencies": {
87
94
  "react": "^19.0.0",
88
95
  "react-dom": "^19.0.0"
89
96
  },
90
- "dependencies": {
91
- "acorn": "^8.15.0",
92
- "esbuild": "^0.27.2",
93
- "picocolors": "^1.1.1"
97
+ "repository": {
98
+ "directory": "packages/rari",
99
+ "type": "git",
100
+ "url": "https://github.com/rari-build/rari.git"
94
101
  },
95
- "optionalDependencies": {
96
- "rari-darwin-arm64": "0.7.3",
97
- "rari-darwin-x64": "0.7.3",
98
- "rari-linux-arm64": "0.7.3",
99
- "rari-linux-x64": "0.7.3",
100
- "rari-win32-x64": "0.7.3"
102
+ "scripts": {
103
+ "build": "pnpm clean && pnpm typecheck && tsdown",
104
+ "clean": "rm -rf dist",
105
+ "lint": "oxlint",
106
+ "lint:fix": "oxlint --fix",
107
+ "typecheck": "tsgo"
101
108
  },
102
- "devDependencies": {
103
- "@types/node": "^25.0.8",
104
- "@types/react": "^19.2.8",
105
- "@typescript/native-preview": "^7.0.0-dev.20260114.1",
106
- "chokidar": "^5.0.0",
107
- "eslint": "^9.39.2",
108
- "oxlint": "^1.39.0",
109
- "rolldown-vite": "^7.3.1",
110
- "tsdown": "^0.18.4"
111
- }
109
+ "type": "module",
110
+ "types": "dist/index.d.mts"
112
111
  }
@@ -3,12 +3,6 @@ import type { ReactElement } from 'react'
3
3
  export interface ImageResponseOptions {
4
4
  width?: number
5
5
  height?: number
6
- fonts?: Array<{
7
- name: string
8
- data: ArrayBuffer
9
- weight?: number
10
- style?: 'normal' | 'italic'
11
- }>
12
6
  }
13
7
 
14
8
  export interface ImageResponseSize {
@@ -25,7 +19,6 @@ export class ImageResponse {
25
19
  this.options = {
26
20
  width: options.width || 1200,
27
21
  height: options.height || 630,
28
- fonts: options.fonts || [],
29
22
  }
30
23
  }
31
24
 
@@ -292,10 +292,19 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
292
292
  return
293
293
  }
294
294
 
295
- const targetPath = normalizePath(href)
296
-
297
- if (targetPath === currentRouteRef.current && !options.replace)
295
+ const [pathWithoutHash, hash] = href.includes('#') ? href.split('#') : [href, '']
296
+ const targetPath = normalizePath(pathWithoutHash)
297
+
298
+ if (targetPath === currentRouteRef.current && !options.replace) {
299
+ if (hash) {
300
+ const element = document.getElementById(hash)
301
+ if (element) {
302
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' })
303
+ window.history.pushState(window.history.state, '', `${targetPath}#${hash}`)
304
+ }
305
+ }
298
306
  return
307
+ }
299
308
 
300
309
  const existingPending = pendingNavigationsRef.current.get(targetPath)
301
310
  if (existingPending)
@@ -326,18 +335,20 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
326
335
  key: historyKey,
327
336
  }
328
337
 
338
+ const urlWithHash = hash ? `${targetPath}#${hash}` : targetPath
339
+
329
340
  if (options.replace) {
330
341
  window.history.replaceState(
331
342
  historyState,
332
343
  '',
333
- targetPath,
344
+ urlWithHash,
334
345
  )
335
346
  }
336
347
  else {
337
348
  window.history.pushState(
338
349
  historyState,
339
350
  '',
340
- targetPath,
351
+ urlWithHash,
341
352
  )
342
353
  }
343
354
 
@@ -359,6 +370,7 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
359
370
  const actualTargetPath = finalPath !== targetPath ? finalPath : targetPath
360
371
 
361
372
  if (finalPath !== targetPath) {
373
+ const finalUrlWithHash = hash ? `${finalPath}#${hash}` : finalPath
362
374
  window.history.replaceState(
363
375
  {
364
376
  route: finalPath,
@@ -368,7 +380,7 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
368
380
  key: options.historyKey || generateHistoryKey(),
369
381
  },
370
382
  '',
371
- finalPath,
383
+ finalUrlWithHash,
372
384
  )
373
385
  }
374
386
 
@@ -482,6 +494,20 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
482
494
  statePreserverRef.current.restoreState(actualTargetPath)
483
495
  })
484
496
  }
497
+ else if (hash) {
498
+ requestAnimationFrame(() => {
499
+ const scrollToHash = (attempts = 0) => {
500
+ const element = document.getElementById(hash)
501
+ if (element) {
502
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' })
503
+ }
504
+ else if (attempts < 10) {
505
+ setTimeout(() => scrollToHash(attempts + 1), 50)
506
+ }
507
+ }
508
+ scrollToHash()
509
+ })
510
+ }
485
511
  }
486
512
 
487
513
  pendingNavigationsRef.current.delete(targetPath)
@@ -589,6 +615,17 @@ export function ClientRouter({ children, initialRoute }: ClientRouterProps) {
589
615
  if (isExternalUrl(href))
590
616
  return
591
617
 
618
+ if (href.startsWith('#')) {
619
+ event.preventDefault()
620
+ const hash = href.slice(1)
621
+ const element = document.getElementById(hash)
622
+ if (element) {
623
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' })
624
+ window.history.pushState(window.history.state, '', href)
625
+ }
626
+ return
627
+ }
628
+
592
629
  event.preventDefault()
593
630
 
594
631
  const pathname = extractPathname(href)
@@ -151,7 +151,7 @@ export function isExternalUrl(url: string, currentOrigin?: string): boolean {
151
151
  export function extractPathname(url: string): string {
152
152
  try {
153
153
  const urlObj = new URL(url, window.location.origin)
154
- return urlObj.pathname
154
+ return urlObj.pathname + urlObj.hash
155
155
  }
156
156
  catch {
157
157
  return url
@@ -38,14 +38,6 @@ export interface MetadataResult {
38
38
  index?: boolean
39
39
  follow?: boolean
40
40
  nocache?: boolean
41
- googleBot?: {
42
- 'index'?: boolean
43
- 'follow'?: boolean
44
- 'noimageindex'?: boolean
45
- 'max-video-preview'?: number
46
- 'max-image-preview'?: 'none' | 'standard' | 'large'
47
- 'max-snippet'?: number
48
- }
49
41
  }
50
42
  icons?: {
51
43
  icon?: Array<{
@@ -77,24 +69,8 @@ export interface MetadataResult {
77
69
  statusBarStyle?: 'default' | 'black' | 'black-translucent'
78
70
  capable?: boolean
79
71
  }
80
- viewport?: {
81
- width?: string | number
82
- height?: string | number
83
- initialScale?: number
84
- maximumScale?: number
85
- minimumScale?: number
86
- userScalable?: boolean
87
- }
88
- verification?: {
89
- google?: string
90
- yandex?: string
91
- yahoo?: string
92
- other?: Record<string, string>
93
- }
94
- alternates?: {
95
- canonical?: string
96
- languages?: Record<string, string>
97
- }
72
+ viewport?: string
73
+ canonical?: string
98
74
  }
99
75
 
100
76
  export type StaticParamsResult = Array<Record<string, string | string[]>>
@@ -226,12 +202,14 @@ export function mergeMetadata(
226
202
  merged.icons = { ...parentMetadata.icons, ...childMetadata.icons }
227
203
  if (childMetadata.manifest !== undefined)
228
204
  merged.manifest = childMetadata.manifest
205
+ if (childMetadata.themeColor !== undefined)
206
+ merged.themeColor = childMetadata.themeColor
207
+ if (childMetadata.appleWebApp !== undefined)
208
+ merged.appleWebApp = { ...parentMetadata.appleWebApp, ...childMetadata.appleWebApp }
229
209
  if (childMetadata.viewport !== undefined)
230
- merged.viewport = { ...parentMetadata.viewport, ...childMetadata.viewport }
231
- if (childMetadata.verification !== undefined)
232
- merged.verification = { ...parentMetadata.verification, ...childMetadata.verification }
233
- if (childMetadata.alternates !== undefined)
234
- merged.alternates = { ...parentMetadata.alternates, ...childMetadata.alternates }
210
+ merged.viewport = childMetadata.viewport
211
+ if (childMetadata.canonical !== undefined)
212
+ merged.canonical = childMetadata.canonical
235
213
 
236
214
  return merged
237
215
  }
@@ -357,15 +357,30 @@ class AppRouteGenerator {
357
357
 
358
358
  private sortRoutes(routes: AppRouteEntry[]): AppRouteEntry[] {
359
359
  return routes.sort((a, b) => {
360
- if (!a.isDynamic && b.isDynamic)
361
- return -1
362
- if (a.isDynamic && !b.isDynamic)
360
+ const getSpecificity = (route: AppRouteEntry): number => {
361
+ if (!route.isDynamic)
362
+ return 0
363
+
364
+ const hasCatchAll = route.segments.some(s => s.type === 'catch-all')
365
+ const hasOptionalCatchAll = route.segments.some(s => s.type === 'optional-catch-all')
366
+
367
+ if (hasOptionalCatchAll)
368
+ return 3
369
+ if (hasCatchAll)
370
+ return 2
363
371
  return 1
372
+ }
373
+
374
+ const aSpec = getSpecificity(a)
375
+ const bSpec = getSpecificity(b)
376
+
377
+ if (aSpec !== bSpec)
378
+ return aSpec - bSpec
364
379
 
365
380
  const aDepth = a.path.split('/').length
366
381
  const bDepth = b.path.split('/').length
367
382
  if (aDepth !== bDepth)
368
- return aDepth - bDepth
383
+ return bDepth - aDepth
369
384
 
370
385
  return a.path.localeCompare(b.path)
371
386
  })
@@ -7,11 +7,38 @@ import { AppRouterProvider } from 'virtual:app-router-provider'
7
7
  import { createFromReadableStream } from 'virtual:react-server-dom-rari-client'
8
8
  import 'virtual:rsc-integration'
9
9
 
10
+ function getClientComponent(id) {
11
+ if (globalThis['~clientComponents'][id]?.component)
12
+ return globalThis['~clientComponents'][id].component
13
+
14
+ if (id.includes('#')) {
15
+ const [path, exportName] = id.split('#')
16
+ const componentId = globalThis['~clientComponentPaths'][path]
17
+ if (componentId && globalThis['~clientComponents'][componentId]) {
18
+ const componentInfo = globalThis['~clientComponents'][componentId]
19
+ if (exportName === 'default' || !exportName)
20
+ return componentInfo.component
21
+ }
22
+
23
+ const normalizedPath = path.startsWith('./') ? path.slice(2) : path
24
+ const componentIdByNormalizedPath = globalThis['~clientComponentPaths'][normalizedPath]
25
+ if (componentIdByNormalizedPath && globalThis['~clientComponents'][componentIdByNormalizedPath])
26
+ return globalThis['~clientComponents'][componentIdByNormalizedPath].component
27
+ }
28
+
29
+ const componentId = globalThis['~clientComponentNames'][id]
30
+ if (componentId && globalThis['~clientComponents'][componentId])
31
+ return globalThis['~clientComponents'][componentId].component
32
+
33
+ return null
34
+ }
35
+
10
36
  if (typeof globalThis['~rari'] === 'undefined') {
11
37
  globalThis['~rari'] = {}
12
38
  }
13
39
  globalThis['~rari'].AppRouterProvider = AppRouterProvider
14
40
  globalThis['~rari'].ClientRouter = ClientRouter
41
+ globalThis['~rari'].getClientComponent = getClientComponent
15
42
 
16
43
  // CLIENT_COMPONENT_IMPORTS_PLACEHOLDER
17
44
 
@@ -138,6 +165,34 @@ export async function renderApp() {
138
165
 
139
166
  setupPartialHydration()
140
167
 
168
+ if (hasServerRenderedContent && !payloadScript && !hasBufferedRows) {
169
+ const clientComponentElements = document.querySelectorAll('[data-client-component]')
170
+ if (clientComponentElements.length > 0) {
171
+ clientComponentElements.forEach((element) => {
172
+ const componentId = element.getAttribute('data-client-component')
173
+ const propsJson = element.getAttribute('data-props')
174
+
175
+ if (!componentId)
176
+ return
177
+
178
+ try {
179
+ const Component = getClientComponent(componentId)
180
+ if (!Component)
181
+ return
182
+
183
+ const props = propsJson ? JSON.parse(propsJson) : {}
184
+ element.innerHTML = ''
185
+ const root = createRoot(element)
186
+ root.render(React.createElement(Component, props))
187
+ }
188
+ catch (error) {
189
+ console.error(`[Rari] Failed to hydrate client component ${componentId}:`, error)
190
+ }
191
+ })
192
+ }
193
+ return
194
+ }
195
+
141
196
  if (hasServerRenderedContent && hasBufferedRows && !payloadScript) {
142
197
  const hasBoundaries = document.querySelectorAll('[data-boundary-id]').length > 0
143
198
 
@@ -152,10 +207,6 @@ export async function renderApp() {
152
207
  }
153
208
  }
154
209
 
155
- if (hasServerRenderedContent && !payloadScript && !hasBufferedRows) {
156
- return
157
- }
158
-
159
210
  try {
160
211
  let element
161
212
  const isFullDocument = false
package/src/vite/index.ts CHANGED
@@ -65,6 +65,9 @@ interface RariOptions {
65
65
  burstSize?: number
66
66
  revalidateRequestsPerMinute?: number
67
67
  }
68
+ spamBlocker?: {
69
+ enabled?: boolean
70
+ }
68
71
  }
69
72
 
70
73
  const DEFAULT_IMAGE_CONFIG = {
@@ -905,6 +908,7 @@ const ${componentName} = registerClientReference(
905
908
  alias: resolvedAlias,
906
909
  csp: options.csp,
907
910
  rateLimit: options.rateLimit,
911
+ spamBlocker: options.spamBlocker,
908
912
  })
909
913
 
910
914
  serverComponentBuilder = builder
@@ -1182,6 +1186,7 @@ const ${componentName} = registerClientReference(
1182
1186
  alias: resolvedAlias,
1183
1187
  csp: options.csp,
1184
1188
  rateLimit: options.rateLimit,
1189
+ spamBlocker: options.spamBlocker,
1185
1190
  })
1186
1191
 
1187
1192
  builder.addServerComponent(filePath)
@@ -1676,6 +1681,7 @@ globalThis['~clientComponentPaths']["${ext.path}"] = "${exportName}";`
1676
1681
  ...options.serverBuild,
1677
1682
  csp: options.csp,
1678
1683
  rateLimit: options.rateLimit,
1684
+ spamBlocker: options.spamBlocker,
1679
1685
  })
1680
1686
 
1681
1687
  const plugins: Plugin[] = [mainPlugin, serverBuildPlugin]
@@ -71,6 +71,9 @@ interface ServerComponentManifest {
71
71
  burstSize?: number
72
72
  revalidateRequestsPerMinute?: number
73
73
  }
74
+ spamBlocker?: {
75
+ enabled?: boolean
76
+ }
74
77
  }
75
78
 
76
79
  export interface ServerBuildOptions {
@@ -79,6 +82,7 @@ export interface ServerBuildOptions {
79
82
  manifestPath?: string
80
83
  minify?: boolean
81
84
  alias?: Record<string, string>
85
+ define?: Record<string, string>
82
86
  csp?: {
83
87
  scriptSrc?: string[]
84
88
  styleSrc?: string[]
@@ -93,6 +97,9 @@ export interface ServerBuildOptions {
93
97
  burstSize?: number
94
98
  revalidateRequestsPerMinute?: number
95
99
  }
100
+ spamBlocker?: {
101
+ enabled?: boolean
102
+ }
96
103
  }
97
104
 
98
105
  export interface ComponentRebuildResult {
@@ -102,9 +109,11 @@ export interface ComponentRebuildResult {
102
109
  error?: string
103
110
  }
104
111
 
105
- type ResolvedServerBuildOptions = Required<Omit<ServerBuildOptions, 'csp' | 'rateLimit'>> & {
112
+ type ResolvedServerBuildOptions = Required<Omit<ServerBuildOptions, 'csp' | 'rateLimit' | 'spamBlocker' | 'define'>> & {
106
113
  csp?: ServerBuildOptions['csp']
107
114
  rateLimit?: ServerBuildOptions['rateLimit']
115
+ spamBlocker?: ServerBuildOptions['spamBlocker']
116
+ define?: ServerBuildOptions['define']
108
117
  }
109
118
 
110
119
  export class ServerComponentBuilder {
@@ -149,8 +158,10 @@ export class ServerComponentBuilder {
149
158
  manifestPath: options.manifestPath || 'server/manifest.json',
150
159
  minify: options.minify ?? process.env.NODE_ENV === 'production',
151
160
  alias: options.alias || {},
161
+ define: options.define,
152
162
  csp: options.csp,
153
163
  rateLimit: options.rateLimit,
164
+ spamBlocker: options.spamBlocker,
154
165
  }
155
166
  }
156
167
 
@@ -435,6 +446,7 @@ const ${importName} = (props) => {
435
446
  define: {
436
447
  'global': 'globalThis',
437
448
  'process.env.NODE_ENV': '"production"',
449
+ ...this.options.define,
438
450
  },
439
451
  loader: {
440
452
  '.ts': 'ts',
@@ -639,6 +651,7 @@ const ${importName} = (props) => {
639
651
  buildTime: new Date().toISOString(),
640
652
  csp: this.options.csp,
641
653
  rateLimit: this.options.rateLimit,
654
+ spamBlocker: this.options.spamBlocker,
642
655
  }
643
656
 
644
657
  for (const [filePath, component] of this.serverComponents) {
@@ -754,6 +767,7 @@ const ${importName} = (props) => {
754
767
  define: {
755
768
  'global': 'globalThis',
756
769
  'process.env.NODE_ENV': '"production"',
770
+ ...this.options.define,
757
771
  },
758
772
  loader: {
759
773
  '.ts': 'ts',
@@ -1432,6 +1446,7 @@ function registerClientReference(clientReference, id, exportName) {
1432
1446
  buildTime: new Date().toISOString(),
1433
1447
  csp: this.options.csp,
1434
1448
  rateLimit: this.options.rateLimit,
1449
+ spamBlocker: this.options.spamBlocker,
1435
1450
  }
1436
1451
  this.manifestCache = manifest
1437
1452
  }
@@ -1,3 +0,0 @@
1
- import { t as generateAppRouteManifest } from "./routes-B_KAzmbj.mjs";
2
-
3
- export { generateAppRouteManifest };
@@ -1,3 +0,0 @@
1
- import { n as createServerBuildPlugin, r as scanDirectory, t as ServerComponentBuilder } from "./server-build-DadtZ6wc.mjs";
2
-
3
- export { ServerComponentBuilder, scanDirectory };