wevu 6.7.7 → 6.9.0

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
@@ -14,7 +14,7 @@ Vue 3 风格的小程序运行时,复用同款响应式与调度器,通过
14
14
  ## 安装
15
15
 
16
16
  ```bash
17
- pnpm add wevu
17
+ pnpm add -D wevu
18
18
  # 或 npm/yarn/pnpm dlx 按需安装
19
19
  ```
20
20
 
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { A as track, C as effect, D as onScopeDispose, E as getCurrentScope, M as triggerEffects, N as nextTick, O as startBatch, P as queueJob, S as batch, T as endBatch, _ as ReactiveFlags, a as toValue, b as addMutationRecorder, c as isRaw, d as reactive, f as isShallowReactive, g as touchReactive, h as prelinkReactiveTree, i as ref, j as trigger, k as stop, l as isReactive, m as clearPatchIndices, n as isRef, o as unref, p as shallowReactive, r as markAsRef, s as getReactiveVersion, t as customRef, u as markRaw, v as isObject$1, w as effectScope, x as removeMutationRecorder, y as toRaw } from "./ref-BjmD-qct.mjs";
2
2
  import { i as computed, n as defineStore, r as createStore, t as storeToRefs } from "./store-Ct-o7qtH.mjs";
3
- import { A as getCurrentInstance, C as onTabItemTap, D as assertInSetup, E as onUnload, F as getMiniProgramGlobalObject, I as getScopedSlotHostGlobalObject, L as readonly, M as pushHook, N as setCurrentInstance, O as callHookList, P as setCurrentSetupContext, S as onShow, T as onUnhandledRejection, _ as onResize, a as onDetached, b as onShareAppMessage, c as onLaunch, d as onMoved, f as onPageNotFound, g as onReady, h as onReachBottom, i as onAttached, j as getCurrentSetupContext, k as callHookReturn, l as onLoad, m as onPullDownRefresh, n as useNativeRouter, o as onError, p as onPageScroll, r as onAddToFavorites, s as onHide, t as useNativePageRouter, u as onMemoryWarning, v as onRouteDone, w as onThemeChange, x as onShareTimeline, y as onSaveExitState } from "./router-CcoGUezU.mjs";
3
+ import { A as onUnload, B as getScopedSlotHostGlobalObject, C as onSaveExitState, D as onTabItemTap, E as onShow, F as getCurrentSetupContext, I as pushHook, L as setCurrentInstance, M as callHookList, N as callHookReturn, O as onThemeChange, P as getCurrentInstance, R as setCurrentSetupContext, S as onRouteDone, T as onShareTimeline, V as readonly, _ as onPageScroll, a as provide, b as onReady, c as onAttached, d as onHide, f as onLaunch, g as onPageNotFound, h as onMoved, i as injectGlobal, j as assertInSetup, k as onUnhandledRejection, l as onDetached, m as onMemoryWarning, n as useNativeRouter, o as provideGlobal, p as onLoad, r as inject, s as onAddToFavorites, t as useNativePageRouter, u as onError, v as onPullDownRefresh, w as onShareAppMessage, x as onResize, y as onReachBottom, z as getMiniProgramGlobalObject } from "./router-BoEmd9rt.mjs";
4
4
  //#region src/reactivity/shallowRef.ts
