rari 0.2.22 → 0.2.23

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { HttpRuntimeClient, Link, Navigate, Outlet, RouteComponent, RouterProvider, Routes, buildSearchString, buildUrl, createHttpRuntimeClient, extractParamNames, findMatchingRoute, getRoutePriority, isDynamicRoute, isPathActive, joinPaths, normalizePathname, parseSearchParams, parseUrl, useNavigation, useParams, usePathname, useRoute, useRouter, useSearchParams, withRouter } from "./runtime-client-BXoadxa8.js";
2
- import { FileRouteGenerator, convertFilePatternToRoutePattern, createRouteManifest, defineRariConfig, defineRariOptions, generateFileRoutes, loadRouteManifest, rari, rariRouter, validateRoutes, watchFileRoutes } from "./server-BK7rNurU.js";
3
- import "./server-build-BM8_GFF5.js";
2
+ import { FileRouteGenerator, convertFilePatternToRoutePattern, createRouteManifest, defineRariConfig, defineRariOptions, generateFileRoutes, loadRouteManifest, rari, rariRouter, validateRoutes, watchFileRoutes } from "./server-C3POnIbO.js";
3
+ import "./server-build-DeJfuJb8.js";
4
4
 
5
5
  export { FileRouteGenerator, HttpRuntimeClient, Link, Navigate, Outlet, RouteComponent as Route, RouterProvider, Routes, buildSearchString, buildUrl, convertFilePatternToRoutePattern, createHttpRuntimeClient, createRouteManifest, defineRariConfig, defineRariOptions, extractParamNames, findMatchingRoute, generateFileRoutes, getRoutePriority, isDynamicRoute, isPathActive, joinPaths, loadRouteManifest, normalizePathname, parseSearchParams, parseUrl, rari, rariRouter, useNavigation, useParams, usePathname, useRoute, useRouter, useSearchParams, validateRoutes, watchFileRoutes, withRouter };
@@ -1,6 +1,6 @@
1
1
  import { __commonJS, __require, __toESM } from "./chunk-BLXvPPr8.js";
2
2
  import { analyzeFilePath } from "./runtime-client-BXoadxa8.js";
3
- import { createServerBuildPlugin } from "./server-build-BM8_GFF5.js";
3
+ import { createServerBuildPlugin } from "./server-build-DeJfuJb8.js";
4
4
  import fs, { promises } from "node:fs";
5
5
  import path from "node:path";
6
6
  import process$1 from "node:process";
