wevu 7.3.0 → 7.5.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 +2 -0
- package/dist/dev/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/defineProperty.mjs +1 -1
- package/dist/dev/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/toPrimitive.mjs +1 -1
- package/dist/dev/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/toPropertyKey.mjs +1 -1
- package/dist/dev/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/typeof.mjs +1 -1
- package/dist/dev/package.mjs +1 -1
- package/dist/dev/reactivity/core.mjs +1 -1
- package/dist/dev/reactivity/ref.mjs +1 -1
- package/dist/dev/router/initialNavigation.mjs +4 -1
- package/dist/dev/router/initialNavigation.mjs.map +1 -1
- package/dist/dev/router/scrollRestoration/adapters.mjs +86 -0
- package/dist/dev/router/scrollRestoration/adapters.mjs.map +1 -0
- package/dist/dev/router/scrollRestoration/controller.mjs +148 -0
- package/dist/dev/router/scrollRestoration/controller.mjs.map +1 -0
- package/dist/dev/router/scrollRestoration/host.mjs +76 -0
- package/dist/dev/router/scrollRestoration/host.mjs.map +1 -0
- package/dist/dev/router/scrollRestoration/index.mjs +156 -0
- package/dist/dev/router/scrollRestoration/index.mjs.map +1 -0
- package/dist/dev/router.mjs +4 -1
- package/dist/dev/runtime/app/diagnostics.mjs +5 -1
- package/dist/dev/runtime/app/diagnostics.mjs.map +1 -1
- package/dist/dev/runtime/app/mount.mjs +8 -3
- package/dist/dev/runtime/app/mount.mjs.map +1 -1
- package/dist/dev/runtime/app/setData/commitTracker.mjs +39 -4
- package/dist/dev/runtime/app/setData/commitTracker.mjs.map +1 -1
- package/dist/dev/runtime/app/setData/observation.mjs +109 -0
- package/dist/dev/runtime/app/setData/observation.mjs.map +1 -0
- package/dist/dev/runtime/app/setData/scheduler.mjs +12 -1
- package/dist/dev/runtime/app/setData/scheduler.mjs.map +1 -1
- package/dist/dev/runtime/app/setDataOptions.mjs +1 -0
- package/dist/dev/runtime/app/setDataOptions.mjs.map +1 -1
- package/dist/dev/runtime/define/initialComputed.mjs +13 -12
- package/dist/dev/runtime/define/initialComputed.mjs.map +1 -1
- package/dist/dev/runtime/define/props.mjs +5 -1
- package/dist/dev/runtime/define/props.mjs.map +1 -1
- package/dist/dev/runtime/define/scopedSlotOptions.mjs +2 -1
- package/dist/dev/runtime/define/scopedSlotOptions.mjs.map +1 -1
- package/dist/dev/runtime/define.mjs +1 -1
- package/dist/dev/runtime/define.mjs.map +1 -1
- package/dist/dev/runtime/features/scopedSlots.mjs.map +1 -1
- package/dist/dev/runtime/hooks/base.mjs +1 -13
- package/dist/dev/runtime/hooks/base.mjs.map +1 -1
- package/dist/dev/runtime/hooks/pageScroll.mjs +41 -0
- package/dist/dev/runtime/hooks/pageScroll.mjs.map +1 -0
- package/dist/dev/runtime/hooks/register.mjs +2 -1
- package/dist/dev/runtime/hooks/register.mjs.map +1 -1
- package/dist/dev/runtime/register/component/lifecycle/optionalHooks.mjs +2 -5
- package/dist/dev/runtime/register/component/lifecycle/optionalHooks.mjs.map +1 -1
- package/dist/dev/runtime/register/component/lifecycle/platform.mjs +8 -20
- package/dist/dev/runtime/register/component/lifecycle/platform.mjs.map +1 -1
- package/dist/dev/runtime/register/component/props.mjs +14 -4
- package/dist/dev/runtime/register/component/props.mjs.map +1 -1
- package/dist/dev/runtime/register/component/registerDefinition.mjs +30 -17
- package/dist/dev/runtime/register/component/registerDefinition.mjs.map +1 -1
- package/dist/dev/runtime/register/component.mjs +2 -1
- package/dist/dev/runtime/register/component.mjs.map +1 -1
- package/dist/dev/runtime/register/runtimeInstance/methodBridge.mjs +14 -7
- package/dist/dev/runtime/register/runtimeInstance/methodBridge.mjs.map +1 -1
- package/dist/dev/runtime/register/runtimeInstance/nativeDeclaration.mjs +78 -0
- package/dist/dev/runtime/register/runtimeInstance/nativeDeclaration.mjs.map +1 -0
- package/dist/dev/runtime/register/runtimeInstance/provideContext.mjs +52 -8
- package/dist/dev/runtime/register/runtimeInstance/provideContext.mjs.map +1 -1
- package/dist/dev/runtime/register/runtimeInstance/setupPhase.mjs +7 -2
- package/dist/dev/runtime/register/runtimeInstance/setupPhase.mjs.map +1 -1
- package/dist/dev/runtime/register/runtimeInstance/utils.mjs.map +1 -1
- package/dist/dev/runtime/register/runtimeInstance.mjs +60 -19
- package/dist/dev/runtime/register/runtimeInstance.mjs.map +1 -1
- package/dist/fetch.mjs +1 -1
- package/dist/internal-template.mjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/reactivity/core.mjs +1 -1
- package/dist/reactivity/reactive/patch.mjs +1 -1
- package/dist/reactivity/reactive/patchState.mjs +1 -1
- package/dist/reactivity/ref.mjs +1 -1
- package/dist/reactivity/watch/helpers.mjs +1 -1
- package/dist/router/initialNavigation.mjs +1 -1
- package/dist/router/scrollRestoration/adapters.d.mts +7 -0
- package/dist/router/scrollRestoration/adapters.mjs +1 -0
- package/dist/router/scrollRestoration/controller.d.mts +7 -0
- package/dist/router/scrollRestoration/controller.mjs +1 -0
- package/dist/router/scrollRestoration/host.d.mts +3 -0
- package/dist/router/scrollRestoration/host.mjs +1 -0
- package/dist/router/scrollRestoration/index.d.mts +8 -0
- package/dist/router/scrollRestoration/index.mjs +1 -0
- package/dist/router/scrollRestoration/types.d.mts +60 -0
- package/dist/router/useRoute.mjs +1 -1
- package/dist/router.d.mts +5 -1
- package/dist/router.mjs +1 -1
- package/dist/routerInternal/matching.mjs +1 -1
- package/dist/routerInternal/params.mjs +1 -1
- package/dist/routerInternal/path.mjs +1 -1
- package/dist/routerInternal/query.mjs +1 -1
- package/dist/routerInternal/records.mjs +1 -1
- package/dist/runtime/app/context.mjs +1 -1
- package/dist/runtime/app/diagnostics.mjs +1 -1
- package/dist/runtime/app/mount.mjs +1 -1
- package/dist/runtime/app/setData/commitTracker.d.mts +2 -1
- package/dist/runtime/app/setData/commitTracker.mjs +1 -1
- package/dist/runtime/app/setData/observation.d.mts +12 -0
- package/dist/runtime/app/setData/observation.mjs +1 -0
- package/dist/runtime/app/setData/scheduler.d.mts +1 -0
- package/dist/runtime/app/setData/scheduler.mjs +1 -1
- package/dist/runtime/app/setDataOptions.mjs +1 -1
- package/dist/runtime/define/initialComputed.mjs +1 -1
- package/dist/runtime/define/props.mjs +1 -1
- package/dist/runtime/define/scopedSlotOptions.mjs +1 -1
- package/dist/runtime/define.mjs +1 -1
- package/dist/runtime/diff.mjs +1 -1
- package/dist/runtime/features/publicLayout.mjs +1 -1
- package/dist/runtime/features/scopedSlots.d.mts +2 -1
- package/dist/runtime/hooks/base.mjs +1 -1
- package/dist/runtime/hooks/pageScroll.mjs +1 -0
- package/dist/runtime/hooks/register.mjs +1 -1
- package/dist/runtime/jsxIsland.mjs +1 -1
- package/dist/runtime/pageLayout.mjs +1 -1
- package/dist/runtime/pageScroll.mjs +1 -1
- package/dist/runtime/register/component/alipayRegistration.mjs +1 -1
- package/dist/runtime/register/component/lifecycle/optionalHooks.mjs +1 -1
- package/dist/runtime/register/component/lifecycle/platform.mjs +1 -1
- package/dist/runtime/register/component/lifecycle.mjs +1 -1
- package/dist/runtime/register/component/props.mjs +1 -1
- package/dist/runtime/register/component/registerDefinition.mjs +1 -1
- package/dist/runtime/register/component/registerNativeDefinition.mjs +1 -1
- package/dist/runtime/register/component.mjs +1 -1
- package/dist/runtime/register/runtimeInstance/methodBridge.mjs +1 -1
- package/dist/runtime/register/runtimeInstance/nativeDeclaration.mjs +1 -0
- package/dist/runtime/register/runtimeInstance/provideContext.mjs +1 -1
- package/dist/runtime/register/runtimeInstance/setupPhase.mjs +1 -1
- package/dist/runtime/register/runtimeInstance.d.mts +8 -4
- package/dist/runtime/register/runtimeInstance.mjs +1 -1
- package/dist/runtime/setupTracking.mjs +1 -1
- package/dist/runtime/templateRefs.mjs +1 -1
- package/dist/runtime/types/runtime.d.mts +1 -0
- package/dist/runtime/types/setData.d.mts +30 -0
- package/dist/scheduler.mjs +1 -1
- package/dist/web-apis.mjs +1 -1
- package/package.json +10 -9
- package/dist/dev/api/vitest/setup.d.mts +0 -1
- package/dist/dev/api/vitest.d.mts +0 -1
- package/dist/dev/api.d.mts +0 -1
- package/dist/dev/compiler.d.mts +0 -1
- package/dist/dev/fetch.d.mts +0 -9
- package/dist/dev/index.d.mts +0 -72
- package/dist/dev/internal-reactivity.d.mts +0 -18
- package/dist/dev/internal-runtime.d.mts +0 -45
- package/dist/dev/internal-template.d.mts +0 -2
- package/dist/dev/jsxTypes.d.mts +0 -9
- package/dist/dev/macros/shared.d.mts +0 -83
- package/dist/dev/macros.d.mts +0 -71
- package/dist/dev/reactivity/asyncDerivation.d.mts +0 -41
- package/dist/dev/reactivity/computed.d.mts +0 -25
- package/dist/dev/reactivity/core.d.mts +0 -35
- package/dist/dev/reactivity/index.d.mts +0 -16
- package/dist/dev/reactivity/reactive/mutation.d.mts +0 -21
- package/dist/dev/reactivity/reactive/patch.d.mts +0 -18
- package/dist/dev/reactivity/reactive/shallow.d.mts +0 -22
- package/dist/dev/reactivity/reactive/shared.d.mts +0 -4
- package/dist/dev/reactivity/reactive.d.mts +0 -42
- package/dist/dev/reactivity/readonly.d.mts +0 -27
- package/dist/dev/reactivity/ref.d.mts +0 -27
- package/dist/dev/reactivity/shallowRef.d.mts +0 -19
- package/dist/dev/reactivity/toRefs.d.mts +0 -43
- package/dist/dev/reactivity/traverse.d.mts +0 -8
- package/dist/dev/reactivity/watch/types.d.mts +0 -43
- package/dist/dev/reactivity/watch.d.mts +0 -22
- package/dist/dev/router/auto-routes.d.mts +0 -8
- package/dist/dev/router/createRouter.d.mts +0 -9
- package/dist/dev/router/navigationCore.d.mts +0 -7
- package/dist/dev/router/resolve.d.mts +0 -7
- package/dist/dev/router/routeSync.d.mts +0 -2
- package/dist/dev/router/types.d.mts +0 -267
- package/dist/dev/router/useRoute.d.mts +0 -20
- package/dist/dev/router/useRouter.d.mts +0 -9
- package/dist/dev/router.d.mts +0 -26
- package/dist/dev/routerInternal/location.d.mts +0 -2
- package/dist/dev/routerInternal/matching.d.mts +0 -2
- package/dist/dev/routerInternal/params.d.mts +0 -2
- package/dist/dev/routerInternal/query.d.mts +0 -7
- package/dist/dev/routerInternal/records.d.mts +0 -2
- package/dist/dev/routerInternal/recordsWarnings.d.mts +0 -2
- package/dist/dev/routerInternal/shared.d.mts +0 -9
- package/dist/dev/routerInternal/snapshots.d.mts +0 -2
- package/dist/dev/routerInternal/types.d.mts +0 -9
- package/dist/dev/runtime/app/pending.d.mts +0 -10
- package/dist/dev/runtime/app/setData/commitTracker.d.mts +0 -13
- package/dist/dev/runtime/app/setData/scheduler.d.mts +0 -51
- package/dist/dev/runtime/app.d.mts +0 -8
- package/dist/dev/runtime/capabilities.d.mts +0 -78
- package/dist/dev/runtime/css.d.mts +0 -14
- package/dist/dev/runtime/defaults.d.mts +0 -12
- package/dist/dev/runtime/define.d.mts +0 -118
- package/dist/dev/runtime/disposables.d.mts +0 -31
- package/dist/dev/runtime/elementIntersectionObserver.d.mts +0 -26
- package/dist/dev/runtime/features/inlineEvents.d.mts +0 -7
- package/dist/dev/runtime/features/jsxIslands.d.mts +0 -7
- package/dist/dev/runtime/features/layout.d.mts +0 -7
- package/dist/dev/runtime/features/patchStrategy.d.mts +0 -7
- package/dist/dev/runtime/features/publicLayout.d.mts +0 -24
- package/dist/dev/runtime/features/scopedSlots.d.mts +0 -23
- package/dist/dev/runtime/features/setDataHighFrequencyWarning.d.mts +0 -7
- package/dist/dev/runtime/features/templateRefs.d.mts +0 -7
- package/dist/dev/runtime/hooks/base.d.mts +0 -27
- package/dist/dev/runtime/hooks/register.d.mts +0 -30
- package/dist/dev/runtime/hooks/vue.d.mts +0 -52
- package/dist/dev/runtime/hooks.d.mts +0 -4
- package/dist/dev/runtime/index.d.mts +0 -46
- package/dist/dev/runtime/intersectionObserver.d.mts +0 -14
- package/dist/dev/runtime/jsxIsland.d.mts +0 -37
- package/dist/dev/runtime/layoutBridge.d.mts +0 -55
- package/dist/dev/runtime/noSetData.d.mts +0 -5
- package/dist/dev/runtime/pageEnvironment.d.mts +0 -50
- package/dist/dev/runtime/pageLayout.d.mts +0 -25
- package/dist/dev/runtime/pageScroll.d.mts +0 -29
- package/dist/dev/runtime/provide.d.mts +0 -60
- package/dist/dev/runtime/provideStore.d.mts +0 -7
- package/dist/dev/runtime/publicRuntime.d.mts +0 -22
- package/dist/dev/runtime/pullDownRefresh.d.mts +0 -12
- package/dist/dev/runtime/register/app.d.mts +0 -14
- package/dist/dev/runtime/register/component.d.mts +0 -17
- package/dist/dev/runtime/register/inline.d.mts +0 -15
- package/dist/dev/runtime/register/runtimeInstance.d.mts +0 -26
- package/dist/dev/runtime/register/setup.d.mts +0 -11
- package/dist/dev/runtime/register/watch.d.mts +0 -12
- package/dist/dev/runtime/register.d.mts +0 -5
- package/dist/dev/runtime/selectorQuery.d.mts +0 -54
- package/dist/dev/runtime/template.d.mts +0 -6
- package/dist/dev/runtime/templateRefTypes.d.mts +0 -12
- package/dist/dev/runtime/types/core.d.mts +0 -35
- package/dist/dev/runtime/types/miniprogram.d.mts +0 -84
- package/dist/dev/runtime/types/miniprogramHost.d.mts +0 -45
- package/dist/dev/runtime/types/miniprogramHostSources.d.mts +0 -112
- package/dist/dev/runtime/types/options.d.mts +0 -138
- package/dist/dev/runtime/types/props/propTypes.d.mts +0 -79
- package/dist/dev/runtime/types/props/router.d.mts +0 -51
- package/dist/dev/runtime/types/props/setup.d.mts +0 -96
- package/dist/dev/runtime/types/props.d.mts +0 -4
- package/dist/dev/runtime/types/runtime.d.mts +0 -59
- package/dist/dev/runtime/types/setData.d.mts +0 -237
- package/dist/dev/runtime/types.d.mts +0 -29
- package/dist/dev/runtime/uniAppHost.d.mts +0 -8
- package/dist/dev/runtime/updatePerformance.d.mts +0 -13
- package/dist/dev/runtime/use.d.mts +0 -13
- package/dist/dev/runtime/vueCompat/context.d.mts +0 -8
- package/dist/dev/runtime/vueCompat/model.d.mts +0 -30
- package/dist/dev/runtime/vueCompat/router.d.mts +0 -29
- package/dist/dev/runtime/vueCompat/templateRef.d.mts +0 -9
- package/dist/dev/runtime/vueCompat.d.mts +0 -5
- package/dist/dev/scheduler.d.mts +0 -4
- package/dist/dev/store/define.d.mts +0 -8
- package/dist/dev/store/manager.d.mts +0 -16
- package/dist/dev/store/storeToRefs.d.mts +0 -11
- package/dist/dev/store/types.d.mts +0 -106
- package/dist/dev/store.d.mts +0 -5
- package/dist/dev/version.d.mts +0 -4
- package/dist/dev/vue-augment.d.mts +0 -8
- package/dist/dev/vue-demi.d.mts +0 -87
- package/dist/dev/vue-types.d.mts +0 -19
- package/dist/dev/web-apis.d.mts +0 -3
- /package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/defineProperty.mjs +0 -0
- /package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/toPrimitive.mjs +0 -0
- /package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/toPropertyKey.mjs +0 -0
- /package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.153.0}/helpers/esm/typeof.mjs +0 -0
package/README.md
CHANGED
|
@@ -180,6 +180,8 @@ const onActiveChange = bindModel.model<boolean>('isActive').onChange
|
|
|
180
180
|
|
|
181
181
|
- 更新被批量加入微任务队列;`nextTick` 只等待当前 JavaScript/响应式任务队列排空,不等待小程序 `setData` 回调或视图提交。
|
|
182
182
|
- 对状态做快照 diff,只把变更路径传给 `setData`;宿主提交失败时,下一次响应式更新会发送完整恢复快照。
|
|
183
|
+
- 可用 `setData.debugPhases: true` 在现有 `debug` 回调中关联 prepare、物理 dispatch 与 commit。合并调用按 ID 去重;callback/Promise/同步返回不等于可见视图完成,未观测边界保持 `null`。参见 [阶段观测与测量示例](../../docs/wevu/setdata-observation.md)。
|
|
184
|
+
- `weapp.wevu.preset: 'performance'` 默认开启 patch、隐藏时暂停和 `diagnostics: 'fallback'`。首次快照收集也会记录 `needsFullSnapshot`;启用阶段观测后,同一 revision 可有多条日志,不能将 warning 条数视为失败或回退次数。配置覆盖见 [预设说明](https://vite.weapp.dev/config/wevu#weapp-wevu-preset)。
|
|
183
185
|
- 提供 `batch`/`startBatch`/`endBatch` 用于同步更新合并触发;以及 `effectScope`/`getCurrentScope`/`onScopeDispose` 统一管理 effect/watch 的销毁,`setup()` 同步阶段内创建的副作用会自动归属到实例级 scope,便于避免泄漏。
|
|
184
186
|
|
|
185
187
|
## 开发产物与源码调试
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import toPropertyKey from "./toPropertyKey.mjs";
|
|
2
2
|
|
|
3
|
-
//#region \0@oxc-project+runtime@0.
|
|
3
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/defineProperty.js
|
|
4
4
|
function _defineProperty(e, r, t) {
|
|
5
5
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
6
6
|
value: t,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _typeof from "./typeof.mjs";
|
|
2
2
|
|
|
3
|
-
//#region \0@oxc-project+runtime@0.
|
|
3
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPrimitive.js
|
|
4
4
|
function toPrimitive(t, r) {
|
|
5
5
|
if ("object" != _typeof(t) || !t) return t;
|
|
6
6
|
var e = t[Symbol.toPrimitive];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _typeof from "./typeof.mjs";
|
|
2
2
|
import toPrimitive from "./toPrimitive.mjs";
|
|
3
3
|
|
|
4
|
-
//#region \0@oxc-project+runtime@0.
|
|
4
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPropertyKey.js
|
|
5
5
|
function toPropertyKey(t) {
|
|
6
6
|
var i = toPrimitive(t, "string");
|
|
7
7
|
return "symbol" == _typeof(i) ? i : i + "";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/typeof.js
|
|
2
2
|
function _typeof(o) {
|
|
3
3
|
"@babel/helpers - typeof";
|
|
4
4
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
package/dist/dev/package.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { queueJob } from "../scheduler.mjs";
|
|
2
|
-
import _defineProperty from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import _defineProperty from "../_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/defineProperty.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/reactivity/core.ts
|
|
5
5
|
const targetMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _defineProperty from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import _defineProperty from "../_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/defineProperty.mjs";
|
|
2
2
|
import { trackEffects, triggerEffects } from "./core.mjs";
|
|
3
3
|
import { convertToReactive, markRaw } from "./reactive.mjs";
|
|
4
4
|
|
|
@@ -30,6 +30,9 @@ function getInitialNavigationTimeout() {
|
|
|
30
30
|
function isNavigationFailureResult(result) {
|
|
31
31
|
return Boolean(result && typeof result === "object" && result.__wevuNavigationFailure);
|
|
32
32
|
}
|
|
33
|
+
function getInitialNavigationPromise(instance) {
|
|
34
|
+
return initialNavigationControllers.get(instance)?.promise;
|
|
35
|
+
}
|
|
33
36
|
function ensureInitialNavigation(instance, query, options = {}) {
|
|
34
37
|
const existing = initialNavigationControllers.get(instance);
|
|
35
38
|
if (existing) {
|
|
@@ -142,5 +145,5 @@ function registerInitialNavigationRunner(router, runner, timeoutMs = DEFAULT_INI
|
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
//#endregion
|
|
145
|
-
export { DEFAULT_INITIAL_NAVIGATION_TIMEOUT, cancelInitialNavigation, ensureInitialNavigation, getInitialNavigationTimeout, registerInitialNavigationRunner };
|
|
148
|
+
export { DEFAULT_INITIAL_NAVIGATION_TIMEOUT, cancelInitialNavigation, ensureInitialNavigation, getInitialNavigationPromise, getInitialNavigationTimeout, registerInitialNavigationRunner };
|
|
146
149
|
//# sourceMappingURL=initialNavigation.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialNavigation.mjs","names":[],"sources":["../../../src/router/initialNavigation.ts"],"sourcesContent":["import type { MiniProgramPageLike } from '../routerInternal/shared'\nimport type { InitialNavigationMode, LocationQueryRaw, NavigationFailure } from './types'\nimport { WEVU_INITIAL_NAVIGATION_TIMEOUT_MARKER } from '@weapp-core/constants'\nimport { queueMicrotaskPolyfill } from '@wevu/web-apis'\nimport { registerInitialNavigationLifecycle } from '../runtime/navigationLifecycle'\nimport { getActiveRouter } from './instance'\n\nexport const DEFAULT_INITIAL_NAVIGATION_TIMEOUT = 10_000\n\nexport type InitialNavigationStatus = 'idle' | 'running' | 'allowed' | 'aborted' | 'timed-out' | 'cancelled'\n\ninterface InitialNavigationRunnerRegistration {\n runner: InitialNavigationRunner\n mode: InitialNavigationMode\n timeoutMs: number\n}\n\nexport type InitialNavigationRunner = (\n page: MiniProgramPageLike,\n query?: LocationQueryRaw,\n isActive?: () => boolean,\n) => Promise<void | NavigationFailure>\n\ninterface InitialNavigationController {\n readonly promise: Promise<boolean>\n readonly blocking: boolean\n readonly status: () => InitialNavigationStatus\n subscribe: (callback: (shouldMount: boolean) => void) => () => void\n start: (query?: LocationQueryRaw) => void\n cancel: () => void\n}\n\nconst initialNavigationRunners = new WeakMap<object, InitialNavigationRunnerRegistration>()\nconst initialNavigationControllers = new WeakMap<object, InitialNavigationController>()\n\nfunction normalizeTimeout(timeoutMs: number) {\n return Number.isFinite(timeoutMs) && timeoutMs > 0\n ? Math.max(1, Math.trunc(timeoutMs))\n : DEFAULT_INITIAL_NAVIGATION_TIMEOUT\n}\n\nfunction snapshotPage(instance: MiniProgramPageLike): MiniProgramPageLike {\n return {\n route: typeof instance.route === 'string' ? instance.route : undefined,\n __route__: typeof instance.__route__ === 'string' ? instance.__route__ : undefined,\n options: instance.options && typeof instance.options === 'object'\n ? { ...instance.options }\n : undefined,\n }\n}\n\nfunction snapshotQuery(query: LocationQueryRaw | undefined): LocationQueryRaw | undefined {\n if (!query || typeof query !== 'object') {\n return undefined\n }\n const snapshot: LocationQueryRaw = {}\n for (const [key, value] of Object.entries(query)) {\n snapshot[key] = Array.isArray(value) ? [...value] : value\n }\n return snapshot\n}\n\nexport function getInitialNavigationRunner(): InitialNavigationRunner | undefined {\n const router = getActiveRouter()\n return router ? initialNavigationRunners.get(router)?.runner : undefined\n}\n\nexport function getInitialNavigationTimeout() {\n const router = getActiveRouter()\n return router ? initialNavigationRunners.get(router)?.timeoutMs ?? DEFAULT_INITIAL_NAVIGATION_TIMEOUT : DEFAULT_INITIAL_NAVIGATION_TIMEOUT\n}\n\nexport function getInitialNavigationMode(): InitialNavigationMode {\n const router = getActiveRouter()\n return router ? initialNavigationRunners.get(router)?.mode ?? 'eager' : 'eager'\n}\n\nfunction isNavigationFailureResult(result: void | NavigationFailure): result is NavigationFailure {\n return Boolean(result && typeof result === 'object' && (result as NavigationFailure).__wevuNavigationFailure)\n}\n\nexport function getInitialNavigationPromise(instance: MiniProgramPageLike) {\n return initialNavigationControllers.get(instance as object)?.promise\n}\n\nexport function getInitialNavigationStatus(instance: MiniProgramPageLike) {\n return initialNavigationControllers.get(instance as object)?.status()\n}\n\nexport function ensureInitialNavigation(\n instance: MiniProgramPageLike,\n query?: LocationQueryRaw,\n options: { start?: boolean, onComplete?: (shouldMount: boolean) => void } = {},\n) {\n const existing = initialNavigationControllers.get(instance as object)\n if (existing) {\n if (options.onComplete && existing.blocking) {\n existing.subscribe(options.onComplete)\n }\n if (options.start !== false) {\n existing.start(query)\n }\n return existing.blocking ? existing.promise : undefined\n }\n\n const router = getActiveRouter()\n const registration = router ? initialNavigationRunners.get(router) : undefined\n let pendingRunner = registration?.runner\n if (!pendingRunner) {\n return undefined\n }\n const blocking = registration?.mode === 'blocking'\n\n let page: MiniProgramPageLike | undefined = snapshotPage(instance)\n let initialQuery = snapshotQuery(query)\n let currentStatus: InitialNavigationStatus = 'idle'\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n const timeoutMs = getInitialNavigationTimeout()\n let resolveNavigation!: (shouldMount: boolean) => void\n const completionCallbacks = new Set<{ callback: (shouldMount: boolean) => void, active: boolean }>()\n const promise = new Promise<boolean>((resolve) => {\n resolveNavigation = resolve\n })\n\n const settle = (status: Exclude<InitialNavigationStatus, 'idle' | 'running'>, shouldMount: boolean) => {\n if (currentStatus !== 'idle' && currentStatus !== 'running') {\n return\n }\n currentStatus = status\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle)\n timeoutHandle = undefined\n }\n const callbacks = [...completionCallbacks]\n completionCallbacks.clear()\n pendingRunner = undefined\n page = undefined\n initialQuery = undefined\n resolveNavigation(shouldMount)\n queueMicrotaskPolyfill(() => {\n if (currentStatus !== 'allowed' && currentStatus !== 'timed-out') {\n return\n }\n for (const entry of callbacks) {\n if (entry.active) {\n entry.callback(shouldMount)\n entry.active = false\n }\n }\n })\n }\n\n const controller: InitialNavigationController = {\n promise,\n blocking,\n status: () => currentStatus,\n subscribe(callback) {\n const entry = { callback, active: true }\n if (currentStatus !== 'idle' && currentStatus !== 'running') {\n queueMicrotaskPolyfill(() => {\n if (entry.active && (currentStatus === 'allowed' || currentStatus === 'timed-out')) {\n callback(currentStatus === 'allowed' || currentStatus === 'timed-out')\n entry.active = false\n }\n })\n }\n else {\n completionCallbacks.add(entry)\n }\n return () => {\n entry.active = false\n completionCallbacks.delete(entry)\n }\n },\n start(startQuery?: LocationQueryRaw) {\n if (currentStatus !== 'idle') {\n return\n }\n currentStatus = 'running'\n if (blocking) {\n timeoutHandle = setTimeout(() => {\n if (currentStatus !== 'running') {\n return\n }\n // 超时是可恢复的运行时诊断,保留稳定 marker 供宿主和 E2E 观测。\n // eslint-disable-next-line no-console\n console.warn(`${WEVU_INITIAL_NAVIGATION_TIMEOUT_MARKER} initial navigation exceeded ${timeoutMs}ms; mounting page`, page?.route ?? page?.__route__ ?? '')\n settle('timed-out', true)\n }, timeoutMs)\n }\n const runnerPage = page\n const runnerQuery = snapshotQuery(startQuery ?? initialQuery)\n const runner = pendingRunner\n pendingRunner = undefined\n if (!runner || !runnerPage) {\n settle('aborted', false)\n return\n }\n void runner(runnerPage, runnerQuery, () => currentStatus === 'running').then((result) => {\n const failed = isNavigationFailureResult(result)\n settle(failed ? 'aborted' : 'allowed', !failed)\n }, () => {\n settle('aborted', false)\n })\n },\n cancel() {\n settle('cancelled', false)\n },\n }\n\n initialNavigationControllers.set(instance as object, controller)\n if (options.onComplete && blocking) {\n controller.subscribe(options.onComplete)\n }\n if (options.start !== false) {\n controller.start(query)\n }\n return blocking ? promise : undefined\n}\n\nexport function cancelInitialNavigation(instance: MiniProgramPageLike) {\n initialNavigationControllers.get(instance as object)?.cancel()\n}\n\nexport function registerInitialNavigationRunner(\n router: object,\n runner: InitialNavigationRunner,\n timeoutMs = DEFAULT_INITIAL_NAVIGATION_TIMEOUT,\n mode: InitialNavigationMode = 'blocking',\n) {\n registerInitialNavigationLifecycle({ ensure: ensureInitialNavigation, cancel: cancelInitialNavigation })\n initialNavigationRunners.set(router, {\n runner,\n mode,\n timeoutMs: normalizeTimeout(timeoutMs),\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"initialNavigation.mjs","names":[],"sources":["../../../src/router/initialNavigation.ts"],"sourcesContent":["import type { MiniProgramPageLike } from '../routerInternal/shared'\nimport type { InitialNavigationMode, LocationQueryRaw, NavigationFailure } from './types'\nimport { WEVU_INITIAL_NAVIGATION_TIMEOUT_MARKER } from '@weapp-core/constants'\nimport { queueMicrotaskPolyfill } from '@wevu/web-apis'\nimport { registerInitialNavigationLifecycle } from '../runtime/navigationLifecycle'\nimport { getActiveRouter } from './instance'\n\nexport const DEFAULT_INITIAL_NAVIGATION_TIMEOUT = 10_000\n\nexport type InitialNavigationStatus = 'idle' | 'running' | 'allowed' | 'aborted' | 'timed-out' | 'cancelled'\n\ninterface InitialNavigationRunnerRegistration {\n runner: InitialNavigationRunner\n mode: InitialNavigationMode\n timeoutMs: number\n}\n\nexport type InitialNavigationRunner = (\n page: MiniProgramPageLike,\n query?: LocationQueryRaw,\n isActive?: () => boolean,\n) => Promise<void | NavigationFailure>\n\ninterface InitialNavigationController {\n readonly promise: Promise<boolean>\n readonly blocking: boolean\n readonly status: () => InitialNavigationStatus\n subscribe: (callback: (shouldMount: boolean) => void) => () => void\n start: (query?: LocationQueryRaw) => void\n cancel: () => void\n}\n\nconst initialNavigationRunners = new WeakMap<object, InitialNavigationRunnerRegistration>()\nconst initialNavigationControllers = new WeakMap<object, InitialNavigationController>()\n\nfunction normalizeTimeout(timeoutMs: number) {\n return Number.isFinite(timeoutMs) && timeoutMs > 0\n ? Math.max(1, Math.trunc(timeoutMs))\n : DEFAULT_INITIAL_NAVIGATION_TIMEOUT\n}\n\nfunction snapshotPage(instance: MiniProgramPageLike): MiniProgramPageLike {\n return {\n route: typeof instance.route === 'string' ? instance.route : undefined,\n __route__: typeof instance.__route__ === 'string' ? instance.__route__ : undefined,\n options: instance.options && typeof instance.options === 'object'\n ? { ...instance.options }\n : undefined,\n }\n}\n\nfunction snapshotQuery(query: LocationQueryRaw | undefined): LocationQueryRaw | undefined {\n if (!query || typeof query !== 'object') {\n return undefined\n }\n const snapshot: LocationQueryRaw = {}\n for (const [key, value] of Object.entries(query)) {\n snapshot[key] = Array.isArray(value) ? [...value] : value\n }\n return snapshot\n}\n\nexport function getInitialNavigationRunner(): InitialNavigationRunner | undefined {\n const router = getActiveRouter()\n return router ? initialNavigationRunners.get(router)?.runner : undefined\n}\n\nexport function getInitialNavigationTimeout() {\n const router = getActiveRouter()\n return router ? initialNavigationRunners.get(router)?.timeoutMs ?? DEFAULT_INITIAL_NAVIGATION_TIMEOUT : DEFAULT_INITIAL_NAVIGATION_TIMEOUT\n}\n\nexport function getInitialNavigationMode(): InitialNavigationMode {\n const router = getActiveRouter()\n return router ? initialNavigationRunners.get(router)?.mode ?? 'eager' : 'eager'\n}\n\nfunction isNavigationFailureResult(result: void | NavigationFailure): result is NavigationFailure {\n return Boolean(result && typeof result === 'object' && (result as NavigationFailure).__wevuNavigationFailure)\n}\n\nexport function getInitialNavigationPromise(instance: MiniProgramPageLike) {\n return initialNavigationControllers.get(instance as object)?.promise\n}\n\nexport function getInitialNavigationStatus(instance: MiniProgramPageLike) {\n return initialNavigationControllers.get(instance as object)?.status()\n}\n\nexport function ensureInitialNavigation(\n instance: MiniProgramPageLike,\n query?: LocationQueryRaw,\n options: { start?: boolean, onComplete?: (shouldMount: boolean) => void } = {},\n) {\n const existing = initialNavigationControllers.get(instance as object)\n if (existing) {\n if (options.onComplete && existing.blocking) {\n existing.subscribe(options.onComplete)\n }\n if (options.start !== false) {\n existing.start(query)\n }\n return existing.blocking ? existing.promise : undefined\n }\n\n const router = getActiveRouter()\n const registration = router ? initialNavigationRunners.get(router) : undefined\n let pendingRunner = registration?.runner\n if (!pendingRunner) {\n return undefined\n }\n const blocking = registration?.mode === 'blocking'\n\n let page: MiniProgramPageLike | undefined = snapshotPage(instance)\n let initialQuery = snapshotQuery(query)\n let currentStatus: InitialNavigationStatus = 'idle'\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n const timeoutMs = getInitialNavigationTimeout()\n let resolveNavigation!: (shouldMount: boolean) => void\n const completionCallbacks = new Set<{ callback: (shouldMount: boolean) => void, active: boolean }>()\n const promise = new Promise<boolean>((resolve) => {\n resolveNavigation = resolve\n })\n\n const settle = (status: Exclude<InitialNavigationStatus, 'idle' | 'running'>, shouldMount: boolean) => {\n if (currentStatus !== 'idle' && currentStatus !== 'running') {\n return\n }\n currentStatus = status\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle)\n timeoutHandle = undefined\n }\n const callbacks = [...completionCallbacks]\n completionCallbacks.clear()\n pendingRunner = undefined\n page = undefined\n initialQuery = undefined\n resolveNavigation(shouldMount)\n queueMicrotaskPolyfill(() => {\n if (currentStatus !== 'allowed' && currentStatus !== 'timed-out') {\n return\n }\n for (const entry of callbacks) {\n if (entry.active) {\n entry.callback(shouldMount)\n entry.active = false\n }\n }\n })\n }\n\n const controller: InitialNavigationController = {\n promise,\n blocking,\n status: () => currentStatus,\n subscribe(callback) {\n const entry = { callback, active: true }\n if (currentStatus !== 'idle' && currentStatus !== 'running') {\n queueMicrotaskPolyfill(() => {\n if (entry.active && (currentStatus === 'allowed' || currentStatus === 'timed-out')) {\n callback(currentStatus === 'allowed' || currentStatus === 'timed-out')\n entry.active = false\n }\n })\n }\n else {\n completionCallbacks.add(entry)\n }\n return () => {\n entry.active = false\n completionCallbacks.delete(entry)\n }\n },\n start(startQuery?: LocationQueryRaw) {\n if (currentStatus !== 'idle') {\n return\n }\n currentStatus = 'running'\n if (blocking) {\n timeoutHandle = setTimeout(() => {\n if (currentStatus !== 'running') {\n return\n }\n // 超时是可恢复的运行时诊断,保留稳定 marker 供宿主和 E2E 观测。\n // eslint-disable-next-line no-console\n console.warn(`${WEVU_INITIAL_NAVIGATION_TIMEOUT_MARKER} initial navigation exceeded ${timeoutMs}ms; mounting page`, page?.route ?? page?.__route__ ?? '')\n settle('timed-out', true)\n }, timeoutMs)\n }\n const runnerPage = page\n const runnerQuery = snapshotQuery(startQuery ?? initialQuery)\n const runner = pendingRunner\n pendingRunner = undefined\n if (!runner || !runnerPage) {\n settle('aborted', false)\n return\n }\n void runner(runnerPage, runnerQuery, () => currentStatus === 'running').then((result) => {\n const failed = isNavigationFailureResult(result)\n settle(failed ? 'aborted' : 'allowed', !failed)\n }, () => {\n settle('aborted', false)\n })\n },\n cancel() {\n settle('cancelled', false)\n },\n }\n\n initialNavigationControllers.set(instance as object, controller)\n if (options.onComplete && blocking) {\n controller.subscribe(options.onComplete)\n }\n if (options.start !== false) {\n controller.start(query)\n }\n return blocking ? promise : undefined\n}\n\nexport function cancelInitialNavigation(instance: MiniProgramPageLike) {\n initialNavigationControllers.get(instance as object)?.cancel()\n}\n\nexport function registerInitialNavigationRunner(\n router: object,\n runner: InitialNavigationRunner,\n timeoutMs = DEFAULT_INITIAL_NAVIGATION_TIMEOUT,\n mode: InitialNavigationMode = 'blocking',\n) {\n registerInitialNavigationLifecycle({ ensure: ensureInitialNavigation, cancel: cancelInitialNavigation })\n initialNavigationRunners.set(router, {\n runner,\n mode,\n timeoutMs: normalizeTimeout(timeoutMs),\n })\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ref } from "../../reactivity/ref.mjs";
|
|
2
|
+
import { getCurrentMiniProgramGlobalObject } from "../../runtime/platform/current.mjs";
|
|
3
|
+
import { ensurePageHookOnInstance } from "../../runtime/hooks/pageScroll.mjs";
|
|
4
|
+
import { addScrollHook } from "./host.mjs";
|
|
5
|
+
import { resolveScrollController } from "./controller.mjs";
|
|
6
|
+
import { getScrollSetupScope, registerScrollRestoration } from "./index.mjs";
|
|
7
|
+
import { WEVU_PAGE_SCROLL_OBSERVERS_KEY, WEVU_PAGE_SCROLL_RESTORATION_OWNER_KEY } from "@weapp-core/constants";
|
|
8
|
+
|
|
9
|
+
//#region src/router/scrollRestoration/adapters.ts
|
|
10
|
+
/** WebView 页面适配器;Skyline 没有隐式页面滚动容器。 */
|
|
11
|
+
function usePageScrollRestoration(options = {}) {
|
|
12
|
+
const state = resolveScrollController(options.controller);
|
|
13
|
+
const host = getCurrentMiniProgramGlobalObject();
|
|
14
|
+
if (typeof host?.pageScrollTo !== "function") throw new TypeError("当前宿主不支持 pageScrollTo,请使用显式 scroll-view 适配器。");
|
|
15
|
+
let top = 0;
|
|
16
|
+
let page;
|
|
17
|
+
const cleanups = [];
|
|
18
|
+
return registerScrollRestoration({
|
|
19
|
+
...options,
|
|
20
|
+
capture: () => ({ top }),
|
|
21
|
+
async restore(snapshot, context) {
|
|
22
|
+
const transition = state.transition;
|
|
23
|
+
if (transition && transition.page === page && transition.event.renderer === "skyline") throw new Error("Skyline 不支持页面级滚动,请使用 useScrollViewRestoration()。");
|
|
24
|
+
if (!context.isActive()) return;
|
|
25
|
+
await new Promise((resolve, reject) => {
|
|
26
|
+
host.pageScrollTo({
|
|
27
|
+
scrollTop: snapshot?.top ?? 0,
|
|
28
|
+
duration: 0,
|
|
29
|
+
success: () => resolve(),
|
|
30
|
+
fail: reject
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}, {
|
|
35
|
+
onBindPage(owner) {
|
|
36
|
+
page = owner;
|
|
37
|
+
const releaseOwner = host[WEVU_PAGE_SCROLL_RESTORATION_OWNER_KEY]?.(page);
|
|
38
|
+
if (typeof releaseOwner === "function") cleanups.push(releaseOwner);
|
|
39
|
+
cleanups.push(addScrollHook(page, WEVU_PAGE_SCROLL_OBSERVERS_KEY, (event) => {
|
|
40
|
+
if (event && typeof event === "object" && "scrollTop" in event && typeof event.scrollTop === "number") top = event.scrollTop;
|
|
41
|
+
}));
|
|
42
|
+
ensurePageHookOnInstance(page, "onPageScroll");
|
|
43
|
+
},
|
|
44
|
+
onStop() {
|
|
45
|
+
for (const cleanup of cleanups) cleanup();
|
|
46
|
+
cleanups.length = 0;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** 用属性控制 WebView/Skyline scroll-view,scroll 事件不产生 setData。 */
|
|
51
|
+
function useScrollViewRestoration(options = {}) {
|
|
52
|
+
const { commit } = getScrollSetupScope();
|
|
53
|
+
const scrollTop = ref(0);
|
|
54
|
+
const scrollLeft = ref(0);
|
|
55
|
+
let top = 0;
|
|
56
|
+
let left = 0;
|
|
57
|
+
return {
|
|
58
|
+
...registerScrollRestoration({
|
|
59
|
+
...options,
|
|
60
|
+
capture: () => ({
|
|
61
|
+
top,
|
|
62
|
+
left
|
|
63
|
+
}),
|
|
64
|
+
async restore(snapshot, context) {
|
|
65
|
+
if (!context.isActive()) return;
|
|
66
|
+
scrollTop.value = top;
|
|
67
|
+
scrollLeft.value = left;
|
|
68
|
+
await commit();
|
|
69
|
+
if (!context.isActive()) return;
|
|
70
|
+
scrollTop.value = snapshot?.top ?? 0;
|
|
71
|
+
scrollLeft.value = snapshot?.left ?? 0;
|
|
72
|
+
await commit();
|
|
73
|
+
}
|
|
74
|
+
}),
|
|
75
|
+
scrollTop,
|
|
76
|
+
scrollLeft,
|
|
77
|
+
onScroll(event) {
|
|
78
|
+
top = event.detail.scrollTop;
|
|
79
|
+
left = event.detail.scrollLeft;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
export { usePageScrollRestoration, useScrollViewRestoration };
|
|
86
|
+
//# sourceMappingURL=adapters.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.mjs","names":[],"sources":["../../../../src/router/scrollRestoration/adapters.ts"],"sourcesContent":["import type { InternalRuntimeState } from '../../runtime/types'\nimport type { ScrollPage } from './host'\nimport type { ScrollRestorationHandle, ScrollRestorationRegistrationOptions, ScrollViewRestorationHandle } from './types'\nimport { WEVU_PAGE_SCROLL_OBSERVERS_KEY, WEVU_PAGE_SCROLL_RESTORATION_OWNER_KEY } from '@weapp-core/constants'\nimport { ref } from '../../reactivity'\nimport { ensurePageHookOnInstance } from '../../runtime/hooks/pageScroll'\nimport { getCurrentMiniProgramGlobalObject } from '../../runtime/platform'\nimport { resolveScrollController } from './controller'\nimport { addScrollHook } from './host'\nimport { getScrollSetupScope, registerScrollRestoration } from './index'\n\n/** WebView 页面适配器;Skyline 没有隐式页面滚动容器。 */\nexport function usePageScrollRestoration(options: ScrollRestorationRegistrationOptions = {}): ScrollRestorationHandle {\n const state = resolveScrollController(options.controller)\n const host = getCurrentMiniProgramGlobalObject()\n if (typeof host?.pageScrollTo !== 'function') {\n throw new TypeError('当前宿主不支持 pageScrollTo,请使用显式 scroll-view 适配器。')\n }\n let top = 0\n let page: ScrollPage | undefined\n const cleanups: Array<() => void> = []\n\n return registerScrollRestoration({\n ...options,\n capture: () => ({ top }),\n async restore(snapshot, context) {\n const transition = state.transition\n if (transition && transition.page === page && transition.event.renderer === 'skyline') {\n throw new Error('Skyline 不支持页面级滚动,请使用 useScrollViewRestoration()。')\n }\n if (!context.isActive()) {\n return\n }\n await new Promise<void>((resolve, reject) => {\n host.pageScrollTo({ scrollTop: snapshot?.top ?? 0, duration: 0, success: () => resolve(), fail: reject })\n })\n },\n }, {\n onBindPage(owner) {\n page = owner\n const releaseOwner = host[WEVU_PAGE_SCROLL_RESTORATION_OWNER_KEY]?.(page)\n if (typeof releaseOwner === 'function') {\n cleanups.push(releaseOwner)\n }\n cleanups.push(addScrollHook(page, WEVU_PAGE_SCROLL_OBSERVERS_KEY, (event) => {\n if (event && typeof event === 'object' && 'scrollTop' in event && typeof event.scrollTop === 'number') {\n top = event.scrollTop\n }\n }))\n ensurePageHookOnInstance(page as InternalRuntimeState, 'onPageScroll')\n },\n onStop() {\n for (const cleanup of cleanups) {\n cleanup()\n }\n cleanups.length = 0\n },\n })\n}\n\n/** 用属性控制 WebView/Skyline scroll-view,scroll 事件不产生 setData。 */\nexport function useScrollViewRestoration(options: ScrollRestorationRegistrationOptions = {}): ScrollViewRestorationHandle {\n const { commit } = getScrollSetupScope()\n const scrollTop = ref(0)\n const scrollLeft = ref(0)\n let top = 0\n let left = 0\n const handle = registerScrollRestoration({\n ...options,\n capture: () => ({ top, left }),\n async restore(snapshot, context) {\n if (!context.isActive()) {\n return\n }\n // 先同步实际位置,确保重复恢复相同目标也会产生有效的属性变化。\n // 内容和目标滚动位置分次提交,避免原生 scroll-view 使用更新前的尺寸。\n scrollTop.value = top\n scrollLeft.value = left\n await commit()\n if (!context.isActive()) {\n return\n }\n scrollTop.value = snapshot?.top ?? 0\n scrollLeft.value = snapshot?.left ?? 0\n await commit()\n },\n })\n return {\n ...handle,\n scrollTop,\n scrollLeft,\n onScroll(event) {\n top = event.detail.scrollTop\n left = event.detail.scrollLeft\n },\n }\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,yBAAyB,UAAgD,CAAC,GAA4B;CACpH,MAAM,QAAQ,wBAAwB,QAAQ,UAAU;CACxD,MAAM,OAAO,kCAAkC;CAC/C,IAAI,OAAO,MAAM,iBAAiB,YAChC,MAAM,IAAI,UAAU,6CAA6C;CAEnE,IAAI,MAAM;CACV,IAAI;CACJ,MAAM,WAA8B,CAAC;CAErC,OAAO,0BAA0B;EAC/B,GAAG;EACH,gBAAgB,EAAE,IAAI;EACtB,MAAM,QAAQ,UAAU,SAAS;GAC/B,MAAM,aAAa,MAAM;GACzB,IAAI,cAAc,WAAW,SAAS,QAAQ,WAAW,MAAM,aAAa,WAC1E,MAAM,IAAI,MAAM,kDAAkD;GAEpE,IAAI,CAAC,QAAQ,SAAS,GACpB;GAEF,MAAM,IAAI,SAAe,SAAS,WAAW;IAC3C,KAAK,aAAa;KAAE,WAAW,UAAU,OAAO;KAAG,UAAU;KAAG,eAAe,QAAQ;KAAG,MAAM;IAAO,CAAC;GAC1G,CAAC;EACH;CACF,GAAG;EACD,WAAW,OAAO;GAChB,OAAO;GACP,MAAM,eAAe,KAAK,uCAAuC,GAAG,IAAI;GACxE,IAAI,OAAO,iBAAiB,YAC1B,SAAS,KAAK,YAAY;GAE5B,SAAS,KAAK,cAAc,MAAM,iCAAiC,UAAU;IAC3E,IAAI,SAAS,OAAO,UAAU,YAAY,eAAe,SAAS,OAAO,MAAM,cAAc,UAC3F,MAAM,MAAM;GAEhB,CAAC,CAAC;GACF,yBAAyB,MAA8B,cAAc;EACvE;EACA,SAAS;GACP,KAAK,MAAM,WAAW,UACpB,QAAQ;GAEV,SAAS,SAAS;EACpB;CACF,CAAC;AACH;;AAGA,SAAgB,yBAAyB,UAAgD,CAAC,GAAgC;CACxH,MAAM,EAAE,WAAW,oBAAoB;CACvC,MAAM,YAAY,IAAI,CAAC;CACvB,MAAM,aAAa,IAAI,CAAC;CACxB,IAAI,MAAM;CACV,IAAI,OAAO;CAqBX,OAAO;EACL,GArBa,0BAA0B;GACvC,GAAG;GACH,gBAAgB;IAAE;IAAK;GAAK;GAC5B,MAAM,QAAQ,UAAU,SAAS;IAC/B,IAAI,CAAC,QAAQ,SAAS,GACpB;IAIF,UAAU,QAAQ;IAClB,WAAW,QAAQ;IACnB,MAAM,OAAO;IACb,IAAI,CAAC,QAAQ,SAAS,GACpB;IAEF,UAAU,QAAQ,UAAU,OAAO;IACnC,WAAW,QAAQ,UAAU,QAAQ;IACrC,MAAM,OAAO;GACf;EACF,CAEU;EACR;EACA;EACA,SAAS,OAAO;GACd,MAAM,MAAM,OAAO;GACnB,OAAO,MAAM,OAAO;EACtB;CACF;AACF"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { getCurrentMiniProgramPages } from "../../runtime/platform.mjs";
|
|
2
|
+
import { resolvePageRoute } from "../../routerInternal/location.mjs";
|
|
3
|
+
import { getActiveRouter } from "../instance.mjs";
|
|
4
|
+
import { currentScrollPage, subscribeScrollRouteEvents, supportsScrollRouteEvents } from "./host.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/router/scrollRestoration/controller.ts
|
|
7
|
+
const controllers = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
const routerControllers = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
/** 创建显式启用的路由会话;不会安装全局默认滚动行为。 */
|
|
10
|
+
function createScrollRestoration(options) {
|
|
11
|
+
if (routerControllers.has(options.router)) throw new Error("该 router 已创建 scroll restoration 会话,请复用或先 dispose()。");
|
|
12
|
+
const router = options.router;
|
|
13
|
+
const snapshots = /* @__PURE__ */ new Map();
|
|
14
|
+
const registrations = /* @__PURE__ */ new Map();
|
|
15
|
+
const seenPages = new WeakSet(getCurrentMiniProgramPages());
|
|
16
|
+
const report = options.onError ?? ((error) => console.error("[wevu/router] scroll restoration:", error));
|
|
17
|
+
let disposed = false;
|
|
18
|
+
let generation = 0;
|
|
19
|
+
let transition;
|
|
20
|
+
let unsubscribe;
|
|
21
|
+
const controller = {
|
|
22
|
+
automatic: supportsScrollRouteEvents(),
|
|
23
|
+
clear(key) {
|
|
24
|
+
if (key === void 0) snapshots.clear();
|
|
25
|
+
else snapshots.delete(key);
|
|
26
|
+
for (const records of registrations.values()) for (const record of records) if (key === void 0 || record.key === key) record.invalidate();
|
|
27
|
+
},
|
|
28
|
+
dispose() {
|
|
29
|
+
if (disposed) return;
|
|
30
|
+
disposed = true;
|
|
31
|
+
generation++;
|
|
32
|
+
unsubscribe?.();
|
|
33
|
+
for (const records of registrations.values()) for (const record of records) record.stop();
|
|
34
|
+
registrations.clear();
|
|
35
|
+
snapshots.clear();
|
|
36
|
+
transition = void 0;
|
|
37
|
+
routerControllers.delete(options.router);
|
|
38
|
+
controllers.delete(controller);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const state = {
|
|
42
|
+
controller,
|
|
43
|
+
get disposed() {
|
|
44
|
+
return disposed;
|
|
45
|
+
},
|
|
46
|
+
get transition() {
|
|
47
|
+
return transition;
|
|
48
|
+
},
|
|
49
|
+
get generation() {
|
|
50
|
+
return generation;
|
|
51
|
+
},
|
|
52
|
+
resolveRoute: (page) => router.resolve(resolvePageRoute(page)),
|
|
53
|
+
register(page, registration) {
|
|
54
|
+
if (disposed) throw new Error("scroll restoration 会话已 dispose()。");
|
|
55
|
+
let records = registrations.get(page);
|
|
56
|
+
if (!records) {
|
|
57
|
+
records = /* @__PURE__ */ new Set();
|
|
58
|
+
registrations.set(page, records);
|
|
59
|
+
}
|
|
60
|
+
for (const record of records) if (record.key === registration.key && record.id === registration.id) throw new Error(`同一页面重复注册 scroll restoration key/id: ${registration.key} / ${registration.id}`);
|
|
61
|
+
records.add(registration);
|
|
62
|
+
return () => {
|
|
63
|
+
records.delete(registration);
|
|
64
|
+
if (records.size === 0) registrations.delete(page);
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
read: (key, id) => snapshots.get(key)?.get(id),
|
|
68
|
+
save(key, id, value) {
|
|
69
|
+
if (disposed) return;
|
|
70
|
+
if (value === null) {
|
|
71
|
+
state.clear(key, id);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let entries = snapshots.get(key);
|
|
75
|
+
if (!entries) {
|
|
76
|
+
entries = /* @__PURE__ */ new Map();
|
|
77
|
+
snapshots.set(key, entries);
|
|
78
|
+
}
|
|
79
|
+
entries.set(id, value);
|
|
80
|
+
},
|
|
81
|
+
clear(key, id) {
|
|
82
|
+
const entries = snapshots.get(key);
|
|
83
|
+
entries?.delete(id);
|
|
84
|
+
if (entries?.size === 0) snapshots.delete(key);
|
|
85
|
+
for (const records of registrations.values()) for (const record of records) if (record.key === key && record.id === id) record.invalidate();
|
|
86
|
+
},
|
|
87
|
+
report
|
|
88
|
+
};
|
|
89
|
+
if (controller.automatic) unsubscribe = subscribeScrollRouteEvents({
|
|
90
|
+
BeforeAppRoute(event) {
|
|
91
|
+
if (disposed || transition?.event.routeEventId === event.routeEventId) return;
|
|
92
|
+
const page = currentScrollPage();
|
|
93
|
+
if (page) {
|
|
94
|
+
seenPages.add(page);
|
|
95
|
+
for (const record of registrations.get(page) ?? []) record.capture();
|
|
96
|
+
}
|
|
97
|
+
generation++;
|
|
98
|
+
for (const records of registrations.values()) for (const record of records) record.invalidate();
|
|
99
|
+
transition = {
|
|
100
|
+
event,
|
|
101
|
+
fresh: false,
|
|
102
|
+
done: false
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
BeforePageUnload(event) {
|
|
106
|
+
const page = event.page;
|
|
107
|
+
if (!page) return;
|
|
108
|
+
if (transition?.event.routeEventId !== event.routeEventId && page === currentScrollPage()) for (const record of registrations.get(page) ?? []) record.capture();
|
|
109
|
+
for (const record of registrations.get(page) ?? []) record.stop();
|
|
110
|
+
},
|
|
111
|
+
AppRoute(event) {
|
|
112
|
+
if (disposed || transition && transition.event.routeEventId !== event.routeEventId) return;
|
|
113
|
+
const page = currentScrollPage();
|
|
114
|
+
if (!page || resolvePageRoute(page).path !== event.path.replace(/^\/+/, "")) return;
|
|
115
|
+
transition ?? (transition = {
|
|
116
|
+
event,
|
|
117
|
+
fresh: false,
|
|
118
|
+
done: false
|
|
119
|
+
});
|
|
120
|
+
if (transition.page) return;
|
|
121
|
+
transition.page = page;
|
|
122
|
+
transition.fresh = !seenPages.has(page);
|
|
123
|
+
seenPages.add(page);
|
|
124
|
+
},
|
|
125
|
+
AppRouteDone(event) {
|
|
126
|
+
if (disposed || !transition) return;
|
|
127
|
+
const completesFreshPage = event.routeEventId === "" && transition.fresh && Number.isInteger(transition.event.webviewId) && event.webviewId === transition.event.webviewId && event.path === transition.event.path && typeof event.openType === "string" && event.openType === transition.event.openType;
|
|
128
|
+
if (transition.event.routeEventId !== event.routeEventId && !completesFreshPage) return;
|
|
129
|
+
if (!transition.page || transition.page !== currentScrollPage() || transition.done) return;
|
|
130
|
+
transition.done = true;
|
|
131
|
+
for (const record of registrations.get(transition.page) ?? []) record.restoreAutomatic();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
controllers.set(controller, state);
|
|
135
|
+
routerControllers.set(options.router, controller);
|
|
136
|
+
return controller;
|
|
137
|
+
}
|
|
138
|
+
function resolveScrollController(controller) {
|
|
139
|
+
const router = getActiveRouter();
|
|
140
|
+
const resolved = controller ?? (router && routerControllers.get(router));
|
|
141
|
+
const state = resolved && controllers.get(resolved);
|
|
142
|
+
if (!state || state.disposed) throw new Error("请先在应用启动时调用 createScrollRestoration({ router }),或传入有效的 controller。");
|
|
143
|
+
return state;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
//#endregion
|
|
147
|
+
export { createScrollRestoration, resolveScrollController };
|
|
148
|
+
//# sourceMappingURL=controller.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.mjs","names":[],"sources":["../../../../src/router/scrollRestoration/controller.ts"],"sourcesContent":["import type { RouteLocationNormalizedLoaded, RouterNavigation } from '../types'\nimport type { ScrollPage, ScrollRouteEvent } from './host'\nimport type { ScrollRestorationController, ScrollRestorationOptions } from './types'\nimport { resolvePageRoute } from '../../routerInternal/shared'\nimport { getCurrentMiniProgramPages } from '../../runtime/platform'\nimport { getActiveRouter } from '../instance'\nimport { currentScrollPage, subscribeScrollRouteEvents, supportsScrollRouteEvents } from './host'\n\nexport interface ScrollRegistration {\n key: string\n id: string\n capture: () => void\n invalidate: () => void\n restoreAutomatic: () => void\n stop: () => void\n}\n\ninterface ScrollTransition {\n event: ScrollRouteEvent\n page?: ScrollPage\n fresh: boolean\n done: boolean\n}\n\nexport interface ScrollControllerState {\n readonly controller: ScrollRestorationController\n readonly disposed: boolean\n readonly transition: ScrollTransition | undefined\n readonly generation: number\n resolveRoute: (page: ScrollPage) => RouteLocationNormalizedLoaded\n register: (page: ScrollPage, registration: ScrollRegistration) => () => void\n read: (key: string, id: string) => object | undefined\n save: (key: string, id: string, value: object | null) => void\n clear: (key: string, id: string) => void\n report: (error: unknown) => void\n}\n\nconst controllers = new WeakMap<ScrollRestorationController, ScrollControllerState>()\nconst routerControllers = new WeakMap<object, ScrollRestorationController>()\n\n/** 创建显式启用的路由会话;不会安装全局默认滚动行为。 */\nexport function createScrollRestoration<TRouteMap extends object>(options: ScrollRestorationOptions<TRouteMap>): ScrollRestorationController {\n if (routerControllers.has(options.router)) {\n throw new Error('该 router 已创建 scroll restoration 会话,请复用或先 dispose()。')\n }\n // 泛型仅约束公开路由名,内部处理来自原生页面的标准化路径。\n const router = options.router as unknown as RouterNavigation\n const snapshots = new Map<string, Map<string, object>>()\n const registrations = new Map<ScrollPage, Set<ScrollRegistration>>()\n const seenPages = new WeakSet<object>(getCurrentMiniProgramPages())\n // eslint-disable-next-line no-console -- 自动恢复没有调用方 Promise;默认处理必须报告错误。\n const report = options.onError ?? ((error: unknown) => console.error('[wevu/router] scroll restoration:', error))\n let disposed = false\n let generation = 0\n let transition: ScrollTransition | undefined\n let unsubscribe: (() => void) | undefined\n\n const controller: ScrollRestorationController = {\n automatic: supportsScrollRouteEvents(),\n clear(key) {\n if (key === undefined) {\n snapshots.clear()\n }\n else {\n snapshots.delete(key)\n }\n for (const records of registrations.values()) {\n for (const record of records) {\n if (key === undefined || record.key === key) {\n record.invalidate()\n }\n }\n }\n },\n dispose() {\n if (disposed) {\n return\n }\n disposed = true\n generation++\n unsubscribe?.()\n for (const records of registrations.values()) {\n for (const record of records) {\n record.stop()\n }\n }\n registrations.clear()\n snapshots.clear()\n transition = undefined\n routerControllers.delete(options.router)\n controllers.delete(controller)\n },\n }\n\n const state: ScrollControllerState = {\n controller,\n get disposed() {\n return disposed\n },\n get transition() {\n return transition\n },\n get generation() {\n return generation\n },\n resolveRoute: page => router.resolve(resolvePageRoute(page)),\n register(page, registration) {\n if (disposed) {\n throw new Error('scroll restoration 会话已 dispose()。')\n }\n let records = registrations.get(page)\n if (!records) {\n records = new Set()\n registrations.set(page, records)\n }\n for (const record of records) {\n if (record.key === registration.key && record.id === registration.id) {\n throw new Error(`同一页面重复注册 scroll restoration key/id: ${registration.key} / ${registration.id}`)\n }\n }\n records.add(registration)\n return () => {\n records.delete(registration)\n if (records.size === 0) {\n registrations.delete(page)\n }\n }\n },\n read: (key, id) => snapshots.get(key)?.get(id),\n save(key, id, value) {\n if (disposed) {\n return\n }\n if (value === null) {\n state.clear(key, id)\n return\n }\n let entries = snapshots.get(key)\n if (!entries) {\n entries = new Map()\n snapshots.set(key, entries)\n }\n entries.set(id, value)\n },\n clear(key, id) {\n const entries = snapshots.get(key)\n entries?.delete(id)\n if (entries?.size === 0) {\n snapshots.delete(key)\n }\n for (const records of registrations.values()) {\n for (const record of records) {\n if (record.key === key && record.id === id) {\n record.invalidate()\n }\n }\n }\n },\n report,\n }\n\n if (controller.automatic) {\n unsubscribe = subscribeScrollRouteEvents({\n BeforeAppRoute(event) {\n if (disposed || transition?.event.routeEventId === event.routeEventId) {\n return\n }\n const page = currentScrollPage()\n if (page) {\n seenPages.add(page)\n for (const record of registrations.get(page) ?? []) {\n record.capture()\n }\n }\n generation++\n for (const records of registrations.values()) {\n for (const record of records) {\n record.invalidate()\n }\n }\n transition = { event, fresh: false, done: false }\n },\n BeforePageUnload(event) {\n const page = event.page\n if (!page) {\n return\n }\n // 低层卸载可能没有前置路由通知;仍在当前页时最后同步读取内存缓存。\n if (transition?.event.routeEventId !== event.routeEventId && page === currentScrollPage()) {\n for (const record of registrations.get(page) ?? []) {\n record.capture()\n }\n }\n for (const record of registrations.get(page) ?? []) {\n record.stop()\n }\n },\n AppRoute(event) {\n if (disposed || (transition && transition.event.routeEventId !== event.routeEventId)) {\n return\n }\n const page = currentScrollPage()\n if (!page || resolvePageRoute(page).path !== event.path.replace(/^\\/+/, '')) {\n return\n }\n transition ??= { event, fresh: false, done: false }\n if (transition.page) {\n return\n }\n transition.page = page\n transition.fresh = !seenPages.has(page)\n seenPages.add(page)\n },\n AppRouteDone(event) {\n if (disposed || !transition) {\n return\n }\n // 原生同路径 reLaunch 可能返回空 id;只接受已确认的新页面对应的宿主 webview,\n // 不把旧页面、保留页面或仅路径相同的完成事件认作当前导航。\n const completesFreshPage = event.routeEventId === ''\n && transition.fresh\n && Number.isInteger(transition.event.webviewId)\n && event.webviewId === transition.event.webviewId\n && event.path === transition.event.path\n && typeof event.openType === 'string'\n && event.openType === transition.event.openType\n if (transition.event.routeEventId !== event.routeEventId && !completesFreshPage) {\n return\n }\n if (!transition.page || transition.page !== currentScrollPage() || transition.done) {\n return\n }\n transition.done = true\n for (const record of registrations.get(transition.page) ?? []) {\n record.restoreAutomatic()\n }\n },\n })\n }\n controllers.set(controller, state)\n routerControllers.set(options.router, controller)\n return controller\n}\n\nexport function resolveScrollController(controller?: ScrollRestorationController): ScrollControllerState {\n const router = getActiveRouter()\n const resolved = controller ?? (router && routerControllers.get(router))\n const state = resolved && controllers.get(resolved)\n if (!state || state.disposed) {\n throw new Error('请先在应用启动时调用 createScrollRestoration({ router }),或传入有效的 controller。')\n }\n return state\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getCurrentMiniProgramGlobalObject } from "../../runtime/platform/current.mjs";
|
|
2
|
+
import { getCurrentMiniProgramPages } from "../../runtime/platform.mjs";
|
|
3
|
+
import { pushHook } from "../../runtime/hooks/base.mjs";
|
|
4
|
+
import { WEVU_HOOKS_KEY, WEVU_NATIVE_INSTANCE_KEY, WEVU_ROUTE_EVENT_CONTRACT_KEY } from "@weapp-core/constants";
|
|
5
|
+
|
|
6
|
+
//#region src/router/scrollRestoration/host.ts
|
|
7
|
+
const routeEvents = [
|
|
8
|
+
"BeforeAppRoute",
|
|
9
|
+
"BeforePageUnload",
|
|
10
|
+
"AppRoute",
|
|
11
|
+
"AppRouteDone"
|
|
12
|
+
];
|
|
13
|
+
function supportsScrollRouteEvents(host = getCurrentMiniProgramGlobalObject()) {
|
|
14
|
+
if (!host || !routeEvents.every((name) => typeof host[`on${name}`] === "function" && typeof host[`off${name}`] === "function")) return false;
|
|
15
|
+
if (host[WEVU_ROUTE_EVENT_CONTRACT_KEY] === 1) return true;
|
|
16
|
+
const version = host.getAppBaseInfo?.().SDKVersion ?? host.getSystemInfoSync?.().SDKVersion;
|
|
17
|
+
if (typeof version !== "string") return false;
|
|
18
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:\D|$)/.exec(version);
|
|
19
|
+
if (!match) return false;
|
|
20
|
+
const major = Number(match[1]);
|
|
21
|
+
const minor = Number(match[2]);
|
|
22
|
+
const patch = Number(match[3]);
|
|
23
|
+
return major > 3 || major === 3 && (minor > 5 || minor === 5 && patch >= 5);
|
|
24
|
+
}
|
|
25
|
+
function subscribeScrollRouteEvents(handlers) {
|
|
26
|
+
const host = getCurrentMiniProgramGlobalObject();
|
|
27
|
+
const cleanups = [];
|
|
28
|
+
try {
|
|
29
|
+
for (const name of routeEvents) {
|
|
30
|
+
const listener = (event) => {
|
|
31
|
+
if (typeof event?.routeEventId === "string" && typeof event.path === "string") handlers[name](event);
|
|
32
|
+
};
|
|
33
|
+
host[`on${name}`](listener);
|
|
34
|
+
cleanups.push(() => host[`off${name}`](listener));
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
for (const cleanup of cleanups) cleanup();
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
return () => {
|
|
41
|
+
for (const cleanup of cleanups) cleanup();
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function currentScrollPage() {
|
|
45
|
+
const pages = getCurrentMiniProgramPages();
|
|
46
|
+
return pages[pages.length - 1];
|
|
47
|
+
}
|
|
48
|
+
/** 按实例或宿主页面 id 查找归属,不用路径猜测同路由的多个页面。 */
|
|
49
|
+
function resolveScrollPage(instance) {
|
|
50
|
+
const pages = getCurrentMiniProgramPages();
|
|
51
|
+
const visited = /* @__PURE__ */ new Set();
|
|
52
|
+
let owner = instance;
|
|
53
|
+
while (owner && !visited.has(owner)) {
|
|
54
|
+
visited.add(owner);
|
|
55
|
+
if (pages.includes(owner)) return owner;
|
|
56
|
+
const pageId = owner.__wxWebviewId__;
|
|
57
|
+
if (pageId !== void 0) {
|
|
58
|
+
const page = pages.find((candidate) => candidate.__wxWebviewId__ === pageId);
|
|
59
|
+
if (page) return page;
|
|
60
|
+
}
|
|
61
|
+
const native = owner[WEVU_NATIVE_INSTANCE_KEY] ?? owner.$;
|
|
62
|
+
owner = native && native !== owner ? native : owner.selectOwnerComponent?.();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function addScrollHook(instance, name, handler) {
|
|
66
|
+
pushHook(instance, name, handler);
|
|
67
|
+
return () => {
|
|
68
|
+
const bucket = instance[WEVU_HOOKS_KEY];
|
|
69
|
+
const hooks = bucket?.[name];
|
|
70
|
+
if (bucket && Array.isArray(hooks)) bucket[name] = hooks.filter((hook) => hook !== handler);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
export { addScrollHook, currentScrollPage, resolveScrollPage, subscribeScrollRouteEvents, supportsScrollRouteEvents };
|
|
76
|
+
//# sourceMappingURL=host.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.mjs","names":[],"sources":["../../../../src/router/scrollRestoration/host.ts"],"sourcesContent":["import type { WEVU_READY_CALLED_KEY } from '@weapp-core/constants'\nimport type { MiniProgramPageLike } from '../../routerInternal/types'\nimport type { InternalRuntimeState } from '../../runtime/types'\nimport type { LocationQueryRaw } from '../types'\nimport { WEVU_HOOKS_KEY, WEVU_NATIVE_INSTANCE_KEY, WEVU_ROUTE_EVENT_CONTRACT_KEY } from '@weapp-core/constants'\nimport { pushHook } from '../../runtime/hooks/base'\nimport { getCurrentMiniProgramGlobalObject, getCurrentMiniProgramPages } from '../../runtime/platform'\n\ntype ScrollHook = (...args: unknown[]) => void\n\nexport interface ScrollPage extends MiniProgramPageLike {\n __wxWebviewId__?: number | string\n [WEVU_NATIVE_INSTANCE_KEY]?: ScrollPage\n [WEVU_READY_CALLED_KEY]?: boolean\n [WEVU_HOOKS_KEY]?: Record<string, ScrollHook | ScrollHook[]>\n $?: ScrollPage\n selectOwnerComponent?: () => ScrollPage | undefined\n onPageScroll?: (event: { scrollTop: number }) => unknown\n}\n\nexport interface ScrollRouteEvent {\n routeEventId: string\n path: string\n query?: LocationQueryRaw\n openType?: string\n webviewId?: number\n renderer?: string\n page?: ScrollPage\n}\n\nconst routeEvents = ['BeforeAppRoute', 'BeforePageUnload', 'AppRoute', 'AppRouteDone'] as const\nexport type ScrollRouteEventName = typeof routeEvents[number]\n\nexport function supportsScrollRouteEvents(host = getCurrentMiniProgramGlobalObject()): boolean {\n if (!host || !routeEvents.every(name => typeof host[`on${name}`] === 'function' && typeof host[`off${name}`] === 'function')) {\n return false\n }\n if (host[WEVU_ROUTE_EVENT_CONTRACT_KEY] === 1) {\n return true\n }\n const version = host.getAppBaseInfo?.().SDKVersion ?? host.getSystemInfoSync?.().SDKVersion\n if (typeof version !== 'string') {\n return false\n }\n const match = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:\\D|$)/.exec(version)\n if (!match) {\n return false\n }\n const major = Number(match[1])\n const minor = Number(match[2])\n const patch = Number(match[3])\n return major > 3 || (major === 3 && (minor > 5 || (minor === 5 && patch >= 5)))\n}\n\nexport function subscribeScrollRouteEvents(handlers: Record<ScrollRouteEventName, (event: ScrollRouteEvent) => void>): () => void {\n const host = getCurrentMiniProgramGlobalObject()!\n const cleanups: Array<() => void> = []\n try {\n for (const name of routeEvents) {\n const listener = (event: ScrollRouteEvent) => {\n if (typeof event?.routeEventId === 'string' && typeof event.path === 'string') {\n handlers[name](event)\n }\n }\n host[`on${name}`](listener)\n cleanups.push(() => host[`off${name}`](listener))\n }\n }\n catch (error) {\n for (const cleanup of cleanups) {\n cleanup()\n }\n throw error\n }\n return () => {\n for (const cleanup of cleanups) {\n cleanup()\n }\n }\n}\n\nexport function currentScrollPage(): ScrollPage | undefined {\n const pages = getCurrentMiniProgramPages()\n return pages[pages.length - 1]\n}\n\n/** 按实例或宿主页面 id 查找归属,不用路径猜测同路由的多个页面。 */\nexport function resolveScrollPage(instance: ScrollPage): ScrollPage | undefined {\n const pages = getCurrentMiniProgramPages()\n const visited = new Set<object>()\n let owner: ScrollPage | undefined = instance\n while (owner && !visited.has(owner)) {\n visited.add(owner)\n if (pages.includes(owner)) {\n return owner\n }\n const pageId = owner.__wxWebviewId__\n if (pageId !== undefined) {\n const page = pages.find(candidate => candidate.__wxWebviewId__ === pageId)\n if (page) {\n return page\n }\n }\n const native: ScrollPage | undefined = owner[WEVU_NATIVE_INSTANCE_KEY] ?? owner.$\n owner = native && native !== owner\n ? native\n : owner.selectOwnerComponent?.()\n }\n return undefined\n}\n\nexport function addScrollHook(instance: ScrollPage, name: string, handler: ScrollHook): () => void {\n pushHook(instance as InternalRuntimeState, name, handler)\n return () => {\n const bucket = instance[WEVU_HOOKS_KEY]\n const hooks = bucket?.[name]\n if (bucket && Array.isArray(hooks)) {\n // 不原地修改正在被生命周期分发器遍历的数组,避免跳过后续用户 hook。\n bucket[name] = hooks.filter(hook => hook !== handler)\n }\n }\n}\n"],"mappings":";;;;;;AA8BA,MAAM,cAAc;CAAC;CAAkB;CAAoB;CAAY;AAAc;AAGrF,SAAgB,0BAA0B,OAAO,kCAAkC,GAAY;CAC7F,IAAI,CAAC,QAAQ,CAAC,YAAY,OAAM,SAAQ,OAAO,KAAK,KAAK,YAAY,cAAc,OAAO,KAAK,MAAM,YAAY,UAAU,GACzH,OAAO;CAET,IAAI,KAAK,mCAAmC,GAC1C,OAAO;CAET,MAAM,UAAU,KAAK,iBAAiB,CAAC,CAAC,cAAc,KAAK,oBAAoB,CAAC,CAAC;CACjF,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,MAAM,QAAQ,+BAA+B,KAAK,OAAO;CACzD,IAAI,CAAC,OACH,OAAO;CAET,MAAM,QAAQ,OAAO,MAAM,EAAE;CAC7B,MAAM,QAAQ,OAAO,MAAM,EAAE;CAC7B,MAAM,QAAQ,OAAO,MAAM,EAAE;CAC7B,OAAO,QAAQ,KAAM,UAAU,MAAM,QAAQ,KAAM,UAAU,KAAK,SAAS;AAC7E;AAEA,SAAgB,2BAA2B,UAAuF;CAChI,MAAM,OAAO,kCAAkC;CAC/C,MAAM,WAA8B,CAAC;CACrC,IAAI;EACF,KAAK,MAAM,QAAQ,aAAa;GAC9B,MAAM,YAAY,UAA4B;IAC5C,IAAI,OAAO,OAAO,iBAAiB,YAAY,OAAO,MAAM,SAAS,UACnE,SAAS,KAAK,CAAC,KAAK;GAExB;GACA,KAAK,KAAK,OAAO,CAAC,QAAQ;GAC1B,SAAS,WAAW,KAAK,MAAM,OAAO,CAAC,QAAQ,CAAC;EAClD;CACF,SACO,OAAO;EACZ,KAAK,MAAM,WAAW,UACpB,QAAQ;EAEV,MAAM;CACR;CACA,aAAa;EACX,KAAK,MAAM,WAAW,UACpB,QAAQ;CAEZ;AACF;AAEA,SAAgB,oBAA4C;CAC1D,MAAM,QAAQ,2BAA2B;CACzC,OAAO,MAAM,MAAM,SAAS;AAC9B;;AAGA,SAAgB,kBAAkB,UAA8C;CAC9E,MAAM,QAAQ,2BAA2B;CACzC,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI,QAAgC;CACpC,OAAO,SAAS,CAAC,QAAQ,IAAI,KAAK,GAAG;EACnC,QAAQ,IAAI,KAAK;EACjB,IAAI,MAAM,SAAS,KAAK,GACtB,OAAO;EAET,MAAM,SAAS,MAAM;EACrB,IAAI,WAAW,QAAW;GACxB,MAAM,OAAO,MAAM,MAAK,cAAa,UAAU,oBAAoB,MAAM;GACzE,IAAI,MACF,OAAO;EAEX;EACA,MAAM,SAAiC,MAAM,6BAA6B,MAAM;EAChF,QAAQ,UAAU,WAAW,QACzB,SACA,MAAM,uBAAuB;CACnC;AAEF;AAEA,SAAgB,cAAc,UAAsB,MAAc,SAAiC;CACjG,SAAS,UAAkC,MAAM,OAAO;CACxD,aAAa;EACX,MAAM,SAAS,SAAS;EACxB,MAAM,QAAQ,SAAS;EACvB,IAAI,UAAU,MAAM,QAAQ,KAAK,GAE/B,OAAO,QAAQ,MAAM,QAAO,SAAQ,SAAS,OAAO;CAExD;AACF"}
|