@virou/core 1.0.0 → 1.1.1

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <p>
4
4
  <a href="https://www.npmjs.com/package/@virou/core"><img src="https://img.shields.io/npm/v/@virou/core.svg?style=flat&colorA=18181B&colorB=39737d" alt="Version"></a>
5
5
  <a href="https://www.npmjs.com/package/@virou/core"><img src="https://img.shields.io/npm/dm/@virou/core.svg?style=flat&colorA=18181B&colorB=39737d" alt="Downloads"></a>
6
- <a href="https://bundlephobia.com/package/@virou/core"><img src="https://img.shields.io/bundlephobia/min/@virou/core?style=flat&colorA=18181B&colorB=39737d" alt="Bundle Size"></a>
6
+ <a href="https://bundlephobia.com/package/@virou/core"><img src="https://img.shields.io/bundlephobia/min/@virou/core?style=flat&colorA=18181B&colorB=39737d" alt="Bundle Size"><a/>
7
7
  <a href="https://github.com/tankosinn/virou/tree/main/LICENSE"><img src="https://img.shields.io/github/license/tankosinn/virou.svg?style=flat&colorA=18181B&colorB=39737d" alt="License"></a>
8
8
  </p>
9
9
 
@@ -66,6 +66,8 @@ createApp(App)
66
66
  .mount('#app')
