wevu 0.0.1 → 1.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
- const require_ref = require('./ref-DtCdcykK.cjs');
1
+ const require_store = require('./store-Cmw9vWBT.cjs');
2
2
 
3
3
  //#region src/reactivity/readonly.ts
4
4
  function readonly(target) {
5
- if (require_ref.isRef(target)) {
5
+ if (require_store.isRef(target)) {
6
6
  const source = target;
7
7
  return {
8
8
  get value() {
@@ -13,7 +13,7 @@ function readonly(target) {
13
13
  }
14
14
  };
15
15
  }
16
- if (!require_ref.isObject(target)) return target;
16
+ if (!require_store.isObject(target)) return target;
17
17
  return new Proxy(target, {
18
18
  set() {
19
19
  throw new Error("Cannot set property on readonly object");
@@ -30,10 +30,81 @@ function readonly(target) {
30
30
  });
31
31
  }
32
32
 
33
+ //#endregion
34
+ //#region src/reactivity/shallowRef.ts
35
+ function shallowRef(value, defaultValue) {
36
+ return require_store.customRef((track, trigger) => ({
37
+ get() {
38
+ track();
39
+ return value;
40
+ },
41
+ set(newValue) {
42
+ if (Object.is(value, newValue)) return;
43
+ value = newValue;
44
+ trigger();
45
+ }
46
+ }), defaultValue);
47
+ }
48
+ /**
49
+ * 判断传入值是否为浅层 ref。
50
+ *
51
+ * @param r 待判断的值
52
+ * @returns 若为浅层 ref 则返回 true
53
+ */
54
+ function isShallowRef(r) {
55
+ return r && typeof r === "object" && "value" in r && typeof r.value !== "function";
56
+ }
57
+ /**
58
+ * 主动触发一次浅层 ref 的更新(无需深度比较)。
59
+ *
60
+ * @param ref 需要触发的 ref
61
+ */
62
+ function triggerRef(ref$1) {
63
+ if (ref$1 && typeof ref$1 === "object" && "value" in ref$1) ref$1.value = ref$1.value;
64
+ }
65
+
66
+ //#endregion
67
+ //#region src/reactivity/toRefs.ts
68
+ /**
69
+ * 将一个响应式对象转换成“同结构的普通对象”,其中每个字段都是指向原对象对应属性的 ref。
70
+ *
71
+ * @param object 待转换的响应式对象
72
+ * @returns 包含若干 ref 的普通对象
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const state = reactive({ foo: 1, bar: 2 })
77
+ * const stateAsRefs = toRefs(state)
78
+ *
79
+ * stateAsRefs.foo.value++ // 2
80
+ * state.foo // 2
81
+ * ```
82
+ */
83
+ function toRefs(object) {
84
+ if (!require_store.isReactive(object)) console.warn(`toRefs() expects a reactive object but received a plain one.`);
85
+ const result = Array.isArray(object) ? Array.from({ length: object.length }) : {};
86
+ for (const key in object) result[key] = toRef(object, key);
87
+ return result;
88
+ }
89
+ function toRef(object, key, defaultValue) {
90
+ const value = object[key];
91
+ if (require_store.isRef(value)) return value;
92
+ return require_store.customRef((track, trigger) => ({
93
+ get() {
94
+ track();
95
+ return object[key];
96
+ },
97
+ set(newValue) {
98
+ object[key] = newValue;
99
+ trigger();
100
+ }
101
+ }), defaultValue);
102
+ }
103
+
33
104
  //#endregion
34
105
  //#region src/reactivity/traverse.ts
35
106
  function traverse(value, seen = /* @__PURE__ */ new Set()) {
36
- if (!require_ref.isObject(value) || seen.has(value)) return value;
107
+ if (!require_store.isObject(value) || seen.has(value)) return value;
37
108
  seen.add(value);
38
109
  for (const key in value) traverse(value[key], seen);
39
110
  return value;
@@ -51,15 +122,15 @@ function getDeepWatchStrategy() {
51
122
  function watch(source, cb, options = {}) {
52
123
  let getter;
53
124
  if (typeof source === "function") getter = source;
54
- else if (require_ref.isRef(source)) getter = () => source.value;
55
- else if (require_ref.isReactive(source)) getter = () => source;
125
+ else if (require_store.isRef(source)) getter = () => source.value;
126
+ else if (require_store.isReactive(source)) getter = () => source;
56
127
  else throw new Error("Invalid watch source");
57
128
  if (options.deep) {
58
129
  const baseGetter = getter;
59
130
  getter = () => {
60
131
  const val = baseGetter();
61
- if (__deepWatchStrategy === "version" && require_ref.isReactive(val)) {
62
- require_ref.touchReactive(val);
132
+ if (__deepWatchStrategy === "version" && require_store.isReactive(val)) {
133
+ require_store.touchReactive(val);
63
134
  return val;
64
135
  }
65
136
  return traverse(val);
@@ -78,37 +149,37 @@ function watch(source, cb, options = {}) {
78
149
  cb(newValue, oldValue, onCleanup);
79
150
  oldValue = newValue;
80
151
  };
81
- runner = require_ref.effect(() => getter(), {
82
- scheduler: () => require_ref.queueJob(job),
152
+ runner = require_store.effect(() => getter(), {
153
+ scheduler: () => require_store.queueJob(job),
83
154
  lazy: true
84
155
  });
85
156
  if (options.immediate) job();
86
157
  else oldValue = runner();
87
158
  return () => {
88
159
  cleanup?.();
89
- require_ref.stop(runner);
160
+ require_store.stop(runner);
90
161
  };
91
162
  }
92
163
  /**
93
- * watchEffect registers a reactive effect with optional cleanup.
94
- * The effect executes immediately and re-runs when its dependencies change.
164
+ * watchEffect 注册一个响应式副作用,可选清理函数。
165
+ * 副作用会立即执行,并在依赖变化时重新运行。
95
166
  */
96
167
  function watchEffect(effectFn) {
97
168
  let cleanup;
98
169
  const onCleanup = (fn) => {
99
170
  cleanup = fn;
100
171
  };
101
- const runner = require_ref.effect(() => {
172
+ const runner = require_store.effect(() => {
102
173
  cleanup?.();
103
174
  cleanup = void 0;
104
175
  effectFn(onCleanup);
105
- }, { scheduler: () => require_ref.queueJob(() => {
176
+ }, { scheduler: () => require_store.queueJob(() => {
106
177
  if (runner.active) runner();
107
178
  }) });
108
179
  runner();
109
180
  return () => {
110
181
  cleanup?.();
111
- require_ref.stop(runner);
182
+ require_store.stop(runner);
112
183
  };
113
184
  }
114
185
 
@@ -218,9 +289,9 @@ function isPlainObject(value) {
218
289
  return proto === null || proto === Object.prototype;
219
290
  }
220
291
  function toPlain(value, seen = /* @__PURE__ */ new WeakMap()) {
221
- const unwrapped = require_ref.unref(value);
292
+ const unwrapped = require_store.unref(value);
222
293
  if (typeof unwrapped !== "object" || unwrapped === null) return unwrapped;
223
- const raw = require_ref.isReactive(unwrapped) ? require_ref.toRaw(unwrapped) : unwrapped;
294
+ const raw = require_store.isReactive(unwrapped) ? require_store.toRaw(unwrapped) : unwrapped;
224
295
  if (seen.has(raw)) return seen.get(raw);
225
296
  if (Array.isArray(raw)) {
226
297
  const arr = [];
@@ -397,9 +468,114 @@ function onAddToFavorites(handler) {
397
468
  if (!__currentInstance) throw new Error("onAddToFavorites() must be called synchronously inside setup()");
398
469
  pushHook(__currentInstance, "onAddToFavorites", handler, { single: true });
399
470
  }
471
+ /**
472
+ * Vue 3 对齐:组件/页面已挂载,映射小程序 onReady
473
+ */
474
+ function onMounted(handler) {
475
+ if (!__currentInstance) throw new Error("onMounted() must be called synchronously inside setup()");
476
+ pushHook(__currentInstance, "onReady", handler);
477
+ }
478
+ /**
479
+ * Vue 3 对齐:组件/页面更新后触发。
480
+ * 小程序没有专用 update 生命周期,这里在每次 setData 完成后调用。
481
+ */
482
+ function onUpdated(handler) {
483
+ if (!__currentInstance) throw new Error("onUpdated() must be called synchronously inside setup()");
484
+ pushHook(__currentInstance, "__wevuOnUpdated", handler);
485
+ }
486
+ /**
487
+ * Vue 3 对齐:卸载前触发。
488
+ * 小程序无 before-unload 生命周期,setup 时同步执行以保持语义。
489
+ */
490
+ function onBeforeUnmount(handler) {
491
+ if (!__currentInstance) throw new Error("onBeforeUnmount() must be called synchronously inside setup()");
492
+ handler();
493
+ }
494
+ /**
495
+ * Vue 3 对齐:组件/页面卸载;映射到页面 onUnload 或组件 detached
496
+ */
497
+ function onUnmounted(handler) {
498
+ if (!__currentInstance) throw new Error("onUnmounted() must be called synchronously inside setup()");
499
+ pushHook(__currentInstance, "onUnload", handler);
500
+ }
501
+ /**
502
+ * Vue 3 对齐:挂载前;setup 时同步触发以模拟 beforeMount 语义
503
+ */
504
+ function onBeforeMount(handler) {
505
+ if (!__currentInstance) throw new Error("onBeforeMount() must be called synchronously inside setup()");
506
+ handler();
507
+ }
508
+ /**
509
+ * Vue 3 对齐:更新前;在每次 setData 前触发
510
+ */
511
+ function onBeforeUpdate(handler) {
512
+ if (!__currentInstance) throw new Error("onBeforeUpdate() must be called synchronously inside setup()");
513
+ pushHook(__currentInstance, "__wevuOnBeforeUpdate", handler);
514
+ }
515
+ /**
516
+ * Vue 3 对齐:错误捕获;映射到小程序 onError
517
+ */
518
+ function onErrorCaptured(handler) {
519
+ if (!__currentInstance) throw new Error("onErrorCaptured() must be called synchronously inside setup()");
520
+ pushHook(__currentInstance, "onAppError", (err) => handler(err, __currentInstance, ""));
521
+ }
522
+ /**
523
+ * Vue 3 对齐:组件激活;映射到小程序 onShow
524
+ */
525
+ function onActivated(handler) {
526
+ if (!__currentInstance) throw new Error("onActivated() must be called synchronously inside setup()");
527
+ pushHook(__currentInstance, "onShow", handler);
528
+ }
529
+ /**
530
+ * Vue 3 对齐:组件失活;映射到小程序 onHide
531
+ */
532
+ function onDeactivated(handler) {
533
+ if (!__currentInstance) throw new Error("onDeactivated() must be called synchronously inside setup()");
534
+ pushHook(__currentInstance, "onHide", handler);
535
+ }
536
+ /**
537
+ * Vue 3 对齐:服务端渲染前置钩子。
538
+ * 小程序无此场景,保留空实现以保持 API 兼容。
539
+ */
540
+ function onServerPrefetch(_handler) {
541
+ if (!__currentInstance) throw new Error("onServerPrefetch() must be called synchronously inside setup()");
542
+ }
543
+ function callUpdateHooks(target, phase) {
544
+ callHookList(target, phase === "before" ? "__wevuOnBeforeUpdate" : "__wevuOnUpdated");
545
+ }
400
546
 
401
547
  //#endregion
402
548
  //#region src/runtime/register.ts
549
+ function runInlineExpression(ctx, expr, event) {
550
+ const handlerName = typeof expr === "string" ? expr : void 0;
551
+ if (!handlerName) return;
552
+ const argsRaw = (event?.currentTarget)?.dataset?.wvArgs ?? (event?.target)?.dataset?.wvArgs;
553
+ let args = [];
554
+ if (typeof argsRaw === "string") try {
555
+ args = JSON.parse(argsRaw);
556
+ } catch {
557
+ args = [];
558
+ }
559
+ const resolvedArgs = args.map((item) => item === "$event" ? event : item);
560
+ const handler = ctx?.[handlerName];
561
+ if (typeof handler === "function") return handler.apply(ctx, resolvedArgs);
562
+ }
563
+ function runSetupFunction(setup, props, context) {
564
+ if (typeof setup !== "function") return;
565
+ const runtimeContext = context?.runtime ?? {
566
+ methods: Object.create(null),
567
+ state: {},
568
+ proxy: {},
569
+ watch: () => () => {},
570
+ bindModel: () => {}
571
+ };
572
+ if (context) context.runtime = runtimeContext;
573
+ const finalContext = {
574
+ ...context ?? {},
575
+ runtime: runtimeContext
576
+ };
577
+ return setup.length >= 2 ? setup(props, finalContext) : setup(finalContext);
578
+ }
403
579
  function normalizeWatchDescriptor(descriptor, runtime, instance) {
404
580
  if (typeof descriptor === "function") return {
405
581
  handler: descriptor.bind(runtime.proxy),
@@ -449,32 +625,58 @@ function registerWatches(runtime, watchMap, instance) {
449
625
  return stops;
450
626
  }
451
627
  function mountRuntimeInstance(target, runtimeApp, watchMap, setup) {
628
+ if (target.__wevu) return target.__wevu;
452
629
  const runtime = runtimeApp.mount({ setData(payload) {
453
630
  if (typeof target.setData === "function") target.setData(payload);
454
631
  } });
632
+ const runtimeProxy = runtime?.proxy ?? {};
633
+ const runtimeState = runtime?.state ?? {};
634
+ if (!runtime?.methods) try {
635
+ runtime.methods = Object.create(null);
636
+ } catch {}
637
+ const runtimeMethods = runtime?.methods ?? Object.create(null);
638
+ const runtimeWatch = runtime?.watch ?? (() => () => {});
639
+ const runtimeBindModel = runtime?.bindModel ?? (() => {});
640
+ const runtimeWithDefaults = {
641
+ ...runtime ?? {},
642
+ state: runtimeState,
643
+ proxy: runtimeProxy,
644
+ methods: runtimeMethods,
645
+ watch: runtimeWatch,
646
+ bindModel: runtimeBindModel
647
+ };
455
648
  Object.defineProperty(target, "$wevu", {
456
- value: runtime,
649
+ value: runtimeWithDefaults,
457
650
  configurable: true,
458
651
  enumerable: false,
459
652
  writable: false
460
653
  });
461
- target.__wevu = runtime;
654
+ target.__wevu = runtimeWithDefaults;
462
655
  if (watchMap) {
463
- const stops = registerWatches(runtime, watchMap, target);
656
+ const stops = registerWatches(runtimeWithDefaults, watchMap, target);
464
657
  if (stops.length) target.__wevuWatchStops = stops;
465
658
  }
466
659
  if (setup) {
660
+ const props = target.properties || {};
467
661
  const context = {
468
- runtime,
469
- state: runtime.state,
470
- proxy: runtime.proxy,
471
- bindModel: runtime.bindModel.bind(runtime),
472
- watch: runtime.watch.bind(runtime),
473
- instance: target
662
+ props,
663
+ runtime: runtimeWithDefaults,
664
+ state: runtimeState,
665
+ proxy: runtimeProxy,
666
+ bindModel: runtimeBindModel.bind(runtimeWithDefaults),
667
+ watch: runtimeWatch.bind(runtimeWithDefaults),
668
+ instance: target,
669
+ emit: (event, ...args) => {
670
+ if (typeof target.triggerEvent === "function") target.triggerEvent(event, ...args);
671
+ },
672
+ expose: (exposed) => {
673
+ target.__wevuExposed = exposed;
674
+ },
675
+ attrs: {}
474
676
  };
475
677
  setCurrentInstance(target);
476
678
  try {
477
- const result = setup(context);
679
+ const result = runSetupFunction(setup, props, context);
478
680
  if (result && typeof result === "object") Object.keys(result).forEach((key) => {
479
681
  const val = result[key];
480
682
  if (typeof val === "function") runtime.methods[key] = (...args) => val.apply(runtime.proxy, args);
@@ -495,6 +697,7 @@ function mountRuntimeInstance(target, runtimeApp, watchMap, setup) {
495
697
  }
496
698
  function teardownRuntimeInstance(target) {
497
699
  const runtime = target.__wevu;
700
+ if (runtime && target.__wevuHooks) callHookList(target, "onUnload", []);
498
701
  if (target.__wevuHooks) target.__wevuHooks = void 0;
499
702
  const stops = target.__wevuWatchStops;
500
703
  if (Array.isArray(stops)) for (const stop$1 of stops) try {
@@ -510,6 +713,10 @@ function registerApp(runtimeApp, methods, watch$1, setup, mpOptions) {
510
713
  const methodNames = Object.keys(methods ?? {});
511
714
  const appOptions = { ...mpOptions };
512
715
  appOptions.globalData = appOptions.globalData ?? {};
716
+ if (!appOptions.__weapp_vite_inline) appOptions.__weapp_vite_inline = function __weapp_vite_inline(event) {
717
+ const expr = event?.currentTarget?.dataset?.wvHandler ?? event?.target?.dataset?.wvHandler;
718
+ return runInlineExpression(this.__wevu?.proxy ?? this, expr, event);
719
+ };
513
720
  const userOnLaunch = appOptions.onLaunch;
514
721
  appOptions.onLaunch = function onLaunch(...args) {
515
722
  mountRuntimeInstance(this, runtimeApp, watch$1, setup);
@@ -544,89 +751,38 @@ function registerApp(runtimeApp, methods, watch$1, setup, mpOptions) {
544
751
  }
545
752
  App(appOptions);
546
753
  }
547
- function registerPage(runtimeApp, methods, watch$1, setup, mpOptions, features) {
548
- if (typeof Page !== "function") throw new TypeError("definePage requires the global Page constructor to be available");
549
- const methodNames = Object.keys(methods ?? {});
550
- const pageOptions = { ...mpOptions };
551
- const userOnLoad = mpOptions.onLoad;
552
- pageOptions.onLoad = function onLoad(...args) {
553
- mountRuntimeInstance(this, runtimeApp, watch$1, setup);
554
- callHookList(this, "onShow", args);
555
- if (typeof userOnLoad === "function") userOnLoad.apply(this, args);
556
- };
557
- const userOnUnload = mpOptions.onUnload;
558
- pageOptions.onUnload = function onUnload$1(...args) {
559
- teardownRuntimeInstance(this);
560
- if (typeof userOnUnload === "function") userOnUnload.apply(this, args);
754
+ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions, features) {
755
+ const { methods: userMethods = {}, lifetimes: userLifetimes = {}, pageLifetimes: userPageLifetimes = {}, options: userOptions = {}, ...rest } = mpOptions;
756
+ const userOnLoad = rest.onLoad;
757
+ const userOnUnload = rest.onUnload;
758
+ const userOnShow = rest.onShow;
759
+ const userOnHide = rest.onHide;
760
+ const userOnReady = rest.onReady;
761
+ const userOnSaveExitState = rest.onSaveExitState;
762
+ const userOnPageScroll = rest.onPageScroll;
763
+ const userOnShareAppMessage = rest.onShareAppMessage;
764
+ const userOnShareTimeline = rest.onShareTimeline;
765
+ const userOnAddToFavorites = rest.onAddToFavorites;
766
+ const restOptions = { ...rest };
767
+ delete restOptions.onLoad;
768
+ delete restOptions.onUnload;
769
+ delete restOptions.onShow;
770
+ delete restOptions.onHide;
771
+ delete restOptions.onReady;
772
+ delete restOptions.onSaveExitState;
773
+ delete restOptions.onPageScroll;
774
+ delete restOptions.onShareAppMessage;
775
+ delete restOptions.onShareTimeline;
776
+ delete restOptions.onAddToFavorites;
777
+ const finalOptions = {
778
+ multipleSlots: userOptions.multipleSlots ?? true,
779
+ ...userOptions
561
780
  };
562
- const userOnShow = mpOptions.onShow;
563
- pageOptions.onShow = function onShow$1(...args) {
564
- callHookList(this, "onShow", args);
565
- if (typeof userOnShow === "function") userOnShow.apply(this, args);
566
- };
567
- const userOnHide = mpOptions.onHide;
568
- pageOptions.onHide = function onHide$1(...args) {
569
- callHookList(this, "onHide", args);
570
- if (typeof userOnHide === "function") userOnHide.apply(this, args);
571
- };
572
- const userOnReady = mpOptions.onReady;
573
- pageOptions.onReady = function onReady$1(...args) {
574
- callHookList(this, "onReady", args);
575
- if (typeof userOnReady === "function") return userOnReady.apply(this, args);
576
- };
577
- const userOnSaveExitState = mpOptions.onSaveExitState;
578
- pageOptions.onSaveExitState = function onSaveExitState$1(...args) {
579
- const ret = callHookReturn(this, "onSaveExitState", args);
580
- if (ret !== void 0) return ret;
581
- if (typeof userOnSaveExitState === "function") return userOnSaveExitState.apply(this, args);
582
- };
583
- if (features?.listenPageScroll) {
584
- const userOnPageScroll = mpOptions.onPageScroll;
585
- pageOptions.onPageScroll = function onPageScroll$1(...args) {
586
- callHookList(this, "onPageScroll", args);
587
- if (typeof userOnPageScroll === "function") return userOnPageScroll.apply(this, args);
588
- };
589
- }
590
- if (features?.enableShareAppMessage) {
591
- const userOnShare = mpOptions.onShareAppMessage;
592
- pageOptions.onShareAppMessage = function pageOnShareAppMessage(...args) {
593
- const ret = callHookReturn(this, "onShareAppMessage", args);
594
- if (ret !== void 0) return ret;
595
- if (typeof userOnShare === "function") return userOnShare.apply(this, args);
596
- };
597
- }
598
- if (features?.enableShareTimeline) {
599
- const userOnShareTimeline = mpOptions.onShareTimeline;
600
- pageOptions.onShareTimeline = function pageOnShareTimeline(...args) {
601
- const ret = callHookReturn(this, "onShareTimeline", args);
602
- if (ret !== void 0) return ret;
603
- if (typeof userOnShareTimeline === "function") return userOnShareTimeline.apply(this, args);
604
- };
605
- }
606
- if (features?.enableAddToFavorites) {
607
- const userOnAddToFavorites = mpOptions.onAddToFavorites;
608
- pageOptions.onAddToFavorites = function pageOnAddToFavorites(...args) {
609
- const ret = callHookReturn(this, "onAddToFavorites", args);
610
- if (ret !== void 0) return ret;
611
- if (typeof userOnAddToFavorites === "function") return userOnAddToFavorites.apply(this, args);
612
- };
613
- }
614
- for (const methodName of methodNames) {
615
- const userMethod = mpOptions[methodName];
616
- pageOptions[methodName] = function runtimeMethod(...args) {
617
- const runtime = this.__wevu;
618
- let result;
619
- const bound = runtime?.methods?.[methodName];
620
- if (bound) result = bound.apply(runtime.proxy, args);
621
- if (typeof userMethod === "function") return userMethod.apply(this, args);
622
- return result;
623
- };
624
- }
625
- Page(pageOptions);
626
- }
627
- function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
628
- const { methods: userMethods = {}, lifetimes: userLifetimes = {}, pageLifetimes: userPageLifetimes = {}, ...rest } = mpOptions;
629
781
  const finalMethods = { ...userMethods };
782
+ if (!finalMethods.__weapp_vite_inline) finalMethods.__weapp_vite_inline = function __weapp_vite_inline(event) {
783
+ const expr = event?.currentTarget?.dataset?.wvHandler ?? event?.target?.dataset?.wvHandler;
784
+ return runInlineExpression(this.__wevu?.proxy ?? this, expr, event);
785
+ };
630
786
  const methodNames = Object.keys(methods ?? {});
631
787
  for (const methodName of methodNames) {
632
788
  const userMethod = finalMethods[methodName];
@@ -648,8 +804,58 @@ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
648
804
  };
649
805
  wrapSpecial("onTabItemTap");
650
806
  wrapSpecial("onRouteDone");
807
+ const pageLifecycleHooks = {
808
+ onLoad(...args) {
809
+ mountRuntimeInstance(this, runtimeApp, watch$1, setup);
810
+ if (typeof userOnLoad === "function") return userOnLoad.apply(this, args);
811
+ },
812
+ onUnload(...args) {
813
+ teardownRuntimeInstance(this);
814
+ if (typeof userOnUnload === "function") return userOnUnload.apply(this, args);
815
+ },
816
+ onShow(...args) {
817
+ callHookList(this, "onShow", args);
818
+ if (typeof userOnShow === "function") return userOnShow.apply(this, args);
819
+ },
820
+ onHide(...args) {
821
+ callHookList(this, "onHide", args);
822
+ if (typeof userOnHide === "function") return userOnHide.apply(this, args);
823
+ },
824
+ onReady(...args) {
825
+ if (!this.__wevuReadyCalled) {
826
+ this.__wevuReadyCalled = true;
827
+ callHookList(this, "onReady", args);
828
+ }
829
+ if (typeof userOnReady === "function") return userOnReady.apply(this, args);
830
+ },
831
+ onSaveExitState(...args) {
832
+ const ret = callHookReturn(this, "onSaveExitState", args);
833
+ if (ret !== void 0) return ret;
834
+ if (typeof userOnSaveExitState === "function") return userOnSaveExitState.apply(this, args);
835
+ }
836
+ };
837
+ if (features?.listenPageScroll) pageLifecycleHooks.onPageScroll = function onPageScroll$1(...args) {
838
+ callHookList(this, "onPageScroll", args);
839
+ if (typeof userOnPageScroll === "function") return userOnPageScroll.apply(this, args);
840
+ };
841
+ if (features?.enableShareAppMessage) pageLifecycleHooks.onShareAppMessage = function onShareAppMessage$1(...args) {
842
+ const ret = callHookReturn(this, "onShareAppMessage", args);
843
+ if (ret !== void 0) return ret;
844
+ if (typeof userOnShareAppMessage === "function") return userOnShareAppMessage.apply(this, args);
845
+ };
846
+ if (features?.enableShareTimeline) pageLifecycleHooks.onShareTimeline = function onShareTimeline$1(...args) {
847
+ const ret = callHookReturn(this, "onShareTimeline", args);
848
+ if (ret !== void 0) return ret;
849
+ if (typeof userOnShareTimeline === "function") return userOnShareTimeline.apply(this, args);
850
+ };
851
+ if (features?.enableAddToFavorites) pageLifecycleHooks.onAddToFavorites = function onAddToFavorites$1(...args) {
852
+ const ret = callHookReturn(this, "onAddToFavorites", args);
853
+ if (ret !== void 0) return ret;
854
+ if (typeof userOnAddToFavorites === "function") return userOnAddToFavorites.apply(this, args);
855
+ };
651
856
  Component({
652
- ...rest,
857
+ ...restOptions,
858
+ ...pageLifecycleHooks,
653
859
  lifetimes: {
654
860
  ...userLifetimes,
655
861
  attached: function attached(...args) {
@@ -657,7 +863,10 @@ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
657
863
  if (typeof userLifetimes.attached === "function") userLifetimes.attached.apply(this, args);
658
864
  },
659
865
  ready: function ready(...args) {
660
- callHookList(this, "onReady", args);
866
+ if (!this.__wevuReadyCalled) {
867
+ this.__wevuReadyCalled = true;
868
+ callHookList(this, "onReady", args);
869
+ }
661
870
  if (typeof userLifetimes.ready === "function") userLifetimes.ready.apply(this, args);
662
871
  },
663
872
  detached: function detached(...args) {
@@ -676,7 +885,8 @@ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
676
885
  if (typeof userPageLifetimes.hide === "function") userPageLifetimes.hide.apply(this, args);
677
886
  }
678
887
  },
679
- methods: finalMethods
888
+ methods: finalMethods,
889
+ options: finalOptions
680
890
  });
681
891
  }
682
892
 
@@ -690,7 +900,7 @@ function createApp(options) {
690
900
  const appConfig = { globalProperties: {} };
691
901
  const runtimeApp = {
692
902
  mount(adapter) {
693
- const state = require_ref.reactive((data ?? (() => ({})))());
903
+ const state = require_store.reactive((data ?? (() => ({})))());
694
904
  const computedDefs = resolvedComputed;
695
905
  const methodDefs = resolvedMethods;
696
906
  const computedRefs = Object.create(null);
@@ -775,18 +985,18 @@ function createApp(options) {
775
985
  });
776
986
  Object.keys(computedDefs).forEach((key) => {
777
987
  const definition = computedDefs[key];
778
- if (typeof definition === "function") computedRefs[key] = require_ref.computed(() => definition.call(publicInstance));
988
+ if (typeof definition === "function") computedRefs[key] = require_store.computed(() => definition.call(publicInstance));
779
989
  else {
780
990
  const getter = definition.get?.bind(publicInstance);
781
991
  if (!getter) throw new Error(`Computed property "${key}" requires a getter`);
782
992
  const setter = definition.set?.bind(publicInstance);
783
993
  if (setter) {
784
994
  computedSetters[key] = setter;
785
- computedRefs[key] = require_ref.computed({
995
+ computedRefs[key] = require_store.computed({
786
996
  get: getter,
787
997
  set: setter
788
998
  });
789
- } else computedRefs[key] = require_ref.computed(getter);
999
+ } else computedRefs[key] = require_store.computed(getter);
790
1000
  }
791
1001
  });
792
1002
  const currentAdapter = adapter ?? { setData: () => {} };
@@ -808,12 +1018,12 @@ function createApp(options) {
808
1018
  if (result && typeof result.then === "function") result.catch(() => {});
809
1019
  }
810
1020
  };
811
- const tracker = require_ref.effect(() => {
812
- require_ref.touchReactive(state);
1021
+ const tracker = require_store.effect(() => {
1022
+ require_store.touchReactive(state);
813
1023
  Object.keys(computedRefs).forEach((key) => computedRefs[key].value);
814
- }, { scheduler: () => require_ref.queueJob(job) });
1024
+ }, { scheduler: () => require_store.queueJob(job) });
815
1025
  job();
816
- stopHandles.push(() => require_ref.stop(tracker));
1026
+ stopHandles.push(() => require_store.stop(tracker));
817
1027
  function registerWatch(source, cb, watchOptions) {
818
1028
  const stopHandle = watch(source, (value, oldValue) => cb(value, oldValue), watchOptions);
819
1029
  stopHandles.push(stopHandle);
@@ -877,98 +1087,259 @@ function setComputedValue(setters, key, value) {
877
1087
 
878
1088
  //#endregion
879
1089
  //#region src/runtime/define.ts
1090
+ /**
1091
+ * 按 Vue 3 风格定义一个小程序组件/页面。
1092
+ *
1093
+ * - 统一注册为 `Component()`
1094
+ *
1095
+ * @param options 组件定义项
1096
+ * @returns 可手动注册的组件定义
1097
+ *
1098
+ * @example
1099
+ * ```ts
1100
+ * defineComponent({
1101
+ * data: () => ({ count: 0 }),
1102
+ * setup() {
1103
+ * onMounted(() => console.log('mounted'))
1104
+ * }
1105
+ * })
1106
+ * ```
1107
+ *
1108
+ * @example
1109
+ * ```ts
1110
+ * defineComponent({
1111
+ * features: { listenPageScroll: true },
1112
+ * setup() {
1113
+ * onPageScroll(() => {})
1114
+ * }
1115
+ * })
1116
+ * ```
1117
+ */
880
1118
  function defineComponent(options) {
881
- const { type = "component", data, computed: computed$1, methods, watch: watch$1, setup, ...mpOptions } = options;
1119
+ const { features, data, computed: computed$1, methods, watch: watch$1, setup, props, ...mpOptions } = options;
882
1120
  const runtimeApp = createApp({
883
1121
  data,
884
1122
  computed: computed$1,
885
1123
  methods
886
1124
  });
887
1125
  const setupWrapper = (ctx) => {
888
- const result = setup?.(ctx);
1126
+ const result = runSetupFunction(setup, ctx?.props ?? {}, ctx);
889
1127
  if (result) applySetupResult(ctx.runtime, ctx.instance, result);
890
1128
  };
891
- if (type === "component") registerComponent(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptions);
892
- else registerPage(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptions, void 0);
893
- return { mount: (_features) => {} };
894
- }
895
- function definePage(options, features) {
896
- const { data, computed: computed$1, methods, watch: watch$1, setup, ...mpOptions } = options;
897
- const runtimeApp = createApp({
1129
+ const mpOptionsWithProps = normalizeProps(mpOptions, props);
1130
+ const componentOptions = {
898
1131
  data,
899
1132
  computed: computed$1,
900
- methods
901
- });
902
- const setupWrapper = (ctx) => {
903
- const result = setup?.(ctx);
904
- if (result) applySetupResult(ctx.runtime, ctx.instance, result);
1133
+ methods,
1134
+ watch: watch$1,
1135
+ setup: setupWrapper,
1136
+ mpOptions: mpOptionsWithProps,
1137
+ features
1138
+ };
1139
+ registerComponent(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptionsWithProps, features);
1140
+ return {
1141
+ __wevu_runtime: runtimeApp,
1142
+ __wevu_options: componentOptions
905
1143
  };
906
- registerPage(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptions, features);
907
- return { mount: () => {} };
908
1144
  }
909
1145
  function applySetupResult(runtime, _target, result) {
1146
+ const methods = runtime?.methods ?? Object.create(null);
1147
+ const state = runtime?.state ?? Object.create(null);
1148
+ if (runtime && !runtime.methods) try {
1149
+ runtime.methods = methods;
1150
+ } catch {}
1151
+ if (runtime && !runtime.state) try {
1152
+ runtime.state = state;
1153
+ } catch {}
910
1154
  Object.keys(result).forEach((key) => {
911
1155
  const val = result[key];
912
- if (typeof val === "function") runtime.methods[key] = (...args) => val.apply(runtime.proxy, args);
913
- else runtime.state[key] = val;
1156
+ if (typeof val === "function") methods[key] = (...args) => val.apply(runtime?.proxy ?? runtime, args);
1157
+ else state[key] = val;
1158
+ });
1159
+ if (runtime) {
1160
+ runtime.methods = runtime.methods ?? methods;
1161
+ runtime.state = runtime.state ?? state;
1162
+ }
1163
+ }
1164
+ /**
1165
+ * 从 Vue SFC 选项创建 wevu 组件,供 weapp-vite 编译产物直接调用的兼容入口。
1166
+ *
1167
+ * @param options 组件选项,可能包含小程序特有的 properties
1168
+ */
1169
+ function createWevuComponent(options) {
1170
+ const { properties, props, ...restOptions } = options;
1171
+ defineComponent(normalizeProps(restOptions, props, properties));
1172
+ }
1173
+ function normalizeProps(baseOptions, props, explicitProperties) {
1174
+ if (explicitProperties || !props) return {
1175
+ ...baseOptions,
1176
+ ...explicitProperties ? { properties: explicitProperties } : {}
1177
+ };
1178
+ const properties = {};
1179
+ Object.entries(props).forEach(([key, definition]) => {
1180
+ if (definition === null || definition === void 0) return;
1181
+ if (Array.isArray(definition) || typeof definition === "function") {
1182
+ properties[key] = { type: definition };
1183
+ return;
1184
+ }
1185
+ if (typeof definition === "object") {
1186
+ const propOptions = {};
1187
+ if ("type" in definition && definition.type !== void 0) propOptions.type = definition.type;
1188
+ const defaultValue = "default" in definition ? definition.default : definition.value;
1189
+ if (defaultValue !== void 0) propOptions.value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
1190
+ properties[key] = propOptions;
1191
+ }
914
1192
  });
1193
+ return {
1194
+ ...baseOptions,
1195
+ properties
1196
+ };
915
1197
  }
916
1198
 
917
1199
  //#endregion
918
1200
  //#region src/runtime/provide.ts
919
- const __wevuProvideStore = /* @__PURE__ */ new Map();
1201
+ const PROVIDE_SCOPE_KEY = Symbol("wevu.provideScope");
1202
+ const __wevuGlobalProvideStore = /* @__PURE__ */ new Map();
1203
+ /**
1204
+ * 在组件上下文中向后代注入值(与 Vue 3 行为兼容),若没有当前实例则回落到全局存储。
1205
+ *
1206
+ * @param key 注入键,可为字符串、Symbol 或对象
1207
+ * @param value 提供的值
1208
+ *
1209
+ * @example
1210
+ * ```ts
1211
+ * defineComponent({
1212
+ * setup() {
1213
+ * provide(TOKEN_KEY, { data: 'value' })
1214
+ * }
1215
+ * })
1216
+ * ```
1217
+ */
920
1218
  function provide(key, value) {
921
- __wevuProvideStore.set(key, value);
1219
+ const instance = getCurrentInstance();
1220
+ if (instance) {
1221
+ let scope = instance[PROVIDE_SCOPE_KEY];
1222
+ if (!scope) {
1223
+ scope = /* @__PURE__ */ new Map();
1224
+ instance[PROVIDE_SCOPE_KEY] = scope;
1225
+ }
1226
+ scope.set(key, value);
1227
+ } else __wevuGlobalProvideStore.set(key, value);
922
1228
  }
1229
+ /**
1230
+ * 从祖先组件(或全局存储)读取提供的值。
1231
+ *
1232
+ * @param key 注入键,需与 provide 使用的键保持一致
1233
+ * @param defaultValue 未找到提供者时的默认值
1234
+ * @returns 匹配到的值或默认值
1235
+ *
1236
+ * @example
1237
+ * ```ts
1238
+ * defineComponent({
1239
+ * setup() {
1240
+ * const data = inject(TOKEN_KEY)
1241
+ * const value = inject('key', 'default')
1242
+ * }
1243
+ * })
1244
+ * ```
1245
+ */
923
1246
  function inject(key, defaultValue) {
924
- if (__wevuProvideStore.has(key)) return __wevuProvideStore.get(key);
1247
+ const instance = getCurrentInstance();
1248
+ if (instance) {
1249
+ let current = instance;
1250
+ while (current) {
1251
+ const scope = current[PROVIDE_SCOPE_KEY];
1252
+ if (scope && scope.has(key)) return scope.get(key);
1253
+ current = null;
1254
+ }
1255
+ }
1256
+ if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
925
1257
  if (arguments.length >= 2) return defaultValue;
926
1258
  throw new Error(`wevu.inject: no value found for key`);
927
1259
  }
1260
+ /**
1261
+ * 全局注入值,适用于组件外部调用场景。
1262
+ */
1263
+ function provideGlobal(key, value) {
1264
+ __wevuGlobalProvideStore.set(key, value);
1265
+ }
1266
+ /**
1267
+ * 从全局存储读取值,适用于组件外部调用场景。
1268
+ */
1269
+ function injectGlobal(key, defaultValue) {
1270
+ if (__wevuGlobalProvideStore.has(key)) return __wevuGlobalProvideStore.get(key);
1271
+ if (arguments.length >= 2) return defaultValue;
1272
+ throw new Error(`injectGlobal() no matching provider for key: ${String(key)}`);
1273
+ }
928
1274
 
929
1275
  //#endregion
930
1276
  exports.callHookList = callHookList;
931
1277
  exports.callHookReturn = callHookReturn;
932
- exports.computed = require_ref.computed;
1278
+ exports.callUpdateHooks = callUpdateHooks;
1279
+ exports.computed = require_store.computed;
933
1280
  exports.createApp = createApp;
1281
+ exports.createStore = require_store.createStore;
1282
+ exports.createWevuComponent = createWevuComponent;
934
1283
  exports.defineComponent = defineComponent;
935
- exports.definePage = definePage;
936
- exports.effect = require_ref.effect;
1284
+ exports.defineStore = require_store.defineStore;
1285
+ exports.effect = require_store.effect;
937
1286
  exports.getCurrentInstance = getCurrentInstance;
938
1287
  exports.getDeepWatchStrategy = getDeepWatchStrategy;
939
1288
  exports.inject = inject;
940
- exports.isReactive = require_ref.isReactive;
941
- exports.isRef = require_ref.isRef;
1289
+ exports.injectGlobal = injectGlobal;
1290
+ exports.isRaw = require_store.isRaw;
1291
+ exports.isReactive = require_store.isReactive;
1292
+ exports.isRef = require_store.isRef;
1293
+ exports.isShallowReactive = require_store.isShallowReactive;
1294
+ exports.isShallowRef = isShallowRef;
1295
+ exports.markRaw = require_store.markRaw;
942
1296
  exports.mountRuntimeInstance = mountRuntimeInstance;
943
- exports.nextTick = require_ref.nextTick;
1297
+ exports.nextTick = require_store.nextTick;
1298
+ exports.onActivated = onActivated;
944
1299
  exports.onAddToFavorites = onAddToFavorites;
945
1300
  exports.onAppError = onAppError;
946
1301
  exports.onAppHide = onAppHide;
947
1302
  exports.onAppShow = onAppShow;
1303
+ exports.onBeforeMount = onBeforeMount;
1304
+ exports.onBeforeUnmount = onBeforeUnmount;
1305
+ exports.onBeforeUpdate = onBeforeUpdate;
1306
+ exports.onDeactivated = onDeactivated;
1307
+ exports.onErrorCaptured = onErrorCaptured;
948
1308
  exports.onHide = onHide;
1309
+ exports.onMounted = onMounted;
949
1310
  exports.onPageScroll = onPageScroll;
950
1311
  exports.onReady = onReady;
951
1312
  exports.onRouteDone = onRouteDone;
952
1313
  exports.onSaveExitState = onSaveExitState;
1314
+ exports.onServerPrefetch = onServerPrefetch;
953
1315
  exports.onShareAppMessage = onShareAppMessage;
954
1316
  exports.onShareTimeline = onShareTimeline;
955
1317
  exports.onShow = onShow;
956
1318
  exports.onTabItemTap = onTabItemTap;
957
1319
  exports.onUnload = onUnload;
1320
+ exports.onUnmounted = onUnmounted;
1321
+ exports.onUpdated = onUpdated;
958
1322
  exports.provide = provide;
959
- exports.reactive = require_ref.reactive;
1323
+ exports.provideGlobal = provideGlobal;
1324
+ exports.reactive = require_store.reactive;
960
1325
  exports.readonly = readonly;
961
- exports.ref = require_ref.ref;
1326
+ exports.ref = require_store.ref;
962
1327
  exports.registerApp = registerApp;
963
1328
  exports.registerComponent = registerComponent;
964
- exports.registerPage = registerPage;
1329
+ exports.runSetupFunction = runSetupFunction;
965
1330
  exports.setCurrentInstance = setCurrentInstance;
966
1331
  exports.setDeepWatchStrategy = setDeepWatchStrategy;
967
- exports.stop = require_ref.stop;
1332
+ exports.shallowReactive = require_store.shallowReactive;
1333
+ exports.shallowRef = shallowRef;
1334
+ exports.stop = require_store.stop;
1335
+ exports.storeToRefs = require_store.storeToRefs;
968
1336
  exports.teardownRuntimeInstance = teardownRuntimeInstance;
969
- exports.toRaw = require_ref.toRaw;
970
- exports.touchReactive = require_ref.touchReactive;
1337
+ exports.toRaw = require_store.toRaw;
1338
+ exports.toRef = toRef;
1339
+ exports.toRefs = toRefs;
1340
+ exports.touchReactive = require_store.touchReactive;
971
1341
  exports.traverse = traverse;
972
- exports.unref = require_ref.unref;
1342
+ exports.triggerRef = triggerRef;
1343
+ exports.unref = require_store.unref;
973
1344
  exports.watch = watch;
974
1345
  exports.watchEffect = watchEffect;