Repository: Rezact/Rezact (ts)

Issue:
Support Router Meta Fields
https://router.vuejs.org/guide/advanced/meta.html#Route-Meta-Fields

Pull request description:
55 support router meta fields
close #55 

![image](https://github.com/Rezact/Rezact/assets/2927894/a390868d-f5be-4270-8ef2-bc42dd579f4b)

![image](https://github.com/Rezact/Rezact/assets/2927894/c06b8b06-124f-483e-a779-a16b6b745ad1)

![image](https://github.com/Rezact/Rezact/assets/2927894/9d3254a9-9e7d-4a24-8911-fa07b45d7a4e)


Patch:
diff --git a/src/components/appRouter.ts b/src/components/appRouter.ts
index b4fe46a..9be0dea 100644
--- a/src/components/appRouter.ts
+++ b/src/components/appRouter.ts
@@ -166,21 +166,25 @@ const routes = [
     path: "/users3",
     component: Users,
     title: "Users Test 3",
+    meta: { metaProp: "Users Meta Test 3" },
   },
   {
     path: "/users3/:id",
     component: UsersId,
     title: "Users ID Test 3",
+    meta: { metaProp: "Users ID Meta Test 3" },
     children: [
       {
         path: "/settings",
         component: UsersIdSettings,
         title: "Users Settings Test 3",
+        meta: { metaProp: "Users Settings Meta Test 3" },
       },
       {
         path: "/settings/*",
-        component: () => UsersIdSettingsWildCard,
+        component: UsersIdSettingsWildCard,
         title: "Users Catch AllTest 3",
+        meta: { metaProp: "Users Catch All Meta Test 3" },
       },
     ],
   },
diff --git a/src/examples/NestedRoutes/Users.tsx b/src/examples/NestedRoutes/Users.tsx
index b08b030..5db7d5b 100644
--- a/src/examples/NestedRoutes/Users.tsx
+++ b/src/examples/NestedRoutes/Users.tsx
@@ -2,6 +2,7 @@ import { MyLayout } from "../Layout/nestedLayout";
 import { Page } from "../DataFetching/DataFetching";
 
 export default function Users({ router }) {
+  (window as any).testValues.Users = router.meta;
   return (
     <div id="nested-routes-test-id">
       <h1>1. Users START</h1>
diff --git a/src/examples/NestedRoutes/UsersId.tsx b/src/examples/NestedRoutes/UsersId.tsx
index c1f43e9..afdb140 100644
--- a/src/examples/NestedRoutes/UsersId.tsx
+++ b/src/examples/NestedRoutes/UsersId.tsx
@@ -2,6 +2,7 @@ import { MyLayout } from "../Layout/nestedLayout";
 import { Page } from "../SimpleStringListState/SimpleStringList";
 
 export default function ({ router }) {
+  (window as any).testValues.UsersID = router.meta;
   return (
     <>
       <h1>2. Users ID START</h1>
diff --git a/src/examples/NestedRoutes/UsersIdSettings.tsx b/src/examples/NestedRoutes/UsersIdSettings.tsx
index 191e509..3081c27 100644
--- a/src/examples/NestedRoutes/UsersIdSettings.tsx
+++ b/src/examples/NestedRoutes/UsersIdSettings.tsx
@@ -2,6 +2,7 @@ import { MyLayout } from "../Layout/nestedLayout";
 import { Page } from "../DataFetching/DataFetching";
 
 export default function ({ router }) {
+  (window as any).testValues.UsersSettings = router.meta;
   return (
     <div>
       <h1>3. Users ID Settings START</h1>
diff --git a/src/examples/NestedRoutes/UsersIdSettingsWildCard.tsx b/src/examples/NestedRoutes/UsersIdSettingsWildCard.tsx
index d4651bb..a14c9f4 100644
--- a/src/examples/NestedRoutes/UsersIdSettingsWildCard.tsx
+++ b/src/examples/NestedRoutes/UsersIdSettingsWildCard.tsx
@@ -2,6 +2,7 @@ import { MyLayout } from "../Layout/nestedLayout";
 import { Page } from "../SimpleStringListState/SimpleStringList";
 
 export default function ({ router }) {
+  (window as any).testValues.UsersCatchAll = router.meta;
   let { $rest } = router.params;
   return (
     <>
diff --git a/src/lib/rezact/router.ts b/src/lib/rezact/router.ts
index d17812e..a15ebb4 100644
--- a/src/lib/rezact/router.ts
+++ b/src/lib/rezact/router.ts
@@ -45,6 +45,7 @@ class RouteNode {
   nestedRoot: boolean;
   partName: string;
   title: string;
+  meta: any;
   constructor() {
     this.handlers = {};
     this.children = new Map();
@@ -77,6 +78,7 @@ interface routeIF {
   stack: any;
   currentNode: any;
   outlet?: Signal<Element>;
+  meta?: any;
   go?: (delta: number) => void;
   back?: () => void;
   forward?: () => void;
@@ -174,6 +176,7 @@ export class TrieRouter {
       if (route.component)
         this.addRoute(currentPath, route.component, false, {
           title: route.title,
+          meta: route.meta,
         });
 
       if (route.children && route.children.length > 0) {
@@ -186,13 +189,17 @@ export class TrieRouter {
     const parts = path.split("/").filter(Boolean);
     let firstPartRootSet = false;
     let currentNode = this.root;
-    if (path === "/") this.root.title = opts.title;
+    if (path === "/") {
+      this.root.title = opts.title;
+      this.root.meta = opts.meta;
+    }
 
     for (let part of parts) {
       if (part.startsWith(":")) {
         if (!currentNode.dynamicChild) {
           currentNode.dynamicChild = new RouteNode();
           currentNode.dynamicChild.title = opts.title;
+          currentNode.dynamicChild.meta = opts.meta;
           currentNode.dynamicChild.partName = `/${part}`;
           currentNode.dynamicChild.isDynamic = part.slice(1);
         }
@@ -200,6 +207,7 @@ export class TrieRouter {
       } else if (part.startsWith("*")) {
         currentNode.wildcardHandler = new RouteNode();
         currentNode.wildcardHandler.title = opts.title;
+        currentNode.wildcardHandler.meta = opts.meta;
         currentNode.wildcardHandler.partName = `/${part}`;
         currentNode.wildcardHandler.isDynamic = part.slice(1);
         currentNode.wildcardHandler.handlers.GET = callback;
@@ -209,6 +217,7 @@ export class TrieRouter {
         if (!currentNode.children.has(part)) {
           currentNode.children.set(part, new RouteNode());
           currentNode.children.get(part).title = opts.title;
+          currentNode.children.get(part).meta = opts.meta;
           currentNode.children.get(part).partName = `/${part}`;
         }
         currentNode = currentNode.children.get(part);
@@ -355,6 +364,7 @@ export function useRouter(app = null, config: any = {}) {
           const component = mod.Page || mod.default || mod;
 
           router.outlet = nextItem.router_outlet;
+          router.meta = nextItem.meta;
           render(thisItem.router_outlet, component, { router });
         }
       }
@@ -365,14 +375,17 @@ export function useRouter(app = null, config: any = {}) {
       if (layout) {
         if (currentLayout === layout) {
           router.outlet = stack[0].router_outlet;
+          router.meta = stack[0].meta;
           render(router_outlet, component, { router });
         } else {
           currentLayout = layout;
 
           router.outlet = stack[0].router_outlet;
+          router.meta = stack[0].meta;
           render(router_outlet, component, { router });
 
           router.outlet = router_outlet;
+          router.meta = stack[0].meta;
           render(app, (props) => layout(props), { router });
         }
       } else {
@@ -381,6 +394,7 @@ export function useRouter(app = null, config: any = {}) {
         const mod = pages[0];
         const component = mod.Page || mod.default || mod;
         router.outlet = stack[0].router_outlet;
+        router.meta = stack[0].meta;
         render(app, component, { router });
       }
     },
diff --git a/src/main.ts b/src/main.ts
index 58a015f..bdcb8b1 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -5,4 +5,6 @@ import { router } from "./components/appRouter";
 //   return "/login";
 // });
 
+(window as any).testValues = {};
+
 router.routeChanged();


Test patch:
diff --git a/src/__snapshots__/router.test.js.snap b/src/__snapshots__/router.test.js.snap
index 083cd78..520bc4f 100644
--- a/src/__snapshots__/router.test.js.snap
+++ b/src/__snapshots__/router.test.js.snap
@@ -36,12 +36,7 @@ exports[`Router Tests Suite > DIRECT COMPONENT - Nested Route Level 3 1`] = `"<h
 
 exports[`Router Tests Suite > DIRECT COMPONENT - Nested Route Level 3 2`] = `"<h1>1. Users START</h1><p>ID: direct953test</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><h1>2. Users ID START</h1><p>ID: direct953test</p><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><!--start map--><div><h1>3. Users ID Settings START</h1><p>ID: direct953test</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><span></span><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>3. Users ID Settings END</p></div><!--end map--><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><p>2. Users ID END</p><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>1. Users END</p>"`;
 
-exports[`Router Tests Suite > DIRECT COMPONENT - Nested Route Level 4 1`] = `
-"<h1>1. Users START</h1><p>ID: direct1235</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><h1>2. Users ID START</h1><p>ID: direct1235</p><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><!--start map--><div><h1>3. Users ID Settings START</h1><p>ID: direct1235</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map-->function({ router }) {
-  let { $rest } = router.params;
-  return /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(__vite_ssr_import_0__.xFragment, null, /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(\\"h1\\", null, \\"4. Users ID Settings Wild Card\\"), /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(__vite_ssr_import_2__.Page, null), /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(\\"p\\", null, \\"ID: \\", router.params.id), /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(\\"p\\", null, $rest), /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(\\"button\\", { onClick: () => $rest.set(\\"wqer/qwer/qwer\\") }, \\"Test\\"), /* @__PURE__ */ __vite_ssr_import_0__.xCreateElement(__vite_ssr_import_2__.Page, null));
-}<!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>3. Users ID Settings END</p></div><!--end map--><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><p>2. Users ID END</p><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>1. Users END</p>"
-`;
+exports[`Router Tests Suite > DIRECT COMPONENT - Nested Route Level 4 1`] = `"<h1>1. Users START</h1><p>ID: direct1235</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><h1>2. Users ID START</h1><p>ID: direct1235</p><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><!--start map--><div><h1>3. Users ID Settings START</h1><p>ID: direct1235</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><h1>4. Users ID Settings Wild Card</h1><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><p>ID: direct1235</p><p>all/wild/card/stuff</p><button>Test</button><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>3. Users ID Settings END</p></div><!--end map--><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><p>2. Users ID END</p><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>1. Users END</p>"`;
 
 exports[`Router Tests Suite > DIRECT COMPONENT - Nested Route Level 4 2`] = `"<h1>1. Users START</h1><p>ID: directXXXtest</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><h1>2. Users ID START</h1><p>ID: directXXXtest</p><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><!--start map--><div><h1>3. Users ID Settings START</h1><p>ID: directXXXtest</p><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><!--start map--><h1>4. Users ID Settings Wild Card</h1><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><p>ID: directXXXtest</p><p>all/wild/card/stuff</p><button>Test</button><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>3. Users ID Settings END</p></div><!--end map--><h1>Simple String List</h1><!--start map--><div dataval=\\"Jack\\"><input></div><div dataval=\\"Jill\\"><input></div><div dataval=\\"John\\"><input></div><div dataval=\\"Jane\\"><input></div><!--end map--><!--start map--><div>Jack</div><div>Jill</div><div>John</div><div>Jane</div><!--end map--><!--signal--><p>2. Users ID END</p><!--end map--><h1>Data Fetching</h1><p>Loading</p><span></span><!--start map--><!--end map--><!--signal--><p>1. Users END</p>"`;
 
diff --git a/src/router.test.js b/src/router.test.js
index 796cc31..3690ea7 100644
--- a/src/router.test.js
+++ b/src/router.test.js
@@ -2,6 +2,8 @@ import { afterAll, beforeAll, describe, expect, it } from "vitest";
 import { screen, waitFor } from "@testing-library/dom";
 import userEvent from "@testing-library/user-event";
 
+window.testValues = {};
+
 const currentFetch = global.fetch;
 const currentHistory = global.history;
 const historyState = [];
@@ -225,7 +227,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users");
+    router.routeRequest("/users2");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -241,7 +243,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users/953test/settings");
+    router.routeRequest("/users2/953test/settings");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -257,7 +259,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users/953test");
+    router.routeRequest("/users2/953test");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -273,11 +275,16 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users/953test/settings/all/wild/card/stuff");
+    router.routeRequest("/users2/953test/settings/all/wild/card/stuff");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
     expect(document.title).toBe("Users Catch AllTest 2");
+
+    expect(window.testValues.Users).toBe(undefined);
+    expect(window.testValues.UsersID).toBe(undefined);
+    expect(window.testValues.UsersSettings).toBe(undefined);
+    expect(window.testValues.UsersCatchAll).toBe(undefined);
   });
 
   it("CONFIG BASED - Nested Route Level 1 Again", async () => {
@@ -289,7 +296,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users");
+    router.routeRequest("/users2");
     await delay(100);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -305,7 +312,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users");
+    router.routeRequest("/users3");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -321,7 +328,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users/direct953test/settings");
+    router.routeRequest("/users3/direct953test/settings");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -337,7 +344,7 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users/direct333test");
+    router.routeRequest("/users3/direct333test");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
@@ -353,11 +360,20 @@ describe("Router Tests Suite", () => {
     const testDiv = document.getElementById("nested-routes-test-id");
     expect(testDiv.innerHTML).toMatchSnapshot();
 
-    router.routeRequest("/users/directXXXtest/settings/all/wild/card/stuff");
+    router.routeRequest("/users3/directXXXtest/settings/all/wild/card/stuff");
     await delay(200);
     const testDiv2 = document.getElementById("nested-routes-test-id");
     expect(testDiv2.innerHTML).toMatchSnapshot();
     expect(document.title).toBe("Users Catch AllTest 3");
+
+    expect(window.testValues.Users.metaProp).toBe("Users Meta Test 3");
+    expect(window.testValues.UsersID.metaProp).toBe("Users ID Meta Test 3");
+    expect(window.testValues.UsersSettings.metaProp).toBe(
+      "Users Settings Meta Test 3"
+    );
+    expect(window.testValues.UsersCatchAll.metaProp).toBe(
+      "Users Catch All Meta Test 3"
+    );
   });
 
   it("DIRECT COMPONENT - Nested Route Level 1 Again", async () => {