@@ -5693,7 +5693,7 @@ function rari(options = {}) {
5693
5693
  const serverDirectives = ["'use server'", "\"use server\""];
5694
5694
  const trimmedCode = code.trim();
5695
5695
  const hasServerDirective = serverDirectives.some((directive) => trimmedCode.startsWith(directive) || code.includes(directive));
5696
- const isInFunctionsDir = filePath.includes("/functions/") || filePath.includes("\\functions\\");
5696
+ const isInFunctionsDir = filePath.includes("/functions/") || filePath.includes("\\\\functions\\\\");
5697
5697
  const hasServerFunctionSignature = (code.includes("export async function") || code.includes("export function")) && code.includes("'use server'");
5698
5698
  if (hasServerDirective || isInFunctionsDir && hasServerFunctionSignature) return true;
5699
5699
  return false;
@@ -5980,6 +5980,11 @@ if (import.meta.hot) {
5980
5980
  import.meta.hot.accept();
5981
5981
  }
5982
5982
 
5983
+ if (typeof globalThis !== 'undefined') {
5984
+ globalThis.__rari_server_components = globalThis.__rari_server_components || new Set();
5985
+ globalThis.__rari_server_components.add(${JSON.stringify(id)});
5986
+ }
5987
+
5983
5988
  ${clientTransformedCode}`;
5984
5989
  return clientTransformedCode;
5985
5990
  }
@@ -6065,14 +6070,35 @@ const ${componentName$1} = registerClientReference(
6065
6070
  const srcDir = path.join(projectRoot, "src");
6066
6071
  const discoverAndRegisterComponents = async () => {
6067
6072
  try {
6068
- const { ServerComponentBuilder, scanDirectory } = await import("./server-build-DcbOtG3e.js");
6073
+ const { ServerComponentBuilder, scanDirectory } = await import("./server-build-Cs2pfA52.js");
6069
6074
  const builder = new ServerComponentBuilder(projectRoot, {
6070
6075
  outDir: "temp",
6071
6076
  serverDir: "server",
6072
6077
  manifestPath: "server-manifest.json"
6073
6078
  });
6074
6079
  const srcDir$1 = path.join(projectRoot, "src");
6075
- if (fs.existsSync(srcDir$1)) scanDirectory(srcDir$1, builder);
6080
+ const serverComponentPaths = [];
6081
+ if (fs.existsSync(srcDir$1)) {
6082
+ const collectServerComponents = (dir) => {
6083
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
6084
+ for (const entry of entries) {
6085
+ const fullPath = path.join(dir, entry.name);
6086
+ if (entry.isDirectory()) collectServerComponents(fullPath);
6087
+ else if (entry.isFile() && /\.(?:tsx?|jsx?)$/.test(entry.name)) try {
6088
+ if (isServerComponent(fullPath)) serverComponentPaths.push(fullPath);
6089
+ } catch (error) {
6090
+ console.warn(`[RARI] Error checking ${fullPath}:`, error);
6091
+ }
6092
+ }
6093
+ };
6094
+ collectServerComponents(srcDir$1);
6095
+ scanDirectory(srcDir$1, builder);
6096
+ }
6097
+ if (serverComponentPaths.length > 0) server.ws.send({
6098
+ type: "custom",
6099
+ event: "rari:server-components-registry",
6100
+ data: { serverComponents: serverComponentPaths }
6101
+ });
6076
6102
  const components = await builder.getTransformedComponentsForDevelopment();
6077
6103
  const serverPort = process$1.env.SERVER_PORT ? Number(process$1.env.SERVER_PORT) : Number(process$1.env.PORT || process$1.env.RSC_PORT || 3e3);
6078
6104
  const baseUrl = `http://localhost:${serverPort}`;
@@ -6200,7 +6226,7 @@ const ${componentName$1} = registerClientReference(
6200
6226
  };
6201
6227
  const handleServerComponentHMR = async (filePath) => {
6202
6228
  try {
6203
- const { ServerComponentBuilder } = await import("./server-build-DcbOtG3e.js");
6229
+ const { ServerComponentBuilder } = await import("./server-build-Cs2pfA52.js");
6204
6230
  const builder = new ServerComponentBuilder(projectRoot, {
6205
6231
  outDir: "temp",
6206
6232
  serverDir: "server",
@@ -6236,8 +6262,14 @@ const ${componentName$1} = registerClientReference(
6236
6262
  startRustServer();
6237
6263
  server.watcher.on("change", async (filePath) => {
6238
6264
  if (/\.(?:tsx?|jsx?)$/.test(filePath)) componentTypeCache.delete(filePath);
6239
- if (/\.(?:tsx?|jsx?)$/.test(filePath) && filePath.includes(srcDir)) if (isServerComponent(filePath)) await handleServerComponentHMR(filePath);
6240
- else setTimeout(discoverAndRegisterComponents, 1e3);
6265
+ if (/\.(?:tsx?|jsx?)$/.test(filePath) && filePath.includes(srcDir)) if (isServerComponent(filePath)) {
6266
+ server.ws.send({
6267
+ type: "custom",
6268
+ event: "rari:register-server-component",
6269
+ data: { filePath }
6270
+ });
6271
+ await handleServerComponentHMR(filePath);
6272
+ } else setTimeout(discoverAndRegisterComponents, 1e3);
6241
6273
  });
6242
6274
  server.middlewares.use("/api/vite/hmr-transform", async (req, res) => {
6243
6275
  if (req.method !== "POST") {
@@ -6591,7 +6623,9 @@ class RscClient {
6591
6623
  }
6592
6624
 
6593
6625
  async fetchServerComponent(componentId, props = {}) {
6594
- const cacheKey = componentId + ':' + JSON.stringify(props);
6626
+ const hmrCounter = (typeof window !== 'undefined' && window.__rscRefreshCounters && window.__rscRefreshCounters[componentId]) || 0;
6627
+ const cacheKey = componentId + ':' + JSON.stringify(props) + ':hmr:' + hmrCounter;
6628
+
6595
6629
 
6596
6630
  if (this.componentCache.has(cacheKey)) {
6597
6631
  return this.componentCache.get(cacheKey);
@@ -6837,14 +6871,15 @@ class RscClient {
6837
6871
  buffered = lines[lines.length - 1];
6838
6872
 
6839
6873
  for (const line of completeLines) {
6840
- if (!line.trim()) continue;
6874
+ if (!line.trim()) continue;
6875
+
6876
+ try {
6877
+ const colonIndex = line.indexOf(':');
6878
+ if (colonIndex === -1) continue;
6841
6879
 
6842
- try {
6843
- const colonIndex = line.indexOf(':');
6844
- if (colonIndex === -1) continue;
6880
+ const rowId = line.substring(0, colonIndex);
6881
+ const content = line.substring(colonIndex + 1);
6845
6882
 
6846
- const rowId = line.substring(0, colonIndex);
6847
- const content = line.substring(colonIndex + 1);
6848
6883
 
6849
6884
  if (content.includes('STREAM_COMPLETE')) {
6850
6885
  isComplete = true;
@@ -7379,6 +7414,9 @@ function createServerComponentWrapper(componentName, importPath) {
7379
7414
  const handleRscInvalidate = (event) => {
7380
7415
  const detail = event.detail;
7381
7416
  if (detail && detail.filePath && isServerComponent(detail.filePath)) {
7417
+
7418
+ rscClient.clearCache();
7419
+
7382
7420
  if (typeof window !== 'undefined') {
7383
7421
  window.__rscRefreshCounters[componentName] = (window.__rscRefreshCounters[componentName] || 0) + 1;
7384
7422
  setMountKey(window.__rscRefreshCounters[componentName]);
@@ -7414,17 +7452,48 @@ export const fetchServerComponent = (componentId, props) =>
7414
7452
 
7415
7453
  // Helper function to check if a file is a server component (client-side)
7416
7454
  function isServerComponent(filePath) {
7417
- // Simple client-side check based on file path patterns
7418
- return filePath && (
7419
- filePath.includes('ServerWithClient') ||
7420
- filePath.includes('server') ||
7421
- filePath.includes('Server')
7422
- );
7455
+ if (!filePath) {
7456
+ return false;
7457
+ }
7458
+
7459
+ try {
7460
+ if (typeof globalThis !== 'undefined' && globalThis.__rari_server_components) {
7461
+ return globalThis.__rari_server_components.has(filePath);
7462
+ }
7463
+
7464
+ const hasServerPattern = (
7465
+ filePath.includes('/functions/') ||
7466
+ filePath.includes('\\\\functions\\\\')
7467
+ );
7468
+
7469
+ return hasServerPattern;
7470
+ } catch (error) {
7471
+ console.warn('Error checking if file is server component:', error);
7472
+ return false;
7473
+ }
7423
7474
  }
7424
7475
 
7425
- // HMR support for RSC cache invalidation
7426
7476
  if (import.meta.hot) {
7427
- // Listen for Vite's beforeFullReload event for server components
7477
+ import.meta.hot.on('rari:register-server-component', (data) => {
7478
+ if (data?.filePath) {
7479
+ if (typeof globalThis !== 'undefined') {
7480
+ globalThis.__rari_server_components = globalThis.__rari_server_components || new Set();
7481
+ globalThis.__rari_server_components.add(data.filePath);
7482
+ }
7483
+ }
7484
+ });
7485
+
7486
+ import.meta.hot.on('rari:server-components-registry', (data) => {
7487
+ if (data?.serverComponents && Array.isArray(data.serverComponents)) {
7488
+ if (typeof globalThis !== 'undefined') {
7489
+ globalThis.__rari_server_components = globalThis.__rari_server_components || new Set();
7490
+ data.serverComponents.forEach(path => {
7491
+ globalThis.__rari_server_components.add(path);
7492
+ });
7493
+ }
7494
+ }
7495
+ });
7496
+
7428
7497
  import.meta.hot.on('vite:beforeFullReload', async (data) => {
7429
7498
  if (data?.path && isServerComponent(data.path)) {
7430
7499
  // Immediately invalidate cache and trigger re-registration before reload
@@ -7432,13 +7501,17 @@ if (import.meta.hot) {
7432
7501
  }
7433
7502
  });
7434
7503
 
7504
+ import.meta.hot.on('rari:server-component-updated', async (data) => {
7505
+ if (data?.path && isServerComponent(data.path)) {
7506
+ await invalidateRscCache({ filePath: data.path, forceReload: false });
7507
+ }
7508
+ });
7509
+
7435
7510
 
7436
7511
 
7437
- // Helper function to invalidate RSC cache and trigger component re-registration
7438
7512
  async function invalidateRscCache(data) {
7439
7513
  const filePath = data?.filePath || data;
7440
7514
 
7441
- // Wait for server to be ready
7442
7515
  const waitForServerReady = async () => {
7443
7516
  for (let i = 0; i < 20; i++) { // Try for up to 2 seconds
7444
7517
  try {
@@ -7535,9 +7608,11 @@ ${registrations.join("\n")}
7535
7608
  }
7536
7609
  },
7537
7610
  handleHotUpdate({ file, server }) {
7538
- if (/\.(?:tsx?|jsx?)$/.test(file) && isServerComponent(file)) {
7539
- server.hot.send("vite:beforeFullReload", {
7540
- type: "full-reload",
7611
+ const isReactFile = /\.(?:tsx?|jsx?)$/.test(file);
7612
+ const isServerComp = isServerComponent(file);
7613
+ if (isReactFile && isServerComp) {
7614
+ server.hot.send("rari:server-component-updated", {
7615
+ type: "rari-hmr",
7541
7616
  path: file
7542
7617
  });
7543
7618
  return [];
@@ -0,0 +1,3 @@
1
+ import { ServerComponentBuilder, createServerBuildPlugin, scanDirectory } from "./server-build-DeJfuJb8.js";
2
+
3
+ export { ServerComponentBuilder, scanDirectory };
@@ -32,7 +32,7 @@ var ServerComponentBuilder = class {
32
32
  ];
33
33
  const trimmedCode = code.trim();
34
34
  const hasServerDirective = serverDirectives.some((directive) => trimmedCode.startsWith(directive) || code.includes(directive));
35
- const isInFunctionsDir = filePath.includes("/functions/") || filePath.includes("\\functions\\");
35
+ const isInFunctionsDir = filePath.includes("/functions/") || filePath.includes("\\\\functions\\\\");
36
36
  const hasServerFunctionSignature = (code.includes("export async function") || code.includes("export function")) && code.includes("'use server'");
37
37
  const hasNodeImports = code.includes("from 'node:") || code.includes("from \"node:") || code.includes("from 'fs'") || code.includes("from \"fs\"") || code.includes("from 'path'") || code.includes("from \"path\"");
38
38
  const hasAsyncDefaultExport = /export\s+default\s+async\s+function/.test(code);
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { HttpRuntimeClient, Link, Navigate, Outlet, RouteComponent, RouterProvider, Routes, buildSearchString, buildUrl, createHttpRuntimeClient, extractParamNames, findMatchingRoute, getRoutePriority, isDynamicRoute, isPathActive, joinPaths, normalizePathname, parseSearchParams, parseUrl, useNavigation, useParams, usePathname, useRoute, useRouter, useSearchParams, withRouter } from "./runtime-client-BXoadxa8.js";
2
- import { FileRouteGenerator, convertFilePatternToRoutePattern, createRouteManifest, defineRariConfig, defineRariOptions, generateFileRoutes, loadRouteManifest, rari, rariRouter, validateRoutes, watchFileRoutes } from "./server-BK7rNurU.js";
3
- import "./server-build-BM8_GFF5.js";
2
+ import { FileRouteGenerator, convertFilePatternToRoutePattern, createRouteManifest, defineRariConfig, defineRariOptions, generateFileRoutes, loadRouteManifest, rari, rariRouter, validateRoutes, watchFileRoutes } from "./server-C3POnIbO.js";
3
+ import "./server-build-DeJfuJb8.js";
4
4
 
5
5
  export { FileRouteGenerator, HttpRuntimeClient, Link, Navigate, Outlet, RouteComponent as Route, RouterProvider, Routes, buildSearchString, buildUrl, convertFilePatternToRoutePattern, createHttpRuntimeClient, createRouteManifest, defineRariConfig, defineRariOptions, extractParamNames, findMatchingRoute, generateFileRoutes, getRoutePriority, isDynamicRoute, isPathActive, joinPaths, loadRouteManifest, normalizePathname, parseSearchParams, parseUrl, rari, rariRouter, useNavigation, useParams, usePathname, useRoute, useRouter, useSearchParams, validateRoutes, watchFileRoutes, withRouter };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rari",
3
3
  "type": "module",
4
- "version": "0.2.22",
4
+ "version": "0.2.23",
5
5
  "description": "Runtime Accelerated Rendering Infrastructure (Rari)",
6
6
  "author": "Ryan Skinner",
7
7
  "license": "MIT",
@@ -77,11 +77,11 @@
77
77
  "picocolors": "^1.1.1"
78
78
  },
79
79
  "optionalDependencies": {
80
- "rari-darwin-arm64": "0.2.15",
81
- "rari-darwin-x64": "0.2.15",
82
- "rari-linux-arm64": "0.2.15",
83
- "rari-linux-x64": "0.2.15",
84
- "rari-win32-x64": "0.2.15"
80
+ "rari-darwin-arm64": "0.2.16",
81
+ "rari-darwin-x64": "0.2.16",
82
+ "rari-linux-arm64": "0.2.16",
83
+ "rari-linux-x64": "0.2.16",
84
+ "rari-win32-x64": "0.2.16"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@types/node": "^24.3.1",
package/src/vite/index.ts CHANGED
@@ -162,7 +162,7 @@ export function rari(options: RariOptions = {}): Plugin[] {
162
162
  )
163
163
 
164
164
  const isInFunctionsDir
165
- = filePath.includes('/functions/') || filePath.includes('\\functions\\')
165
+ = filePath.includes('/functions/') || filePath.includes('\\\\functions\\\\')
166
166
  const hasServerFunctionSignature
167
167
  = (code.includes('export async function')
168
168
  || code.includes('export function'))
@@ -655,6 +655,11 @@ if (import.meta.hot) {
655
655
  import.meta.hot.accept();
656
656
  }
657
657
 
658
+ if (typeof globalThis !== 'undefined') {
659
+ globalThis.__rari_server_components = globalThis.__rari_server_components || new Set();
660
+ globalThis.__rari_server_components.add(${JSON.stringify(id)});
661
+ }
662
+
658
663
  ${clientTransformedCode}`
659
664
  }
660
665
 
@@ -843,11 +848,41 @@ const ${componentName} = registerClientReference(
843
848
  })
844
849
 
845
850
  const srcDir = path.join(projectRoot, 'src')
851
+ const serverComponentPaths: string[] = []
846
852
 
847
853
  if (fs.existsSync(srcDir)) {
854
+ const collectServerComponents = (dir: string) => {
855
+ const entries = fs.readdirSync(dir, { withFileTypes: true })
856
+ for (const entry of entries) {
857
+ const fullPath = path.join(dir, entry.name)
858
+ if (entry.isDirectory()) {
859
+ collectServerComponents(fullPath)
860
+ }
861
+ else if (entry.isFile() && /\.(?:tsx?|jsx?)$/.test(entry.name)) {
862
+ try {
863
+ if (isServerComponent(fullPath)) {
864
+ serverComponentPaths.push(fullPath)
865
+ }
866
+ }
867
+ catch (error) {
868
+ console.warn(`[RARI] Error checking ${fullPath}:`, error)
869
+ }
870
+ }
871
+ }
872
+ }
873
+
874
+ collectServerComponents(srcDir)
848
875
  scanDirectory(srcDir, builder)
849
876
  }
850
877
 
878
+ if (serverComponentPaths.length > 0) {
879
+ server.ws.send({
880
+ type: 'custom',
881
+ event: 'rari:server-components-registry',
882
+ data: { serverComponents: serverComponentPaths },
883
+ })
884
+ }
885
+
851
886
  const components
852
887
  = await builder.getTransformedComponentsForDevelopment()
853
888
 
@@ -1128,6 +1163,11 @@ const ${componentName} = registerClientReference(
1128
1163
 
1129
1164
  if (/\.(?:tsx?|jsx?)$/.test(filePath) && filePath.includes(srcDir)) {
1130
1165
  if (isServerComponent(filePath)) {
1166
+ server.ws.send({
1167
+ type: 'custom',
1168
+ event: 'rari:register-server-component',
1169
+ data: { filePath },
1170
+ })
1131
1171
  await handleServerComponentHMR(filePath)
1132
1172
  }
1133
1173
  else {
@@ -1517,7 +1557,9 @@ class RscClient {
1517
1557
  }
1518
1558
 
1519
1559
  async fetchServerComponent(componentId, props = {}) {
1520
- const cacheKey = componentId + ':' + JSON.stringify(props);
1560
+ const hmrCounter = (typeof window !== 'undefined' && window.__rscRefreshCounters && window.__rscRefreshCounters[componentId]) || 0;
1561
+ const cacheKey = componentId + ':' + JSON.stringify(props) + ':hmr:' + hmrCounter;
1562
+
1521
1563
 
1522
1564
  if (this.componentCache.has(cacheKey)) {
1523
1565
  return this.componentCache.get(cacheKey);
@@ -1763,14 +1805,15 @@ class RscClient {
1763
1805
  buffered = lines[lines.length - 1];
1764
1806
 
1765
1807
  for (const line of completeLines) {
1766
- if (!line.trim()) continue;
1808
+ if (!line.trim()) continue;
1767
1809
 
1768
- try {
1769
- const colonIndex = line.indexOf(':');
1770
- if (colonIndex === -1) continue;
1810
+ try {
1811
+ const colonIndex = line.indexOf(':');
1812
+ if (colonIndex === -1) continue;
1813
+
1814
+ const rowId = line.substring(0, colonIndex);
1815
+ const content = line.substring(colonIndex + 1);
1771
1816
 
1772
- const rowId = line.substring(0, colonIndex);
1773
- const content = line.substring(colonIndex + 1);
1774
1817
 
1775
1818
  if (content.includes('STREAM_COMPLETE')) {
1776
1819
  isComplete = true;
@@ -2305,6 +2348,9 @@ function createServerComponentWrapper(componentName, importPath) {
2305
2348
  const handleRscInvalidate = (event) => {
2306
2349
  const detail = event.detail;
2307
2350
  if (detail && detail.filePath && isServerComponent(detail.filePath)) {
2351
+
2352
+ rscClient.clearCache();
2353
+
2308
2354
  if (typeof window !== 'undefined') {
2309
2355
  window.__rscRefreshCounters[componentName] = (window.__rscRefreshCounters[componentName] || 0) + 1;
2310
2356
  setMountKey(window.__rscRefreshCounters[componentName]);
@@ -2340,17 +2386,48 @@ export const fetchServerComponent = (componentId, props) =>
2340
2386
 
2341
2387
  // Helper function to check if a file is a server component (client-side)
2342
2388
  function isServerComponent(filePath) {
2343
- // Simple client-side check based on file path patterns
2344
- return filePath && (
2345
- filePath.includes('ServerWithClient') ||
2346
- filePath.includes('server') ||
2347
- filePath.includes('Server')
2348
- );
2389
+ if (!filePath) {
2390
+ return false;
2391
+ }
2392
+
2393
+ try {
2394
+ if (typeof globalThis !== 'undefined' && globalThis.__rari_server_components) {
2395
+ return globalThis.__rari_server_components.has(filePath);
2396
+ }
2397
+
2398
+ const hasServerPattern = (
2399
+ filePath.includes('/functions/') ||
2400
+ filePath.includes('\\\\functions\\\\')
2401
+ );
2402
+
2403
+ return hasServerPattern;
2404
+ } catch (error) {
2405
+ console.warn('Error checking if file is server component:', error);
2406
+ return false;
2407
+ }
2349
2408
  }
2350
2409
 
2351
- // HMR support for RSC cache invalidation
2352
2410
  if (import.meta.hot) {
2353
- // Listen for Vite's beforeFullReload event for server components
2411
+ import.meta.hot.on('rari:register-server-component', (data) => {
2412
+ if (data?.filePath) {
2413
+ if (typeof globalThis !== 'undefined') {
2414
+ globalThis.__rari_server_components = globalThis.__rari_server_components || new Set();
2415
+ globalThis.__rari_server_components.add(data.filePath);
2416
+ }
2417
+ }
2418
+ });
2419
+
2420
+ import.meta.hot.on('rari:server-components-registry', (data) => {
2421
+ if (data?.serverComponents && Array.isArray(data.serverComponents)) {
2422
+ if (typeof globalThis !== 'undefined') {
2423
+ globalThis.__rari_server_components = globalThis.__rari_server_components || new Set();
2424
+ data.serverComponents.forEach(path => {
2425
+ globalThis.__rari_server_components.add(path);
2426
+ });
2427
+ }
2428
+ }
2429
+ });
2430
+
2354
2431
  import.meta.hot.on('vite:beforeFullReload', async (data) => {
2355
2432
  if (data?.path && isServerComponent(data.path)) {
2356
2433
  // Immediately invalidate cache and trigger re-registration before reload
@@ -2358,13 +2435,17 @@ if (import.meta.hot) {
2358
2435
  }
2359
2436
  });
2360
2437
 
2438
+ import.meta.hot.on('rari:server-component-updated', async (data) => {
2439
+ if (data?.path && isServerComponent(data.path)) {
2440
+ await invalidateRscCache({ filePath: data.path, forceReload: false });
2441
+ }
2442
+ });
2443
+
2361
2444
 
2362
2445
 
2363
- // Helper function to invalidate RSC cache and trigger component re-registration
2364
2446
  async function invalidateRscCache(data) {
2365
2447
  const filePath = data?.filePath || data;
2366
2448
 
2367
- // Wait for server to be ready
2368
2449
  const waitForServerReady = async () => {
2369
2450
  for (let i = 0; i < 20; i++) { // Try for up to 2 seconds
2370
2451
  try {
@@ -2473,9 +2554,12 @@ ${registrations.join('\n')}
2473
2554
  },
2474
2555
 
2475
2556
  handleHotUpdate({ file, server }) {
2476
- if (/\.(?:tsx?|jsx?)$/.test(file) && isServerComponent(file)) {
2477
- server.hot.send('vite:beforeFullReload', {
2478
- type: 'full-reload',
2557
+ const isReactFile = /\.(?:tsx?|jsx?)$/.test(file)
2558
+ const isServerComp = isServerComponent(file)
2559
+
2560
+ if (isReactFile && isServerComp) {
2561
+ server.hot.send('rari:server-component-updated', {
2562
+ type: 'rari-hmr',
2479
2563
  path: file,
2480
2564
  })
2481
2565
  return []
@@ -80,7 +80,7 @@ export class ServerComponentBuilder {
80
80
  )
81
81
 
82
82
  const isInFunctionsDir
83
- = filePath.includes('/functions/') || filePath.includes('\\functions\\')
83
+ = filePath.includes('/functions/') || filePath.includes('\\\\functions\\\\')
84
84
  const hasServerFunctionSignature
85
85
  = (code.includes('export async function')
86
86
  || code.includes('export function'))
@@ -1,3 +0,0 @@
1
- import { ServerComponentBuilder, createServerBuildPlugin, scanDirectory } from "./server-build-BM8_GFF5.js";
2
-
3
- export { ServerComponentBuilder, scanDirectory };