olovaplugin 1.0.9 → 1.0.11

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.
@@ -91,6 +91,11 @@ function configPlugin() {
91
91
  return {
92
92
  appType: "custom",
93
93
  cacheDir: "./.olova/cache",
94
+ // Exclude olova from pre-bundling because it imports virtual:olova-routes
95
+ // which is only resolved at runtime by the routerPlugin
96
+ optimizeDeps: {
97
+ exclude: ["olova", "olova/Router", "olova/Link", "olova/client", "olova/server", "olova/useParams", "olova/usePathname", "olova/useSearchParams"]
98
+ },
94
99
  build: {
95
100
  outDir: "./.olova/dist",
96
101
  sourcemap: false,
@@ -151,7 +156,7 @@ function configPlugin() {
151
156
  var import_fs2 = __toESM(require("fs"), 1);
152
157
  var import_path2 = __toESM(require("path"), 1);
153
158
  function routerPlugin() {
154
- const virtualModuleId = "olova/routes";
159
+ const virtualModuleId = "virtual:olova-routes";
155
160
  const resolvedVirtualModuleId = "\0" + virtualModuleId;
156
161
  let server = null;
157
162
  let root = process.cwd();
@@ -304,7 +309,7 @@ function frameworkPlugin() {
304
309
  import React from 'react';
305
310
  import { hydrateRoot, createRoot } from 'react-dom/client';
306
311
  import Layout, { metadata as defaultMetadata } from '/src/root.tsx';
307
- import { Router, loadRoute } from '/olova/route.tsx';
312
+ import { Router, loadRoute } from 'olova/Router';
308
313
 
309
314
  // Helper to generate SEO meta tags
310
315
  function generateSeoTags(metadata) {
@@ -425,7 +430,7 @@ loadRoute(path).then((result) => {
425
430
  import React from 'react';
426
431
  import { renderToString } from 'react-dom/server';
427
432
  import Layout, { metadata as defaultMetadata } from '/src/root.tsx';
428
- import { Router, loadRoute } from '/olova/route.tsx';
433
+ import { Router, loadRoute } from 'olova/Router';
429
434
 
430
435
  // Generate SEO head content
431
436
  function generateSeoHead(metadata) {
@@ -544,6 +549,8 @@ export { loadRoute };`;
544
549
  // router/virtual-html.ts
545
550
  var import_fs3 = __toESM(require("fs"), 1);
546
551
  var import_path3 = __toESM(require("path"), 1);
552
+ var import_react = __toESM(require("react"), 1);
553
+ var import_server = require("react-dom/server");
547
554
 
548
555
  // router/hydration.ts
549
556
  function generateOlovaHydration(data, buildId) {
@@ -803,13 +810,51 @@ function virtualHtmlPlugin() {
803
810
  const shouldSSR = isStaticRoute(routePath);
804
811
  try {
805
812
  if (shouldSSR) {
813
+ let RootLayout = void 0;
814
+ const srcDir = import_path3.default.resolve("src");
815
+ const layoutExtensions = [".tsx", ".jsx"];
816
+ let layoutPath = "";
817
+ for (const ext of layoutExtensions) {
818
+ const p = import_path3.default.join(srcDir, "root" + ext);
819
+ if (import_fs3.default.existsSync(p)) {
820
+ layoutPath = "/src/root" + ext;
821
+ break;
822
+ }
823
+ }
806
824
  const { render } = await server.ssrLoadModule("olova/server");
807
- const { html: ssrHtml, hydrationData } = await render(routePath);
825
+ if (layoutPath) {
826
+ const mod = await server.ssrLoadModule(layoutPath);
827
+ RootLayout = mod.default;
828
+ }
829
+ const { html: ssrHtml, hydrationData } = await render(routePath, RootLayout);
808
830
  let fullHtml = ssrHtml;
809
- const hydrationScript = `<script>window.__OLOVA_DATA__ = ${JSON.stringify(hydrationData)};</script>`;
831
+ if (layoutPath) {
832
+ const metadata = hydrationData.metadata || {};
833
+ if (metadata.title && !fullHtml.includes("<title>")) {
834
+ fullHtml = fullHtml.replace("</head>", `<title>${metadata.title}</title>
835
+ </head>`);
836
+ }
837
+ if (metadata.description && !fullHtml.includes('name="description"')) {
838
+ fullHtml = fullHtml.replace("</head>", `<meta name="description" content="${metadata.description}" />
839
+ </head>`);
840
+ }
841
+ }
842
+ const hydrationScript = `<script>window.__OLOVA_DATA__ = ${JSON.stringify(hydrationData)}; window.__OLOVA_HYDRATE_MANUAL__ = true;</script>`;
810
843
  fullHtml = fullHtml.replace("</body>", `${hydrationScript}
811
844
  </body>`);
812
- const clientScript = `<script type="module" src="/olova/client"></script>`;
845
+ let clientScript;
846
+ if (layoutPath) {
847
+ clientScript = `<script type="module">
848
+ import { hydrate } from '/olova/client';
849
+ import RootLayout from '${layoutPath}';
850
+ hydrate(RootLayout);
851
+ </script>`;
852
+ } else {
853
+ clientScript = `<script type="module">
854
+ import { hydrate } from '/olova/client';
855
+ hydrate();
856
+ </script>`;
857
+ }
813
858
  fullHtml = fullHtml.replace("</body>", `${clientScript}
814
859
  </body>`);
815
860
  const devBuildId = "dev-" + Date.now().toString(36);
@@ -828,7 +873,7 @@ function virtualHtmlPlugin() {
828
873
  res.end(html);
829
874
  } else {
830
875
  const { renderShellWithMetadata } = await server.ssrLoadModule("olova/server");
831
- const { loadRoute: clientLoadRoute } = await server.ssrLoadModule("/olova/route.tsx");
876
+ const { loadRoute: clientLoadRoute } = await server.ssrLoadModule("olova/Router");
832
877
  let pageMetadata = {};
833
878
  try {
834
879
  const result = await clientLoadRoute(routePath);
@@ -837,8 +882,41 @@ function virtualHtmlPlugin() {
837
882
  }
838
883
  } catch (e) {
839
884
  }
840
- let fullHtml = renderShellWithMetadata(pageMetadata);
841
- const clientScript = `<script type="module" src="/olova/client"></script>`;
885
+ let RootLayout = void 0;
886
+ const srcDir = import_path3.default.resolve("src");
887
+ const layoutExtensions = [".tsx", ".jsx"];
888
+ let layoutPath = "";
889
+ for (const ext of layoutExtensions) {
890
+ const p = import_path3.default.join(srcDir, "root" + ext);
891
+ if (import_fs3.default.existsSync(p)) {
892
+ layoutPath = "/src/root" + ext;
893
+ break;
894
+ }
895
+ }
896
+ if (layoutPath) {
897
+ const mod = await server.ssrLoadModule(layoutPath);
898
+ RootLayout = mod.default;
899
+ }
900
+ let fullHtml;
901
+ if (RootLayout && layoutPath) {
902
+ const App = import_react.default.createElement(RootLayout, null, import_react.default.createElement("div", null));
903
+ fullHtml = "<!DOCTYPE html>" + (0, import_server.renderToString)(App);
904
+ } else {
905
+ fullHtml = renderShellWithMetadata(pageMetadata);
906
+ }
907
+ let clientScript;
908
+ if (layoutPath) {
909
+ clientScript = `<script type="module">
910
+ import { hydrate } from '/olova/client';
911
+ import RootLayout from '${layoutPath}';
912
+ hydrate(RootLayout);
913
+ </script>`;
914
+ } else {
915
+ clientScript = `<script type="module">
916
+ import { hydrate } from '/olova/client';
917
+ hydrate();
918
+ </script>`;
919
+ }
842
920
  fullHtml = fullHtml.replace("</body>", `${clientScript}
843
921
  </body>`);
844
922
  const devBuildId = "dev-" + Date.now().toString(36);
@@ -31,6 +31,11 @@ function configPlugin() {
31
31
  return {
32
32
  appType: "custom",
33
33
  cacheDir: "./.olova/cache",
34
+ // Exclude olova from pre-bundling because it imports virtual:olova-routes
35
+ // which is only resolved at runtime by the routerPlugin
36
+ optimizeDeps: {
37
+ exclude: ["olova", "olova/Router", "olova/Link", "olova/client", "olova/server", "olova/useParams", "olova/usePathname", "olova/useSearchParams"]
38
+ },
34
39
  build: {
35
40
  outDir: "./.olova/dist",
36
41
  sourcemap: false,
@@ -91,7 +96,7 @@ function configPlugin() {
91
96
  import fs2 from "fs";
92
97
  import path2 from "path";
93
98
  function routerPlugin() {
94
- const virtualModuleId = "olova/routes";
99
+ const virtualModuleId = "virtual:olova-routes";
95
100
  const resolvedVirtualModuleId = "\0" + virtualModuleId;
96
101
  let server = null;
97
102
  let root = process.cwd();
@@ -244,7 +249,7 @@ function frameworkPlugin() {
244
249
  import React from 'react';
245
250
  import { hydrateRoot, createRoot } from 'react-dom/client';
246
251
  import Layout, { metadata as defaultMetadata } from '/src/root.tsx';
247
- import { Router, loadRoute } from '/olova/route.tsx';
252
+ import { Router, loadRoute } from 'olova/Router';
248
253
 
249
254
  // Helper to generate SEO meta tags
250
255
  function generateSeoTags(metadata) {
@@ -365,7 +370,7 @@ loadRoute(path).then((result) => {
365
370
  import React from 'react';
366
371
  import { renderToString } from 'react-dom/server';
367
372
  import Layout, { metadata as defaultMetadata } from '/src/root.tsx';
368
- import { Router, loadRoute } from '/olova/route.tsx';
373
+ import { Router, loadRoute } from 'olova/Router';
369
374
 
370
375
  // Generate SEO head content
371
376
  function generateSeoHead(metadata) {
@@ -484,6 +489,8 @@ export { loadRoute };`;
484
489
  // router/virtual-html.ts
485
490
  import fs3 from "fs";
486
491
  import path3 from "path";
492
+ import React from "react";
493
+ import { renderToString } from "react-dom/server";
487
494
 
488
495
  // router/hydration.ts
489
496
  function generateOlovaHydration(data, buildId) {
@@ -743,13 +750,51 @@ function virtualHtmlPlugin() {
743
750
  const shouldSSR = isStaticRoute(routePath);
744
751
  try {
745
752
  if (shouldSSR) {
753
+ let RootLayout = void 0;
754
+ const srcDir = path3.resolve("src");
755
+ const layoutExtensions = [".tsx", ".jsx"];
756
+ let layoutPath = "";
757
+ for (const ext of layoutExtensions) {
758
+ const p = path3.join(srcDir, "root" + ext);
759
+ if (fs3.existsSync(p)) {
760
+ layoutPath = "/src/root" + ext;
761
+ break;
762
+ }
763
+ }
746
764
  const { render } = await server.ssrLoadModule("olova/server");
747
- const { html: ssrHtml, hydrationData } = await render(routePath);
765
+ if (layoutPath) {
766
+ const mod = await server.ssrLoadModule(layoutPath);
767
+ RootLayout = mod.default;
768
+ }
769
+ const { html: ssrHtml, hydrationData } = await render(routePath, RootLayout);
748
770
  let fullHtml = ssrHtml;
749
- const hydrationScript = `<script>window.__OLOVA_DATA__ = ${JSON.stringify(hydrationData)};</script>`;
771
+ if (layoutPath) {
772
+ const metadata = hydrationData.metadata || {};
773
+ if (metadata.title && !fullHtml.includes("<title>")) {
774
+ fullHtml = fullHtml.replace("</head>", `<title>${metadata.title}</title>
775
+ </head>`);
776
+ }
777
+ if (metadata.description && !fullHtml.includes('name="description"')) {
778
+ fullHtml = fullHtml.replace("</head>", `<meta name="description" content="${metadata.description}" />
779
+ </head>`);
780
+ }
781
+ }
782
+ const hydrationScript = `<script>window.__OLOVA_DATA__ = ${JSON.stringify(hydrationData)}; window.__OLOVA_HYDRATE_MANUAL__ = true;</script>`;
750
783
  fullHtml = fullHtml.replace("</body>", `${hydrationScript}
751
784
  </body>`);
752
- const clientScript = `<script type="module" src="/olova/client"></script>`;
785
+ let clientScript;
786
+ if (layoutPath) {
787
+ clientScript = `<script type="module">
788
+ import { hydrate } from '/olova/client';
789
+ import RootLayout from '${layoutPath}';
790
+ hydrate(RootLayout);
791
+ </script>`;
792
+ } else {
793
+ clientScript = `<script type="module">
794
+ import { hydrate } from '/olova/client';
795
+ hydrate();
796
+ </script>`;
797
+ }
753
798
  fullHtml = fullHtml.replace("</body>", `${clientScript}
754
799
  </body>`);
755
800
  const devBuildId = "dev-" + Date.now().toString(36);
@@ -768,7 +813,7 @@ function virtualHtmlPlugin() {
768
813
  res.end(html);
769
814
  } else {
770
815
  const { renderShellWithMetadata } = await server.ssrLoadModule("olova/server");
771
- const { loadRoute: clientLoadRoute } = await server.ssrLoadModule("/olova/route.tsx");
816
+ const { loadRoute: clientLoadRoute } = await server.ssrLoadModule("olova/Router");
772
817
  let pageMetadata = {};
773
818
  try {
774
819
  const result = await clientLoadRoute(routePath);
@@ -777,8 +822,41 @@ function virtualHtmlPlugin() {
777
822
  }
778
823
  } catch (e) {
779
824
  }
780
- let fullHtml = renderShellWithMetadata(pageMetadata);
781
- const clientScript = `<script type="module" src="/olova/client"></script>`;
825
+ let RootLayout = void 0;
826
+ const srcDir = path3.resolve("src");
827
+ const layoutExtensions = [".tsx", ".jsx"];
828
+ let layoutPath = "";
829
+ for (const ext of layoutExtensions) {
830
+ const p = path3.join(srcDir, "root" + ext);
831
+ if (fs3.existsSync(p)) {
832
+ layoutPath = "/src/root" + ext;
833
+ break;
834
+ }
835
+ }
836
+ if (layoutPath) {
837
+ const mod = await server.ssrLoadModule(layoutPath);
838
+ RootLayout = mod.default;
839
+ }
840
+ let fullHtml;
841
+ if (RootLayout && layoutPath) {
842
+ const App = React.createElement(RootLayout, null, React.createElement("div", null));
843
+ fullHtml = "<!DOCTYPE html>" + renderToString(App);
844
+ } else {
845
+ fullHtml = renderShellWithMetadata(pageMetadata);
846
+ }
847
+ let clientScript;
848
+ if (layoutPath) {
849
+ clientScript = `<script type="module">
850
+ import { hydrate } from '/olova/client';
851
+ import RootLayout from '${layoutPath}';
852
+ hydrate(RootLayout);
853
+ </script>`;
854
+ } else {
855
+ clientScript = `<script type="module">
856
+ import { hydrate } from '/olova/client';
857
+ hydrate();
858
+ </script>`;
859
+ }
782
860
  fullHtml = fullHtml.replace("</body>", `${clientScript}
783
861
  </body>`);
784
862
  const devBuildId = "dev-" + Date.now().toString(36);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olovaplugin",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Vite plugins for Olova framework",
5
5
  "type": "module",
6
6
  "main": "dist/olova-plugins.cjs",
@@ -18,8 +18,13 @@
18
18
  }
19
19
  }
20
20
  },
21
+ "peerDependencies": {
22
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
23
+ "react": "*",
24
+ "react-dom": "*"
25
+ },
21
26
  "scripts": {
22
- "build": "tsup olova-plugins.ts --format cjs,esm --dts --clean"
27
+ "build": "tsup olova-plugins.ts --format cjs,esm --dts --clean --external vite react react-dom react-dom/server util stream path fs"
23
28
  },
24
29
  "keywords": [
25
30
  "vite",
@@ -31,14 +36,10 @@
31
36
  ],
32
37
  "author": "Sera",
33
38
  "license": "MIT",
34
- "peerDependencies": {
35
- "vite": "^6.0.0 || ^5.0.0"
36
- },
37
39
  "devDependencies": {
38
40
  "@types/node": "^20.0.0",
39
41
  "tsup": "^8.0.0",
40
42
  "typescript": "^5.0.0",
41
- "vite": "^6.0.0"
43
+ "vite": "^7.2.4"
42
44
  }
43
-
44
45
  }