67
67
  ```
68
68
 
69
+ > ⚠️ Virou doesn’t globally register any components (including `VRouterView`); it only adds a `$virou` global property to store router instances in a `Map<string, VRouterData>`, which are automatically removed when no longer in use.
70
+
69
71
  ### 🧩 Using with Nuxt
70
72
 
71
73
  Install Virou Nuxt module with your package manager:
@@ -0,0 +1,106 @@
1
+ import { RouterContext } from "rou3";
2
+ import * as vue0 from "vue";
3
+ import { Component, DefineComponent, Plugin, PropType, Ref, ShallowRef, SlotsType, VNodeChild } from "vue";
4
+
5
+ //#region src/types.d.ts
6
+ type Lazy<T> = () => Promise<T>;
7
+ type VRouteComponent = Component | DefineComponent;
8
+ type VRouteLazyComponent = Lazy<VRouteComponent>;
9
+ type VRouteRenderComponent = VRouteComponent | VRouteLazyComponent;
10
+ type VRouteMeta = Record<PropertyKey, unknown>;
11
+ interface VRouteRaw {
12
+ path: string;
13
+ component: VRouteRenderComponent;
14
+ meta?: VRouteMeta;
15
+ children?: VRouteRaw[];
16
+ }
17
+ type VRouteId = Readonly<[path: string, depth: number]>;
18
+ interface VRouteMatchedData {
19
+ id: VRouteId;
20
+ meta?: VRouteMeta;
21
+ }
22
+ interface VRouteNormalized extends Omit<VRouteRaw, 'path' | 'children'> {
23
+ parentId?: VRouteId;
24
+ }
25
+ type VRoutesMap = Map<VRouteId, VRouteNormalized>;
26
+ interface VRoute {
27
+ fullPath: string;
28
+ meta?: VRouteMeta;
29
+ params?: Record<string, string>;
30
+ path: string;
31
+ search: string;
32
+ hash: string;
33
+ _renderList: Component[] | null;
34
+ }
35
+ interface VRouterData {
36
+ context: RouterContext<VRouteMatchedData>;
37
+ routes: VRoutesMap;
38
+ activePath: Ref<string>;
39
+ route: ShallowRef<VRoute>;
40
+ _isGlobal: boolean;
41
+ _deps: number;
42
+ _dispose: () => void;
43
+ }
44
+ interface VRouterOptions {
45
+ initialPath?: string;
46
+ _isGlobal?: boolean;
47
+ }
48
+ interface VRouter {
49
+ route: VRouterData['route'];
50
+ router: {
51
+ addRoute: (route: VRouteRaw) => void;
52
+ replace: (path: string) => void;
53
+ _depthKey: symbol;
54
+ };
55
+ }
56
+ interface VirouPluginOptions {
57
+ routers?: Record<string, {
58
+ routes: VRouteRaw[];
59
+ options?: Omit<VRouterOptions, '_isGlobal'>;
60
+ }>;
61
+ }
62
+ //#endregion
63
+ //#region src/component.d.ts
64
+ declare const VRouterView: vue0.DefineComponent<vue0.ExtractPropTypes<{
65
+ routerKey: StringConstructor;
66
+ keepAlive: {
67
+ type: BooleanConstructor;
68
+ default: boolean;
69
+ };
70
+ viewKey: {
71
+ type: PropType<string | ((route: VRoute, key: string) => string)>;
72
+ };
73
+ }>, () => string | number | boolean | vue0.VNode<vue0.RendererNode, vue0.RendererElement, {
74
+ [key: string]: any;
75
+ }> | vue0.VNodeArrayChildren | null, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<vue0.ExtractPropTypes<{
76
+ routerKey: StringConstructor;
77
+ keepAlive: {
78
+ type: BooleanConstructor;
79
+ default: boolean;
80
+ };
81
+ viewKey: {
82
+ type: PropType<string | ((route: VRoute, key: string) => string)>;
83
+ };
84
+ }>> & Readonly<{}>, {
85
+ keepAlive: boolean;
86
+ }, SlotsType<{
87
+ default: (payload: {
88
+ Component: VNodeChild;
89
+ route: VRoute;
90
+ }) => VNodeChild;
91
+ fallback: (payload: {
92
+ route: VRoute;
93
+ }) => VNodeChild;
94
+ }>, {}, {}, string, vue0.ComponentProvideOptions, true, {}, any>;
95
+ //#endregion
96
+ //#region src/plugin.d.ts
97
+ declare const virou: Plugin<[VirouPluginOptions?]>;
98
+ //#endregion
99
+ //#region src/router.d.ts
100
+ declare const virouSymbol: unique symbol;
101
+ declare function createVRouter(routes: VRouteRaw[], options?: VRouterOptions): VRouterData;
102
+ declare function useVRouter(routes?: VRouteRaw[], options?: VRouterOptions): VRouter;
103
+ declare function useVRouter(key?: string, routes?: VRouteRaw[], options?: VRouterOptions): VRouter;
104
+ //#endregion
105
+ export { VRoute, VRouteComponent, VRouteId, VRouteLazyComponent, VRouteMatchedData, VRouteMeta, VRouteNormalized, VRouteRaw, VRouteRenderComponent, VRouter, VRouterData, VRouterOptions, VRouterView, VRoutesMap, VirouPluginOptions, createVRouter, useVRouter, virou, virouSymbol };
106
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/component.ts","../src/plugin.ts","../src/router.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,178 @@
1
+ import { addRoute, createRouter, findRoute } from "rou3";
2
+ import { KeepAlive, Suspense, defineAsyncComponent, defineComponent, getCurrentInstance, h, inject, onScopeDispose, provide, ref, shallowRef, useId, watchEffect } from "vue";
3
+ import { joinURL, parseURL } from "ufo";
4
+
5
+ //#region src/utils.ts
6
+ const renderListCache = /* @__PURE__ */ new WeakMap();
7
+ function normalizeComponent(component) {
8
+ if (typeof component === "function" && component.length === 0) return defineAsyncComponent(component);
9
+ return component;
10
+ }
11
+ function registerRoutes(ctx, routes, registry, parentId) {
12
+ for (const { path, meta, component, children } of routes) {
13
+ const fullPath = joinURL(parentId?.[0] ?? "/", path);
14
+ const depth = (parentId?.[1] ?? -1) + 1;
15
+ const id = Object.freeze([fullPath, depth]);
16
+ registry.set(id, {
17
+ meta,
18
+ component: normalizeComponent(component),
19
+ parentId
20
+ });
21
+ if (children && children.length) registerRoutes(ctx, children, registry, id);
22
+ addRoute(ctx, "GET", fullPath, {
23
+ id,
24
+ meta
25
+ });
26
+ }
27
+ }
28
+ function createRenderList(data, routes) {
29
+ let cacheForRoutes = renderListCache.get(routes);
30
+ if (!cacheForRoutes) {
31
+ cacheForRoutes = /* @__PURE__ */ new Map();
32
+ renderListCache.set(routes, cacheForRoutes);
33
+ }
34
+ const cached = cacheForRoutes.get(data.id);
35
+ if (cached) return cached;
36
+ const depth = data.id[1];
37
+ const list = Array.from({ length: depth });
38
+ let idx = depth;
39
+ let cursor = routes.get(data.id);
40
+ while (cursor) {
41
+ list[idx--] = cursor.component;
42
+ cursor = cursor.parentId !== void 0 ? routes.get(cursor.parentId) : void 0;
43
+ }
44
+ cacheForRoutes.set(data.id, list);
45
+ return list;
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/router.ts
50
+ const virouSymbol = Symbol("virou");
51
+ function createVRouter(routes, options) {
52
+ const context = createRouter();
53
+ const routeRegistry = /* @__PURE__ */ new Map();
54
+ registerRoutes(context, routes, routeRegistry);
55
+ const activePath = ref(options?.initialPath ?? "/");
56
+ const snapshot = () => {
57
+ const matchedRoute = findRoute(context, "GET", activePath.value);
58
+ const _renderList = matchedRoute ? createRenderList(matchedRoute.data, routeRegistry) : null;
59
+ const { pathname, hash, search } = parseURL(activePath.value);
60
+ return {
61
+ fullPath: activePath.value,
62
+ path: pathname,
63
+ search,
64
+ hash,
65
+ meta: matchedRoute?.data.meta,
66
+ params: matchedRoute?.params,
67
+ _renderList
68
+ };
69
+ };
70
+ const route = shallowRef(snapshot());
71
+ const unwatch = watchEffect(() => {
72
+ route.value = snapshot();
73
+ });
74
+ return {
75
+ context,
76
+ routes: routeRegistry,
77
+ activePath,
78
+ route,
79
+ _isGlobal: options?._isGlobal ?? false,
80
+ _deps: 0,
81
+ _dispose: unwatch
82
+ };
83
+ }
84
+ function useVRouter(...args) {
85
+ if (typeof args[0] !== "string") args.unshift(inject(virouSymbol, useId()));
86
+ const [key, routes = [], options = {}] = args;
87
+ if (!key || typeof key !== "string") throw new TypeError(`[virou] [useVRouter] key must be a string: ${key}`);
88
+ provide(virouSymbol, key);
89
+ const vm = getCurrentInstance();
90
+ if (!vm) throw new TypeError("[virou] [useVRouter] useVRouter must be called in setup()");
91
+ const virou$1 = vm.proxy?.$virou;
92
+ if (!virou$1) throw new Error("[virou] [useVRouter] virou plugin not installed");
93
+ if (routes.length) {
94
+ if (virou$1.get(key)) throw new Error(`[virou] [useVRouter] router with key "${key}" already exists`);
95
+ virou$1.set(key, createVRouter(routes, options));
96
+ }
97
+ const router = virou$1.get(key);
98
+ if (!router) throw new Error(`[virou] [useVRouter] router with key "${key}" not found`);
99
+ router._deps++;
100
+ onScopeDispose(() => {
101
+ router._deps--;
102
+ if (router._deps === 0 && !router._isGlobal) {
103
+ router._dispose();
104
+ virou$1.delete(key);
105
+ }
106
+ });
107
+ return {
108
+ route: router.route,
109
+ router: {
110
+ addRoute: (route) => {
111
+ registerRoutes(router.context, [route], router.routes);
112
+ },
113
+ replace: (path) => {
114
+ router.activePath.value = path;
115
+ },
116
+ _depthKey: Symbol.for(key)
117
+ }
118
+ };
119
+ }
120
+
121
+ //#endregion
122
+ //#region src/component.ts
123
+ const VRouterView = defineComponent({
124
+ name: "VRouterView",
125
+ inheritAttrs: false,
126
+ props: {
127
+ routerKey: String,
128
+ keepAlive: {
129
+ type: Boolean,
130
+ default: false
131
+ },
132
+ viewKey: { type: [String, Function] }
133
+ },
134
+ slots: Object,
135
+ setup(props, { slots, attrs }) {
136
+ const key = props.routerKey ?? inject(virouSymbol);
137
+ if (key === void 0) throw new Error("[virou] [VRouterView] routerKey is required");
138
+ const { route, router } = useVRouter(key);
139
+ const depth = inject(router._depthKey, 0);
140
+ provide(router._depthKey, depth + 1);
141
+ return () => {
142
+ const component = route.value._renderList?.[depth];
143
+ if (!component) return slots.default?.({
144
+ Component: null,
145
+ route: route.value
146
+ }) ?? null;
147
+ const vnodeKey = typeof props.viewKey === "function" ? props.viewKey(route.value, key) : props.viewKey ?? `${key}-${depth}-${route.value.path}`;
148
+ const suspenseVNode = h(Suspense, null, {
149
+ default: () => h(component, {
150
+ key: vnodeKey,
151
+ ...attrs
152
+ }),
153
+ fallback: () => slots.fallback?.({ route: route.value }) ?? null
154
+ });
155
+ const vnode = props.keepAlive ? h(KeepAlive, null, { default: () => suspenseVNode }) : suspenseVNode;
156
+ return slots.default?.({
157
+ Component: vnode,
158
+ route: route.value
159
+ }) ?? vnode;
160
+ };
161
+ }
162
+ });
163
+
164
+ //#endregion
165
+ //#region src/plugin.ts
166
+ const virou = (app, options = {}) => {
167
+ const { routers } = options;
168
+ const map = /* @__PURE__ */ new Map();
169
+ app.config.globalProperties.$virou = map;
170
+ if (routers) for (const [key, router] of Object.entries(routers)) map.set(key, createVRouter(router.routes, {
171
+ ...router.options,
172
+ _isGlobal: true
173
+ }));
174
+ };
175
+
176
+ //#endregion
177
+ export { VRouterView, createVRouter, useVRouter, virou, virouSymbol };
178
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["id: VRouteId","routeRegistry: VRoutesMap","virou","virou: Plugin<[VirouPluginOptions?]>"],"sources":["../src/utils.ts","../src/router.ts","../src/component.ts","../src/plugin.ts"],"sourcesContent":["import type { RouterContext } from 'rou3'\nimport type { Component } from 'vue'\nimport type { VRouteId, VRouteLazyComponent, VRouteMatchedData, VRouteRaw, VRouteRenderComponent, VRoutesMap } from './types'\nimport { addRoute } from 'rou3'\nimport { joinURL } from 'ufo'\nimport { defineAsyncComponent } from 'vue'\n\nconst renderListCache = new WeakMap<VRoutesMap, Map<VRouteId, Component[]>>()\n\nfunction normalizeComponent(component: VRouteRenderComponent): Component {\n if (typeof component === 'function' && (component as VRouteLazyComponent).length === 0) {\n return defineAsyncComponent(component as VRouteLazyComponent)\n }\n return component as Component\n}\n\nexport function registerRoutes(\n ctx: RouterContext<VRouteMatchedData>,\n routes: VRouteRaw[],\n registry: VRoutesMap,\n parentId?: VRouteId,\n): void {\n for (const { path, meta, component, children } of routes) {\n const fullPath = joinURL(parentId?.[0] ?? '/', path)\n const depth = (parentId?.[1] ?? -1) + 1\n\n const id: VRouteId = Object.freeze([fullPath, depth])\n\n registry.set(id, {\n meta,\n component: normalizeComponent(component),\n parentId,\n })\n\n if (children && children.length) {\n registerRoutes(ctx, children, registry, id)\n }\n\n addRoute(ctx, 'GET', fullPath, { id, meta })\n }\n}\n\nexport function createRenderList(\n data: VRouteMatchedData,\n routes: VRoutesMap,\n): VRouteRenderComponent[] {\n let cacheForRoutes = renderListCache.get(routes)\n if (!cacheForRoutes) {\n cacheForRoutes = new Map<VRouteId, Component[]>()\n renderListCache.set(routes, cacheForRoutes)\n }\n\n const cached = cacheForRoutes.get(data.id)\n if (cached) {\n return cached\n }\n\n const depth = data.id[1]\n const list = Array.from<VRouteRenderComponent>({ length: depth })\n let idx = depth\n let cursor = routes.get(data.id)\n while (cursor) {\n list[idx--] = cursor.component\n cursor = cursor.parentId !== undefined ? routes.get(cursor.parentId) : undefined\n }\n\n cacheForRoutes.set(data.id, list)\n return list\n}\n","import type { VRoute, VRouteMatchedData, VRouter, VRouteRaw, VRouterData, VRouterOptions, VRoutesMap } from './types'\nimport { createRouter, findRoute } from 'rou3'\nimport { parseURL } from 'ufo'\nimport { getCurrentInstance, inject, onScopeDispose, provide, ref, shallowRef, useId, watchEffect } from 'vue'\nimport { createRenderList, registerRoutes } from './utils'\n\nexport const virouSymbol = Symbol('virou')\n\nexport function createVRouter(routes: VRouteRaw[], options?: VRouterOptions): VRouterData {\n const context = createRouter<VRouteMatchedData>()\n const routeRegistry: VRoutesMap = new Map()\n registerRoutes(context, routes, routeRegistry)\n\n const activePath = ref(options?.initialPath ?? '/')\n\n const snapshot = (): VRoute => {\n const matchedRoute = findRoute(context, 'GET', activePath.value)\n const _renderList = matchedRoute ? createRenderList(matchedRoute.data, routeRegistry) : null\n const { pathname, hash, search } = parseURL(activePath.value)\n return {\n fullPath: activePath.value,\n path: pathname,\n search,\n hash,\n meta: matchedRoute?.data.meta,\n params: matchedRoute?.params,\n _renderList,\n }\n }\n\n const route = shallowRef<VRoute>(snapshot())\n\n const unwatch = watchEffect(() => {\n route.value = snapshot()\n })\n\n return {\n context,\n routes: routeRegistry,\n activePath,\n route,\n _isGlobal: options?._isGlobal ?? false,\n _deps: 0,\n _dispose: unwatch,\n }\n}\n\nexport function useVRouter(routes?: VRouteRaw[], options?: VRouterOptions): VRouter\nexport function useVRouter(key?: string, routes?: VRouteRaw[], options?: VRouterOptions): VRouter\nexport function useVRouter(...args: any[]): VRouter {\n if (typeof args[0] !== 'string') {\n args.unshift(inject<string>(virouSymbol, useId()))\n }\n\n const [key, routes = [], options = {}] = args as [string, VRouteRaw[], VRouterOptions]\n\n if (!key || typeof key !== 'string') {\n throw new TypeError(`[virou] [useVRouter] key must be a string: ${key}`)\n }\n\n provide(virouSymbol, key)\n\n const vm = getCurrentInstance()\n if (!vm) {\n throw new TypeError('[virou] [useVRouter] useVRouter must be called in setup()')\n }\n\n const virou = vm.proxy?.$virou\n if (!virou) {\n throw new Error('[virou] [useVRouter] virou plugin not installed')\n }\n\n if (routes.length) {\n if (virou.get(key)) {\n throw new Error(`[virou] [useVRouter] router with key \"${key}\" already exists`)\n }\n\n virou.set(key, createVRouter(routes, options))\n }\n\n const router = virou.get(key)\n if (!router) {\n throw new Error(`[virou] [useVRouter] router with key \"${key}\" not found`)\n }\n\n router._deps++\n onScopeDispose(() => {\n router._deps--\n\n if (router._deps === 0 && !router._isGlobal) {\n router._dispose()\n virou.delete(key)\n }\n })\n\n return {\n route: router.route,\n router: {\n addRoute: (route: VRouteRaw) => {\n registerRoutes(router.context, [route], router.routes)\n },\n replace: (path: string) => {\n router.activePath.value = path\n },\n _depthKey: Symbol.for(key),\n },\n }\n}\n","import type { PropType, SlotsType, VNodeChild } from 'vue'\nimport type { VRoute } from './types'\nimport {\n defineComponent,\n h,\n inject,\n KeepAlive,\n provide,\n Suspense,\n} from 'vue'\nimport { useVRouter, virouSymbol } from './router'\n\nexport const VRouterView = defineComponent({\n name: 'VRouterView',\n inheritAttrs: false,\n props: {\n routerKey: String,\n keepAlive: { type: Boolean, default: false },\n viewKey: { type: [String, Function] as PropType<string | ((route: VRoute, key: string) => string)> },\n },\n slots: Object as SlotsType<{\n default: (payload: { Component: VNodeChild, route: VRoute }) => VNodeChild\n fallback: (payload: { route: VRoute }) => VNodeChild\n }>,\n setup(props, { slots, attrs }) {\n const key = props.routerKey ?? inject<string>(virouSymbol)\n if (key === undefined) {\n throw new Error('[virou] [VRouterView] routerKey is required')\n }\n\n const { route, router } = useVRouter(key)\n\n const depth = inject<number>(router._depthKey, 0)\n provide(router._depthKey, depth + 1)\n\n return () => {\n const component = route.value._renderList?.[depth]\n if (!component) {\n return slots.default?.({ Component: null, route: route.value }) ?? null\n }\n\n const vnodeKey = typeof props.viewKey === 'function'\n ? props.viewKey(route.value, key)\n : props.viewKey ?? `${key}-${depth}-${route.value.path}`\n\n const suspenseVNode = h(\n Suspense,\n null,\n {\n default: () => h(component, { key: vnodeKey, ...attrs }),\n fallback: () => slots.fallback?.({ route: route.value }) ?? null,\n },\n )\n\n const vnode = props.keepAlive\n ? h(KeepAlive, null, { default: () => suspenseVNode })\n : suspenseVNode\n\n return slots.default?.({ Component: vnode, route: route.value }) ?? vnode\n }\n },\n})\n","import type { Plugin } from 'vue'\nimport type { VirouPluginOptions, VRouterData } from './types'\nimport { createVRouter } from './router'\n\nexport const virou: Plugin<[VirouPluginOptions?]> = (app, options = {}) => {\n const { routers } = options\n\n const map = new Map<string, VRouterData>()\n app.config.globalProperties.$virou = map\n\n if (routers) {\n for (const [key, router] of Object.entries(routers)) {\n map.set(key, createVRouter(router.routes, { ...router.options, _isGlobal: true }))\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@virou/core",
3
3
  "type": "module",