5
5
  /**
6
6
  * 创建一个“浅层” ref:它只在 .value 被整体替换时触发依赖,不会对内部对象做深层响应式处理。
@@ -4651,87 +4651,6 @@ function usePageScrollThrottle(handler, options = {}) {
4651
4651
  return stop;
4652
4652
  }
4653
4653
  //#endregion
4654
- //#region src/runtime/provide.ts
4655
- const PROVIDE_SCOPE_KEY = Symbol("wevu.provideScope");
4656
- const __wevuGlobalProvideStore = /* @__PURE__ */ new Map();
4657
- /**
4658
- * 在组件上下文中向后代注入值(与 Vue 3 行为兼容),若没有当前实例则回落到全局存储。
4659
- *
4660
- * @param key 注入键,可为字符串、Symbol 或对象
4661
- * @param value 提供的值
4662
- *
4663
- * @example
4664
- * ```ts
4665
- * defineComponent({
4666
- * setup() {
4667
- * provide(TOKEN_KEY, { data: 'value' })
4668
- * }
4669
- * })
4670
- * ```
4671
- */
4672
- function provide(key, value) {
4673
- const instance = getCurrentInstance();
4674
- if (instance) {
4675
- let scope = instance[PROVIDE_SCOPE_KEY];
4676
- if (!scope) {
4677
- scope = /* @__PURE__ */ new Map();
4678
- instance[PROVIDE_SCOPE_KEY] = scope;
4679
- }
4680
- scope.set(key, value);
4681
- } else __wevuGlobalProvideStore.set(key, value);
4682
- }
4683
- /**
4684
- * 从祖先组件(或全局存储)读取提供的值。
4685
- *
4686
- * @param key 注入键,需与 provide 使用的键保持一致
4687
- * @param defaultValue 未找到提供者时的默认值
4688
- * @returns 匹配到的值或默认值
4689
- *
4690
- * @example
4691
- * ```ts
4692
- * defineComponent({
4693
- * setup() {
4694
- * const data = inject(TOKEN_KEY)
4695
- * const value = inject('key', 'default')
4696
- * }
4697
- * })
4698
- * ```
4699
- */
4700
- function inject(key, defaultValue) {
4701
- const instance = getCurrentInstance();
4702
- if (instance) {
4703
- let current = instance;
4704
- while (current) {
4705
- const scope = current[PROVIDE_SCOPE_KEY];
4706
- if (scope && scope.has(key)) return scope.get(key);
4707
- current = null;
4708
- }
4709
- }
4710
- if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
4711
- if (arguments.length >= 2) return defaultValue;
4712
- throw new Error("wevu.inject:未找到对应 key 的值");
4713
- }
4714
- /**
4715
- * 全局注入值,适用于历史兼容场景。
4716
- *
4717
- * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `provide()`,
4718
- * 在无实例上下文时 `provide()` 会自动回落到全局存储。
4719
- */
4720
- function provideGlobal(key, value) {
4721
- __wevuGlobalProvideStore.set(key, value);
4722
- }
4723
- /**
4724
- * 从全局存储读取值,适用于历史兼容场景。
4725
- *
4726
- * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `inject()`,
4727
- * 在无实例上下文时 `inject()` 会自动从全局存储读取。
4728
- */
4729
- function injectGlobal(key, defaultValue) {
4730
- if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
4731
- if (arguments.length >= 2) return defaultValue;
4732
- throw new Error(`injectGlobal():未找到对应 key 的 provider:${String(key)}`);
4733
- }
4734
- //#endregion
4735
4654
  //#region src/runtime/template.ts
4736
4655
  const hyphenateRE = /\B([A-Z])/g;