4
- "version": "1.0.0",
4
+ "version": "1.1.1",
5
5
  "description": "Virtual router with multiple instance support for Vue",
6
6
  "author": "Tankosin<https://github.com/tankosinn>",
7
7
  "license": "MIT",
@@ -22,9 +22,11 @@
22
22
  ],
23
23
  "sideEffects": false,
24
24
  "exports": {
25
- "types": "./dist/index.d.mts",
26
- "default": "./dist/index.mjs"
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
27
  },
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
28
30
  "files": [
29
31
  "dist"
30
32
  ],
@@ -32,13 +34,10 @@
32
34
  "vue": "^3.5.0"
33
35
  },
34
36
  "dependencies": {
35
- "rou3": "^0.6.1",
37
+ "rou3": "^0.7.11",
36
38
  "ufo": "^1.6.1"
37
39
  },
38
- "devDependencies": {
39
- "unbuild": "3.5.0"
40
- },
41
40
  "scripts": {
42
- "build": "unbuild"
41
+ "build": "pnpm -w tsdown -F @virou/core"
43
42
  }
44
43
  }
package/dist/index.d.mts DELETED
@@ -1,107 +0,0 @@
1
- import { RouterContext } from 'rou3';
2
- import * as vue from 'vue';
3
- import { Component, DefineComponent, Ref, ShallowRef, PropType, SlotsType, VNodeChild, Plugin } from 'vue';
4
-
5
- type Lazy<T> = () => Promise<T>;
6
- type VRouteComponent = Component | DefineComponent;
7
- type VRouteLazyComponent = Lazy<VRouteComponent>;
8
- type VRouteRenderComponent = VRouteComponent | VRouteLazyComponent;
9
- type VRouteMeta = Record<PropertyKey, unknown>;
10
- interface VRouteRaw {
11
- path: string;
12
- component: VRouteRenderComponent;
13
- meta?: VRouteMeta;
14
- children?: VRouteRaw[];
15
- }
16
- type VRouteId = Readonly<[path: string, depth: number]>;
17
- interface VRouteMatchedData {
18
- id: VRouteId;
19
- meta?: VRouteMeta;
20
- }
21
- interface VRouteNormalized extends Omit<VRouteRaw, 'path' | 'children'> {
22
- parentId?: VRouteId;
23
- }
24
- type VRoutesMap = Map<VRouteId, VRouteNormalized>;
25
- interface VRoute {
26
- fullPath: string;
27
- meta?: VRouteMeta;
28
- params?: Record<string, string>;
29
- path: string;
30
- search: string;
31
- hash: string;
32
- _renderList: Component[] | null;
33
- }
34
- interface VRouterData {
35
- context: RouterContext<VRouteMatchedData>;
36
- routes: VRoutesMap;
37
- activePath: Ref<string>;
38
- route: ShallowRef<VRoute>;
39
- _isGlobal: boolean;
40
- _deps: number;
41
- _dispose: () => void;
42
- }
43
- interface VRouterOptions {
44
- initialPath?: string;
45
- _isGlobal?: boolean;
46
- }
47
- interface VRouter {
48
- route: VRouterData['route'];
49
- router: {
50
- addRoute: (route: VRouteRaw) => void;
51
- replace: (path: string) => void;
52
- _depthKey: symbol;
53
- };
54
- }
55
- interface VirouPluginOptions {
56
- routers?: Record<string, {
57
- routes: VRouteRaw[];
58
- options?: Omit<VRouterOptions, '_isGlobal'>;
59
- }>;
60
- }
61
-
62
- declare module 'vue' {
63
- interface ComponentCustomProperties {
64
- $virou: Map<string, VRouterData>
65
- }
66
- }
67
-
68
- declare const VRouterView: vue.DefineComponent<vue.ExtractPropTypes<{
69
- routerKey: StringConstructor;
70
- keepAlive: {
71
- type: BooleanConstructor;
72
- default: boolean;
73
- };
74
- viewKey: {
75
- type: PropType<string | ((route: VRoute, key: string) => string)>;
76
- };
77
- }>, () => string | number | boolean | vue.VNode<vue.RendererNode, vue.RendererElement, {
78
- [key: string]: any;
79
- }> | vue.VNodeArrayChildren | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
80
- routerKey: StringConstructor;
81
- keepAlive: {
82
- type: BooleanConstructor;
83
- default: boolean;
84
- };
85
- viewKey: {
86
- type: PropType<string | ((route: VRoute, key: string) => string)>;
87
- };
88
- }>> & Readonly<{}>, {
89
- keepAlive: boolean;
90
- }, SlotsType<{
91
- default: (payload: {
92
- Component: VNodeChild;
93
- route: VRoute;
94
- }) => VNodeChild;
95
- fallback: (payload: {
96
- route: VRoute;
97
- }) => VNodeChild;
98
- }>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
99
-
100
- declare const virou: Plugin<[VirouPluginOptions?]>;
101
-
102
- declare const virouSymbol: unique symbol;
103
- declare function createVRouter(routes: VRouteRaw[], options?: VRouterOptions): VRouterData;
104
- declare function useVRouter(routes?: VRouteRaw[], options?: VRouterOptions): VRouter;
105
- declare function useVRouter(key?: string, routes?: VRouteRaw[], options?: VRouterOptions): VRouter;
106
-
107
- export { type VRoute, type VRouteComponent, type VRouteId, type VRouteLazyComponent, type VRouteMatchedData, type VRouteMeta, type VRouteNormalized, type VRouteRaw, type VRouteRenderComponent, type VRouter, type VRouterData, type VRouterOptions, VRouterView, type VRoutesMap, type VirouPluginOptions, createVRouter, useVRouter, virou, virouSymbol };
package/dist/index.mjs DELETED
@@ -1,182 +0,0 @@
1
- import { defineAsyncComponent, ref, shallowRef, watchEffect, inject, useId, provide, getCurrentInstance, onScopeDispose, defineComponent, h, Suspense, KeepAlive } from 'vue';
2
- import { addRoute, createRouter, findRoute } from 'rou3';
3
- import { joinURL, parseURL } from 'ufo';
4
-
5
- const renderListCache = /* @__PURE__ */ new WeakMap();
6
- function normalizeComponent(component) {
7
- if (typeof component === "function" && component.length === 0) {
8
- return defineAsyncComponent(component);
9
- }
10
- return component;
11
- }
12
- function registerRoutes(ctx, routes, registry, parentId) {
13
- for (const { path, meta, component, children } of routes) {
14
- const fullPath = joinURL(parentId?.[0] ?? "/", path);
15
- const depth = (parentId?.[1] ?? -1) + 1;
16
- const id = Object.freeze([fullPath, depth]);
17
- registry.set(id, {
18
- meta,
19
- component: normalizeComponent(component),
20
- parentId
21
- });
22
- if (children && children.length) {
23
- registerRoutes(ctx, children, registry, id);
24
- }
25
- addRoute(ctx, "GET", fullPath, { id, meta });
26
- }
27
- }
28
- function createRenderList(data, routes) {
29
- let cacheForRoutes = renderListCache.get(routes);
30
- if (!cacheForRoutes) {
31
- cacheForRoutes = /* @__PURE__ */ new Map();
32
- renderListCache.set(routes, cacheForRoutes);
33
- }
34
- const cached = cacheForRoutes.get(data.id);
35
- if (cached) {
36
- return cached;
37
- }
38
- const depth = data.id[1];
39
- const list = Array.from({ length: depth });
40
- let idx = depth;
41
- let cursor = routes.get(data.id);
42
- while (cursor) {
43
- list[idx--] = cursor.component;
44
- cursor = cursor.parentId !== void 0 ? routes.get(cursor.parentId) : void 0;
45
- }
46
- cacheForRoutes.set(data.id, list);
47
- return list;
48
- }
49
-
50
- const virouSymbol = Symbol("virou");
51
- function createVRouter(routes, options) {
52
- const context = createRouter();
53
- const routeRegistry = /* @__PURE__ */ new Map();
54
- registerRoutes(context, routes, routeRegistry);
55
- const activePath = ref(options?.initialPath ?? "/");
56
- const snapshot = () => {
57
- const matchedRoute = findRoute(context, "GET", activePath.value);
58
- const _renderList = matchedRoute ? createRenderList(matchedRoute.data, routeRegistry) : null;
59
- const { pathname, hash, search } = parseURL(activePath.value);
60
- return {
61
- fullPath: activePath.value,
62
- path: pathname,
63
- search,
64
- hash,
65
- meta: matchedRoute?.data.meta,
66
- params: matchedRoute?.params,
67
- _renderList
68
- };
69
- };
70
- const route = shallowRef(snapshot());
71
- const unwatch = watchEffect(() => {
72
- route.value = snapshot();
73
- });
74
- return {
75
- context,
76
- routes: routeRegistry,
77
- activePath,
78
- route,
79
- _isGlobal: options?._isGlobal ?? false,
80
- _deps: 0,
81
- _dispose: unwatch
82
- };
83
- }
84
- function useVRouter(...args) {
85
- if (typeof args[0] !== "string") {
86
- args.unshift(inject(virouSymbol, useId()));
87
- }
88
- const [key, routes = [], options = {}] = args;
89
- if (!key || typeof key !== "string") {
90
- throw new TypeError(`[virou] [useVRouter] key must be a string: ${key}`);
91
- }
92
- provide(virouSymbol, key);
93
- const vm = getCurrentInstance();
94
- if (!vm) {
95
- throw new TypeError("[virou] [useVRouter] useVRouter must be called in setup()");
96
- }
97
- const virou = vm.proxy?.$virou;
98
- if (!virou) {
99
- throw new Error("[virou] [useVRouter] virou plugin not installed");
100
- }
101
- if (routes.length) {
102
- if (virou.get(key)) {
103
- throw new Error(`[virou] [useVRouter] router with key "${key}" already exists`);
104
- }
105
- virou.set(key, createVRouter(routes, options));
106
- }
107
- const router = virou.get(key);
108
- if (!router) {
109
- throw new Error(`[virou] [useVRouter] router with key "${key}" not found`);
110
- }
111
- router._deps++;
112
- onScopeDispose(() => {
113
- router._deps--;
114
- if (router._deps === 0 && !router._isGlobal) {
115
- router._dispose();
116
- virou.delete(key);
117
- }
118
- });
119
- return {
120
- route: router.route,
121
- router: {
122
- addRoute: (route) => {
123
- registerRoutes(router.context, [route], router.routes);
124
- },
125
- replace: (path) => {
126
- router.activePath.value = path;
127
- },
128
- _depthKey: Symbol.for(key)
129
- }
130
- };
131
- }
132
-
133
- const VRouterView = defineComponent({
134
- name: "VRouterView",
135
- inheritAttrs: false,
136
- props: {
137
- routerKey: String,
138
- keepAlive: { type: Boolean, default: false },
139
- viewKey: { type: [String, Function] }
140
- },
141
- slots: Object,
142
- setup(props, { slots, attrs }) {
143
- const key = props.routerKey ?? inject(virouSymbol);
144
- if (key === void 0) {
145
- throw new Error("[virou] [VRouterView] routerKey is required");
146
- }
147
- const { route, router } = useVRouter(key);
148
- const depth = inject(router._depthKey, 0);
149
- provide(router._depthKey, depth + 1);
150
- return () => {
151
- const component = route.value._renderList?.[depth];
152
- if (!component) {
153
- return slots.default?.({ Component: null, route: route.value }) ?? null;
154
- }
155
- const vnodeKey = typeof props.viewKey === "function" ? props.viewKey(route.value, key) : props.viewKey ?? `${key}-${depth}-${route.value.path}`;
156
- const suspenseVNode = h(
157
- Suspense,
158
- null,
159
- {
160
- default: () => h(component, { key: vnodeKey, ...attrs }),
161
- fallback: () => slots.fallback?.({ route: route.value }) ?? null
162
- }
163
- );
164
- const vnode = props.keepAlive ? h(KeepAlive, null, { default: () => suspenseVNode }) : suspenseVNode;
165
- return slots.default?.({ Component: vnode, route: route.value }) ?? vnode;
166
- };
167
- }
168
- });
169
-
170
- const virou = (app, options = {}) => {
171
- const { routers } = options;
172
- const map = /* @__PURE__ */ new Map();
173
- app.config.globalProperties.$virou = map;
174
- app.component("VRouterView", VRouterView);
175
- if (routers) {
176
- for (const [key, router] of Object.entries(routers)) {
177
- map.set(key, createVRouter(router.routes, { ...router.options, _isGlobal: true }));
178
- }
179
- }
180
- };
181
-
182
- export { VRouterView, createVRouter, useVRouter, virou, virouSymbol };