4737
4656
  function hyphenate(value) {
@@ -262,6 +262,87 @@ function onAddToFavorites(handler) {
262
262
  ensureSinglePageHookOnInstance(instance, "onAddToFavorites");
263
263
  }
264
264
  //#endregion
265
+ //#region src/runtime/provide.ts
266
+ const PROVIDE_SCOPE_KEY = Symbol("wevu.provideScope");
267
+ const __wevuGlobalProvideStore = /* @__PURE__ */ new Map();
268
+ /**
269
+ * 在组件上下文中向后代注入值(与 Vue 3 行为兼容),若没有当前实例则回落到全局存储。
270
+ *
271
+ * @param key 注入键,可为字符串、Symbol 或对象
272
+ * @param value 提供的值
273
+ *
274
+ * @example
275
+ * ```ts
276
+ * defineComponent({
277
+ * setup() {
278
+ * provide(TOKEN_KEY, { data: 'value' })
279
+ * }
280
+ * })
281
+ * ```
282
+ */
283
+ function provide(key, value) {
284
+ const instance = getCurrentInstance();
285
+ if (instance) {
286
+ let scope = instance[PROVIDE_SCOPE_KEY];
287
+ if (!scope) {
288
+ scope = /* @__PURE__ */ new Map();
289
+ instance[PROVIDE_SCOPE_KEY] = scope;
290
+ }
291
+ scope.set(key, value);
292
+ } else __wevuGlobalProvideStore.set(key, value);
293
+ }
294
+ /**
295
+ * 从祖先组件(或全局存储)读取提供的值。
296
+ *
297
+ * @param key 注入键,需与 provide 使用的键保持一致
298
+ * @param defaultValue 未找到提供者时的默认值
299
+ * @returns 匹配到的值或默认值
300
+ *
301
+ * @example
302
+ * ```ts
303
+ * defineComponent({
304
+ * setup() {
305
+ * const data = inject(TOKEN_KEY)
306
+ * const value = inject('key', 'default')
307
+ * }
308
+ * })
309
+ * ```
310
+ */
311
+ function inject(key, defaultValue) {
312
+ const instance = getCurrentInstance();
313
+ if (instance) {
314
+ let current = instance;
315
+ while (current) {
316
+ const scope = current[PROVIDE_SCOPE_KEY];
317
+ if (scope && scope.has(key)) return scope.get(key);
318
+ current = null;
319
+ }
320
+ }
321
+ if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
322
+ if (arguments.length >= 2) return defaultValue;
323
+ throw new Error("wevu.inject:未找到对应 key 的值");
324
+ }
325
+ /**
326
+ * 全局注入值,适用于历史兼容场景。
327
+ *
328
+ * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `provide()`,
329
+ * 在无实例上下文时 `provide()` 会自动回落到全局存储。
330
+ */
331
+ function provideGlobal(key, value) {
332
+ __wevuGlobalProvideStore.set(key, value);
333
+ }
334
+ /**
335
+ * 从全局存储读取值,适用于历史兼容场景。
336
+ *
337
+ * @deprecated 已弃用,仅用于兼容/过渡。推荐优先使用 `inject()`,
338
+ * 在无实例上下文时 `inject()` 会自动从全局存储读取。
339
+ */
340
+ function injectGlobal(key, defaultValue) {
341
+ if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
342
+ if (arguments.length >= 2) return defaultValue;
343
+ throw new Error(`injectGlobal():未找到对应 key 的 provider:${String(key)}`);
344
+ }
345
+ //#endregion
265
346
  //#region src/runtime/vueCompat/router.ts
266
347
  const RUNTIME_ROUTER_METHODS = [
267
348
  "switchTab",
@@ -326,4 +407,4 @@ function useNativePageRouter() {
326
407
  return useRuntimeRouterByAccessor("pageRouter", "router", "useNativePageRouter");
327
408
  }
328
409
  //#endregion
329
- export { getCurrentInstance as A, onTabItemTap as C, assertInSetup as D, onUnload as E, getMiniProgramGlobalObject as F, getScopedSlotHostGlobalObject as I, readonly as L, pushHook as M, setCurrentInstance as N, callHookList as O, setCurrentSetupContext as P, onShow as S, onUnhandledRejection as T, onResize as _, onDetached as a, onShareAppMessage as b, onLaunch as c, onMoved as d, onPageNotFound as f, onReady as g, onReachBottom as h, onAttached as i, getCurrentSetupContext as j, callHookReturn as k, onLoad as l, onPullDownRefresh as m, useNativeRouter as n, onError as o, onPageScroll as p, onAddToFavorites as r, onHide as s, useNativePageRouter as t, onMemoryWarning as u, onRouteDone as v, onThemeChange as w, onShareTimeline as x, onSaveExitState as y };
410
+ export { onUnload as A, getScopedSlotHostGlobalObject as B, onSaveExitState as C, onTabItemTap as D, onShow as E, getCurrentSetupContext as F, pushHook as I, setCurrentInstance as L, callHookList as M, callHookReturn as N, onThemeChange as O, getCurrentInstance as P, setCurrentSetupContext as R, onRouteDone as S, onShareTimeline as T, readonly as V, onPageScroll as _, provide as a, onReady as b, onAttached as c, onHide as d, onLaunch as f, onPageNotFound as g, onMoved as h, injectGlobal as i, assertInSetup as j, onUnhandledRejection as k, onDetached as l, onMemoryWarning as m, useNativeRouter as n, provideGlobal as o, onLoad as p, inject as r, onAddToFavorites as s, useNativePageRouter as t, onError as u, onPullDownRefresh as v, onShareAppMessage as w, onResize as x, onReachBottom as y, getMiniProgramGlobalObject as z };
package/dist/router.d.mts CHANGED
@@ -27,6 +27,15 @@ interface NamedRouteRecord {
27
27
  name: string;
28
28
  path: string;
29
29
  }
30
+ interface RouteRecordInput {
31
+ name?: string;
32
+ path: string;
33
+ meta?: RouteMeta;
34
+ alias?: string | readonly string[];
35
+ children?: readonly RouteRecordInput[];
36
+ beforeEnter?: NavigationGuard | readonly NavigationGuard[];
37
+ redirect?: RouteRecordRedirect;
38
+ }
30
39
  type NamedRoutes = Readonly<Record<string, string>> | readonly RouteRecordRaw[];
31
40
  type RouteLocationRaw = string | {
32
41
  path?: string;
@@ -68,12 +77,8 @@ interface NavigationRedirect {
68
77
  replace?: boolean;
69
78
  }
70
79
  type RouteRecordRedirect = RouteLocationRaw | NavigationRedirect | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => RouteLocationRaw | NavigationRedirect | Promise<RouteLocationRaw | NavigationRedirect>);
71
- interface RouteRecordRaw extends NamedRouteRecord {
72
- meta?: RouteMeta;
73
- alias?: string | readonly string[];
80
+ interface RouteRecordRaw extends Omit<RouteRecordInput, 'name' | 'children'>, NamedRouteRecord {
74
81
  children?: readonly RouteRecordRaw[];
75
- beforeEnter?: NavigationGuard | readonly NavigationGuard[];
76
- redirect?: RouteRecordRedirect;
77
82
  }
78
83
  interface RouteRecordMatched {
79
84
  name: string;
@@ -121,7 +126,7 @@ interface UseRouterOptions {
121
126
  /**
122
127
  * Vue Router 对齐入口:推荐使用 `routes`
123
128
  */
124
- routes?: readonly RouteRecordRaw[];
129
+ routes?: readonly RouteRecordInput[];
125
130
  /**
126
131
  * 兼容入口:支持对象 map 或路由记录数组
127
132
  */
@@ -165,6 +170,12 @@ interface AddRoute {
165
170
  (parentName: string, route: RouteRecordRaw): () => void;
166
171
  }
167
172
  //#endregion
173
+ //#region src/router/createRouter.d.ts
174
+ /**
175
+ * @description 创建高阶路由导航器(对齐 Vue Router 的 createRouter 心智)
176
+ */
177
+ declare function createRouter(options?: UseRouterOptions): RouterNavigation;
178
+ //#endregion
168
179
  //#region src/router/navigationCore.d.ts
169
180
  declare function createNavigationFailure(type: NavigationFailureTypeValue, to?: RouteLocationNormalizedLoaded, from?: RouteLocationNormalizedLoaded, cause?: unknown): NavigationFailure;
170
181
  declare function isNavigationFailure(error: unknown, type?: NavigationFailureTypeValue): error is NavigationFailure;
@@ -185,8 +196,8 @@ declare function useNativePageRouter(): SetupContextRouter;
185
196
  //#endregion
186
197
  //#region src/router/useRouter.d.ts
187
198
  /**
188
- * @description 获取高阶路由导航器(对齐 Vue Router 心智)
199
+ * @description 获取当前已创建的路由实例。
189
200
  */
190
- declare function useRouter(options?: UseRouterOptions): RouterNavigation;
201
+ declare function useRouter(): RouterNavigation;
191
202
  //#endregion
192
- export { type AddRoute, type LocationQuery, type LocationQueryRaw, type LocationQueryValue, type LocationQueryValueRaw, type NamedRouteRecord, type NamedRoutes, type NavigationAfterEach, type NavigationAfterEachContext, type NavigationErrorContext, type NavigationErrorHandler, type NavigationFailure, NavigationFailureType, type NavigationFailureTypeValue, type NavigationGuard, type NavigationGuardContext, type NavigationGuardResult, type NavigationMode, type NavigationRedirect, type RouteLocationNormalizedLoaded, type RouteLocationRaw, type RouteLocationRedirectedFrom, type RouteMeta, type RouteParamValue, type RouteParamValueRaw, type RouteParams, type RouteParamsMode, type RouteParamsRaw, type RouteQueryParser, type RouteQueryStringifier, type RouteRecordMatched, type RouteRecordRaw, type RouteRecordRedirect, type RouterNavigateToOption, type RouterNavigation, type RouterReLaunchOption, type RouterRedirectToOption, type RouterSwitchTabOption, type SetupContextRouter, type TypedRouterTabBarUrl, type TypedRouterUrl, type UseRouterOptions, type WevuTypedRouterRouteMap, createNavigationFailure, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
203
+ export { type AddRoute, type LocationQuery, type LocationQueryRaw, type LocationQueryValue, type LocationQueryValueRaw, type NamedRouteRecord, type NamedRoutes, type NavigationAfterEach, type NavigationAfterEachContext, type NavigationErrorContext, type NavigationErrorHandler, type NavigationFailure, NavigationFailureType, type NavigationFailureTypeValue, type NavigationGuard, type NavigationGuardContext, type NavigationGuardResult, type NavigationMode, type NavigationRedirect, type RouteLocationNormalizedLoaded, type RouteLocationRaw, type RouteLocationRedirectedFrom, type RouteMeta, type RouteParamValue, type RouteParamValueRaw, type RouteParams, type RouteParamsMode, type RouteParamsRaw, type RouteQueryParser, type RouteQueryStringifier, type RouteRecordInput, type RouteRecordMatched, type RouteRecordRaw, type RouteRecordRedirect, type RouterNavigateToOption, type RouterNavigation, type RouterReLaunchOption, type RouterRedirectToOption, type RouterSwitchTabOption, type SetupContextRouter, type TypedRouterTabBarUrl, type TypedRouterUrl, type UseRouterOptions, type WevuTypedRouterRouteMap, createNavigationFailure, createRouter, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
package/dist/router.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as reactive } from "./ref-BjmD-qct.mjs";
2
- import { L as readonly, S as onShow, j as getCurrentSetupContext, l as onLoad, n as useNativeRouter$1, t as useNativePageRouter$1, v as onRouteDone } from "./router-CcoGUezU.mjs";
2
+ import { E as onShow, F as getCurrentSetupContext, S as onRouteDone, V as readonly, i as injectGlobal, n as useNativeRouter$1, o as provideGlobal, p as onLoad, t as useNativePageRouter$1 } from "./router-BoEmd9rt.mjs";
3
3
  //#region src/routerInternal/path.ts
4
4
  function normalizePathSegments(path) {
5
5
  const segments = [];
@@ -283,7 +283,7 @@ function resolveNamedRouteLocation(to, lookup, paramsMode) {
283
283
  if (typeof routeName !== "string" || !routeName) return to;
284
284
  if (to.path !== void 0 || to.fullPath !== void 0) return to;
285
285
  const routeRecord = lookup.recordByName.get(routeName);
286
- if (!routeRecord) throw new Error(`Named route "${routeName}" is not defined in useRouter({ routes | namedRoutes })`);
286
+ if (!routeRecord) throw new Error(`Named route "${routeName}" is not defined in createRouter({ routes | namedRoutes })`);
287
287
  const params = to.params ? normalizeRouteParams(to.params) : {};
288
288
  const resolvedResult = resolveNamedRoutePath(routeRecord.path, params, routeName);
289
289
  if (paramsMode === "strict") assertNoUnexpectedNamedRouteParams(params, resolvedResult.consumedKeys, routeName);
@@ -466,7 +466,7 @@ function warnDuplicateRouteEntries(routeEntries) {
466
466
  const duplicateMessages = [];
467
467
  for (const routeEntry of routeEntries) {
468
468
  var _routeEntry$source;
469
- const routeName = routeEntry.route.name.trim();
469
+ const routeName = typeof routeEntry.route.name === "string" ? routeEntry.route.name.trim() : "";
470
470
  if (!routeName) continue;
471
471
  const currentSource = (_routeEntry$source = routeEntry.source) !== null && _routeEntry$source !== void 0 ? _routeEntry$source : "namedRoutes";
472
472
  const currentPath = formatRoutePathForWarning(routeEntry.route.path);
@@ -487,11 +487,16 @@ function normalizeBeforeEnterGuards(beforeEnter) {
487
487
  if (Array.isArray(beforeEnter)) return beforeEnter;
488
488
  return [beforeEnter];
489
489
  }
490
- function normalizeRouteRecordRaw(route, parentName) {
491
- const routeName = route.name.trim();
492
- if (!routeName) return;
490
+ function resolveRouteRecordName(route, normalizedPath, source = "namedRoutes") {
491
+ if (typeof route.name === "string" && route.name.trim()) return route.name.trim();
492
+ if (source === "routes") return normalizedPath || "/";
493
+ return "";
494
+ }
495
+ function normalizeRouteRecordRaw(route, parentName, source = "namedRoutes") {
493
496
  const normalizedPath = resolvePath(route.path, "");
494
- if (!normalizedPath) return;
497
+ if (!normalizedPath && route.path !== "/") return;
498
+ const routeName = resolveRouteRecordName(route, normalizedPath, source);
499
+ if (!routeName) return;
495
500
  return {
496
501
  name: routeName,
497
502
  path: normalizedPath,
@@ -571,16 +576,16 @@ function flattenNamedRouteRecords(records, parentPath, parentName, parentAliasPa
571
576
  warnRouteConfig(`ignored route record at ${routeConfigPath}: detected circular children reference`);
572
577
  continue;
573
578
  }
574
- const routeName = typeof (record === null || record === void 0 ? void 0 : record.name) === "string" ? record.name.trim() : "";
575
- if (!routeName) {
576
- warnRouteConfig(`ignored route record at ${routeConfigPath}: route name is required`);
577
- continue;
578
- }
579
579
  if (typeof record.path !== "string" || !record.path) {
580
- warnRouteConfig(`ignored route record "${routeName}" at ${routeConfigPath}: route path is required`);
580
+ warnRouteConfig(`ignored route record "${typeof (record === null || record === void 0 ? void 0 : record.name) === "string" ? record.name.trim() : ""}" at ${routeConfigPath}: route path is required`);
581
581
  continue;
582
582
  }
583
583
  const normalizedPath = normalizeNestedRoutePath(record.path, parentPath);
584
+ const routeName = resolveRouteRecordName(record, normalizedPath, source);
585
+ if (!routeName) {
586
+ warnRouteConfig(`ignored route record at ${routeConfigPath}: route name is required`);
587
+ continue;
588
+ }
584
589
  const normalizedDirectAliasPaths = [];
585
590
  const directAliasByNormalizedPath = /* @__PURE__ */ new Map();
586
591
  for (const rawAliasPath of normalizeAliasInputList(record.alias)) {
@@ -601,10 +606,12 @@ function flattenNamedRouteRecords(records, parentPath, parentName, parentAliasPa
601
606
  const normalizedInheritedAliasPaths = record.path.startsWith("/") ? [] : parentAliasPaths.map((parentAliasPath) => normalizeNestedRoutePath(record.path, parentAliasPath)).filter(Boolean).filter((aliasPath) => aliasPath !== normalizedPath);
602
607
  const normalizedAliasPaths = mergeAliasPaths([...normalizedDirectAliasPaths, ...normalizedInheritedAliasPaths]);
603
608
  const normalizedRecord = {
604
- ...record,
605
609
  name: routeName,
606
610
  path: normalizedPath ? createAbsoluteRoutePath(normalizedPath) : "/",
607
- alias: createRouteRecordAliasValue(normalizedAliasPaths)
611
+ alias: createRouteRecordAliasValue(normalizedAliasPaths),
612
+ meta: record.meta,
613
+ beforeEnter: record.beforeEnter,
614
+ redirect: record.redirect
608
615
  };
609
616
  flattenedRecords.push({
610
617
  route: normalizedRecord,
@@ -630,7 +637,7 @@ function createNamedRouteNameByStaticPath(recordByName) {
630
637
  function createNamedRouteLookup(routeEntries) {
631
638
  const recordByName = /* @__PURE__ */ new Map();
632
639
  for (const routeRecord of routeEntries) {
633
- const normalizedRecord = normalizeRouteRecordRaw(routeRecord.route, routeRecord.parentName);
640
+ const normalizedRecord = normalizeRouteRecordRaw(routeRecord.route, routeRecord.parentName, routeRecord.source);
634
641
  if (!normalizedRecord) continue;
635
642
  recordByName.set(normalizedRecord.name, normalizedRecord);
636
643
  }
@@ -760,6 +767,18 @@ function hasLocationQuery(query) {
760
767
  return Object.keys(query).length > 0;
761
768
  }
762
769
  //#endregion
770
+ //#region src/router/instance.ts
771
+ const ROUTER_INSTANCE_KEY = Symbol("wevu.router.instance");
772
+ let activeRouter;
773
+ function setActiveRouter(router) {
774
+ activeRouter = router;
775
+ provideGlobal(ROUTER_INSTANCE_KEY, router);
776
+ }
777
+ function getActiveRouter() {
778
+ var _activeRouter;
779
+ return (_activeRouter = activeRouter) !== null && _activeRouter !== void 0 ? _activeRouter : injectGlobal(ROUTER_INSTANCE_KEY, void 0);
780
+ }
781
+ //#endregion
763
782
  //#region src/router/types.ts
764
783
  const NavigationFailureType = {
765
784
  unknown: 1,
@@ -902,69 +921,6 @@ function shouldEmitNavigationError(failure) {
902
921
  return false;
903
922
  }
904
923
  //#endregion
905
- //#region src/router/resolve.ts
906
- const DEFAULT_ROUTE_RESOLVE_CODEC = {
907
- parseQuery,
908
- stringifyQuery
909
- };
910
- function resolveRouteLocation(to, currentPath = "", codec = DEFAULT_ROUTE_RESOLVE_CODEC) {
911
- var _ref, _to$path, _parsedFromFullPath$q, _to$hash;
912
- if (typeof to === "string") {
913
- const parsed = parsePathInput(to, codec);
914
- return createRouteLocation(resolvePath(parsed.path, currentPath), parsed.query, parsed.hash, void 0, {}, codec.stringifyQuery);
915
- }
916
- const parsedFromFullPath = typeof to.fullPath === "string" ? parsePathInput(to.fullPath, codec) : void 0;
917
- return createRouteLocation(resolvePath((_ref = (_to$path = to.path) !== null && _to$path !== void 0 ? _to$path : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.path) !== null && _ref !== void 0 ? _ref : currentPath, currentPath), to.query ? normalizeQuery(to.query) : (_parsedFromFullPath$q = parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.query) !== null && _parsedFromFullPath$q !== void 0 ? _parsedFromFullPath$q : {}, normalizeHash((_to$hash = to.hash) !== null && _to$hash !== void 0 ? _to$hash : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.hash), typeof to.name === "string" ? to.name : void 0, to.params ? normalizeRouteParams(to.params) : {}, codec.stringifyQuery);
918
- }
919
- //#endregion
920
- //#region src/router/useRoute.ts
921
- function useRoute() {
922
- if (!getCurrentSetupContext()) throw new Error("useRoute() 必须在 setup() 的同步阶段调用");
923
- const currentRoute = resolveCurrentRoute();
924
- const routeState = reactive({
925
- path: currentRoute.path,
926
- fullPath: currentRoute.fullPath,
927
- query: currentRoute.query,
928
- hash: currentRoute.hash,
929
- params: currentRoute.params,
930
- name: currentRoute.name
931
- });
932
- if (currentRoute.meta !== void 0) routeState.meta = currentRoute.meta;
933
- function syncRoute(queryOverride) {
934
- const nextRoute = resolveCurrentRoute(queryOverride);
935
- routeState.path = nextRoute.path;
936
- routeState.fullPath = nextRoute.fullPath;
937
- routeState.query = nextRoute.query;
938
- routeState.hash = nextRoute.hash;
939
- if (nextRoute.meta === void 0) delete routeState.meta;
940
- else routeState.meta = nextRoute.meta;
941
- routeState.params = nextRoute.params;
942
- routeState.name = nextRoute.name;
943
- }
944
- onLoad((query) => {
945
- syncRoute(query);
946
- });
947
- onShow(() => {
948
- syncRoute();
949
- });
950
- onRouteDone(() => {
951
- syncRoute();
952
- });
953
- return readonly(routeState);
954
- }
955
- /**
956
- * @description 获取当前组件路径语义的原生 Router
957
- */
958
- function useNativeRouter() {
959
- return useNativeRouter$1();
960
- }
961
- /**
962
- * @description 获取当前页面路径语义的原生 Page Router
963
- */
964
- function useNativePageRouter() {
965
- return useNativePageRouter$1();
966
- }
967
- //#endregion
968
924
  //#region src/router/navigationResult.ts
969
925
  function createNavigationRunResult(mode, from, to, failure) {
970
926
  return {
@@ -1231,6 +1187,21 @@ function createNavigationApi(options) {
1231
1187
  };
1232
1188
  }
1233
1189
  //#endregion
1190
+ //#region src/router/resolve.ts
1191
+ const DEFAULT_ROUTE_RESOLVE_CODEC = {
1192
+ parseQuery,
1193
+ stringifyQuery
1194
+ };
1195
+ function resolveRouteLocation(to, currentPath = "", codec = DEFAULT_ROUTE_RESOLVE_CODEC) {
1196
+ var _ref, _to$path, _parsedFromFullPath$q, _to$hash;
1197
+ if (typeof to === "string") {
1198
+ const parsed = parsePathInput(to, codec);
1199
+ return createRouteLocation(resolvePath(parsed.path, currentPath), parsed.query, parsed.hash, void 0, {}, codec.stringifyQuery);
1200
+ }
1201
+ const parsedFromFullPath = typeof to.fullPath === "string" ? parsePathInput(to.fullPath, codec) : void 0;
1202
+ return createRouteLocation(resolvePath((_ref = (_to$path = to.path) !== null && _to$path !== void 0 ? _to$path : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.path) !== null && _ref !== void 0 ? _ref : currentPath, currentPath), to.query ? normalizeQuery(to.query) : (_parsedFromFullPath$q = parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.query) !== null && _parsedFromFullPath$q !== void 0 ? _parsedFromFullPath$q : {}, normalizeHash((_to$hash = to.hash) !== null && _to$hash !== void 0 ? _to$hash : parsedFromFullPath === null || parsedFromFullPath === void 0 ? void 0 : parsedFromFullPath.hash), typeof to.name === "string" ? to.name : void 0, to.params ? normalizeRouteParams(to.params) : {}, codec.stringifyQuery);
1203
+ }
1204
+ //#endregion
1234
1205
  //#region src/router/routeRegistry.ts
1235
1206
  function normalizeRouteRecordForOutput(record) {
1236
1207
  const normalizedRoute = {
@@ -1254,7 +1225,7 @@ function createRouteRegistry(namedRouteLookup) {
1254
1225
  assertValidAddRouteInput(route);
1255
1226
  const parentRouteName = typeof parentNameOrRoute === "string" ? parentNameOrRoute : void 0;
1256
1227
  const parentRouteRecord = parentRouteName ? namedRouteLookup.recordByName.get(parentRouteName) : void 0;
1257
- if (parentRouteName && !parentRouteRecord) throw new Error(`Parent route "${parentRouteName}" is not defined in useRouter({ routes | namedRoutes })`);
1228
+ if (parentRouteName && !parentRouteRecord) throw new Error(`Parent route "${parentRouteName}" is not defined in createRouter({ routes | namedRoutes })`);
1258
1229
  const routeRecords = flattenNamedRouteRecords([route], parentRouteRecord === null || parentRouteRecord === void 0 ? void 0 : parentRouteRecord.path, parentRouteName, parentRouteRecord === null || parentRouteRecord === void 0 ? void 0 : parentRouteRecord.aliasPaths, void 0, "addRoute");
1259
1230
  if (routeRecords.length === 0) throw new Error("Route name and path are required when adding a named route");
1260
1231
  const addedRoutes = [];
@@ -1300,11 +1271,59 @@ function createRouteRegistry(namedRouteLookup) {
1300
1271
  };
1301
1272
  }
1302
1273
  //#endregion
1303
- //#region src/router/useRouter.ts
1274
+ //#region src/router/useRoute.ts
1275
+ function useRoute() {
1276
+ if (!getCurrentSetupContext()) throw new Error("useRoute() 必须在 setup() 的同步阶段调用");
1277
+ const currentRoute = resolveCurrentRoute();
1278
+ const routeState = reactive({
1279
+ path: currentRoute.path,
1280
+ fullPath: currentRoute.fullPath,
1281
+ query: currentRoute.query,
1282
+ hash: currentRoute.hash,
1283
+ params: currentRoute.params,
1284
+ name: currentRoute.name
1285
+ });
1286
+ if (currentRoute.meta !== void 0) routeState.meta = currentRoute.meta;
1287
+ function syncRoute(queryOverride) {
1288
+ const nextRoute = resolveCurrentRoute(queryOverride);
1289
+ routeState.path = nextRoute.path;
1290
+ routeState.fullPath = nextRoute.fullPath;
1291
+ routeState.query = nextRoute.query;
1292
+ routeState.hash = nextRoute.hash;
1293
+ if (nextRoute.meta === void 0) delete routeState.meta;
1294
+ else routeState.meta = nextRoute.meta;
1295
+ routeState.params = nextRoute.params;
1296
+ routeState.name = nextRoute.name;
1297
+ }
1298
+ onLoad((query) => {
1299
+ syncRoute(query);
1300
+ });
1301
+ onShow(() => {
1302
+ syncRoute();
1303
+ });
1304
+ onRouteDone(() => {
1305
+ syncRoute();
1306
+ });
1307
+ return readonly(routeState);
1308
+ }
1304
1309
  /**
1305
- * @description 获取高阶路由导航器(对齐 Vue Router 心智)
1310
+ * @description 获取当前组件路径语义的原生 Router
1306
1311
  */
1307
- function useRouter(options = {}) {
1312
+ function useNativeRouter() {
1313
+ return useNativeRouter$1();
1314
+ }
1315
+ /**
1316
+ * @description 获取当前页面路径语义的原生 Page Router
1317
+ */
1318
+ function useNativePageRouter() {
1319
+ return useNativePageRouter$1();
1320
+ }
1321
+ //#endregion
1322
+ //#region src/router/createRouter.ts
1323
+ /**
1324
+ * @description 创建高阶路由导航器(对齐 Vue Router 的 createRouter 心智)
1325
+ */
1326
+ function createRouter(options = {}) {
1308
1327
  var _options$maxRedirects, _options$paramsMode, _options$rejectOnErro, _options$parseQuery, _options$stringifyQue, _options$tabBarEntrie;
1309
1328
  const nativeRouter = useNativeRouter();
1310
1329
  const route = useRoute();
@@ -1346,10 +1365,6 @@ function useRouter(options = {}) {
1346
1365
  function resolve(to) {
1347
1366
  return resolveWithCodec(to, route.path);
1348
1367
  }
1349
- function install(_app) {}
1350
- function isReady() {
1351
- return readyPromise;
1352
- }
1353
1368
  const navigationApi = createNavigationApi({
1354
1369
  nativeRouter,
1355
1370
  route,
@@ -1391,13 +1406,20 @@ function useRouter(options = {}) {
1391
1406
  errorHandlers.delete(handler);
1392
1407
  };
1393
1408
  }
1394
- return {
1409
+ const router = {
1395
1410
  nativeRouter,
1396
1411
  options: routerOptions,
1397
1412
  currentRoute: route,
1398
- install,
1413
+ install(app) {
1414
+ var _config;
1415
+ setActiveRouter(router);
1416
+ const globalProperties = app === null || app === void 0 || (_config = app.config) === null || _config === void 0 ? void 0 : _config.globalProperties;
1417
+ if (globalProperties) globalProperties.$router = router;
1418
+ },
1399
1419
  resolve,
1400
- isReady,
1420
+ isReady() {
1421
+ return readyPromise;
1422
+ },
1401
1423
  push: navigationApi.push,
1402
1424
  replace: navigationApi.replace,
1403
1425
  back: navigationApi.back,
@@ -1413,6 +1435,18 @@ function useRouter(options = {}) {
1413
1435
  afterEach,
1414
1436
  onError
1415
1437
  };
1438
+ setActiveRouter(router);
1439
+ return router;
1440
+ }
1441
+ //#endregion
1442
+ //#region src/router/useRouter.ts
1443
+ /**
1444
+ * @description 获取当前已创建的路由实例。
1445
+ */
1446
+ function useRouter() {
1447
+ const router = getActiveRouter();
1448
+ if (router) return router;
1449
+ throw new Error("useRouter() 未找到已创建的 router 实例。请先在 setup() 中调用 createRouter()。");
1416
1450
  }
1417
1451
  //#endregion
1418
- export { NavigationFailureType, createNavigationFailure, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
1452
+ export { NavigationFailureType, createNavigationFailure, createRouter, isNavigationFailure, parseQuery, resolveRouteLocation, stringifyQuery, useNativePageRouter, useNativeRouter, useRoute, useRouter };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wevu",
3
3
  "type": "module",
4
- "version": "6.7.7",
4
+ "version": "6.9.0",
5
5
  "description": "Vue 3 风格的小程序运行时,包含响应式、diff+setData 与轻量状态管理",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -95,8 +95,8 @@
95
95
  },
96
96
  "dependencies": {
97
97
  "vue": "^3.5.30",
98
- "@wevu/api": "0.2.0",
99
- "@wevu/compiler": "6.7.7"
98
+ "@wevu/api": "0.2.1",
99
+ "@wevu/compiler": "6.9.0"
100
100
  },
101
101
  "scripts": {
102
102
  "dev": "tsdown -w",