wevu 1.0.0-alpha.1 → 1.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,6 +102,7 @@ counter.inc()
102
102
 
103
103
  - 更新被批量加入微任务队列,`nextTick` 与 Vue 3 行为一致。
104
104
  - 对状态做快照 diff,只把变更路径传给 `setData`,避免大对象全量下发。
105
+ - 提供 `batch`/`startBatch`/`endBatch` 用于同步更新合并触发;以及 `effectScope`/`onScopeDispose` 统一管理 effect/watch 的销毁,便于避免泄漏。
105
106
 
106
107
  ## 本地开发
107
108
 
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_store = require('./store-Cmw9vWBT.cjs');
1
+ const require_store = require('./store-D0GD8ulz.cjs');
2
2
 
3
3
  //#region src/reactivity/readonly.ts
4
4
  function readonly(target) {
@@ -155,10 +155,13 @@ function watch(source, cb, options = {}) {
155
155
  });
156
156
  if (options.immediate) job();
157
157
  else oldValue = runner();
158
- return () => {
158
+ const stopHandle = () => {
159
159
  cleanup?.();
160
+ cleanup = void 0;
160
161
  require_store.stop(runner);
161
162
  };
163
+ require_store.onScopeDispose(stopHandle);
164
+ return stopHandle;
162
165
  }
163
166
  /**
164
167
  * watchEffect 注册一个响应式副作用,可选清理函数。
@@ -173,14 +176,20 @@ function watchEffect(effectFn) {
173
176
  cleanup?.();
174
177
  cleanup = void 0;
175
178
  effectFn(onCleanup);
176
- }, { scheduler: () => require_store.queueJob(() => {
177
- if (runner.active) runner();
178
- }) });
179
+ }, {
180
+ lazy: true,
181
+ scheduler: () => require_store.queueJob(() => {
182
+ if (runner.active) runner();
183
+ })
184
+ });
179
185
  runner();
180
- return () => {
186
+ const stopHandle = () => {
181
187
  cleanup?.();
188
+ cleanup = void 0;
182
189
  require_store.stop(runner);
183
190
  };
191
+ require_store.onScopeDispose(stopHandle);
192
+ return stopHandle;
184
193
  }
185
194
 
186
195
  //#endregion
@@ -283,7 +292,7 @@ function createBindModel(publicInstance, state, computedRefs, computedSetters) {
283
292
 
284
293
  //#endregion
285
294
  //#region src/runtime/diff.ts
286
- function isPlainObject(value) {
295
+ function isPlainObject$1(value) {
287
296
  if (Object.prototype.toString.call(value) !== "[object Object]") return false;
288
297
  const proto = Object.getPrototypeOf(value);
289
298
  return proto === null || proto === Object.prototype;
@@ -311,7 +320,7 @@ function toPlain(value, seen = /* @__PURE__ */ new WeakMap()) {
311
320
  function isDeepEqual(a, b) {
312
321
  if (Object.is(a, b)) return true;
313
322
  if (Array.isArray(a) && Array.isArray(b)) return isArrayEqual(a, b);
314
- if (isPlainObject(a) && isPlainObject(b)) return isPlainObjectEqual(a, b);
323
+ if (isPlainObject$1(a) && isPlainObject$1(b)) return isPlainObjectEqual(a, b);
315
324
  return false;
316
325
  }
317
326
  function isArrayEqual(a, b) {
@@ -334,7 +343,7 @@ function normalizeSetDataValue(value) {
334
343
  }
335
344
  function assignNestedDiff(prev, next, path, output) {
336
345
  if (isDeepEqual(prev, next)) return;
337
- if (isPlainObject(prev) && isPlainObject(next)) {
346
+ if (isPlainObject$1(prev) && isPlainObject$1(next)) {
338
347
  new Set([...Object.keys(prev), ...Object.keys(next)]).forEach((key) => {
339
348
  if (!Object.prototype.hasOwnProperty.call(next, key)) {
340
349
  output[`${path}.${key}`] = null;
@@ -1009,6 +1018,7 @@ function createApp(options) {
1009
1018
  };
1010
1019
  const job = () => {
1011
1020
  if (!mounted) return;
1021
+ tracker();
1012
1022
  const snapshot = collectSnapshot();
1013
1023
  const diff = diffSnapshots(latestSnapshot, snapshot);
1014
1024
  latestSnapshot = snapshot;
@@ -1018,10 +1028,18 @@ function createApp(options) {
1018
1028
  if (result && typeof result.then === "function") result.catch(() => {});
1019
1029
  }
1020
1030
  };
1021
- const tracker = require_store.effect(() => {
1031
+ let tracker;
1032
+ tracker = require_store.effect(() => {
1022
1033
  require_store.touchReactive(state);
1034
+ Object.keys(state).forEach((key) => {
1035
+ const v = state[key];
1036
+ if (require_store.isRef(v)) v.value;
1037
+ });
1023
1038
  Object.keys(computedRefs).forEach((key) => computedRefs[key].value);
1024
- }, { scheduler: () => require_store.queueJob(job) });
1039
+ }, {
1040
+ lazy: true,
1041
+ scheduler: () => require_store.queueJob(job)
1042
+ });
1025
1043
  job();
1026
1044
  stopHandles.push(() => require_store.stop(tracker));
1027
1045
  function registerWatch(source, cb, watchOptions) {
@@ -1145,6 +1163,7 @@ function defineComponent(options) {
1145
1163
  function applySetupResult(runtime, _target, result) {
1146
1164
  const methods = runtime?.methods ?? Object.create(null);
1147
1165
  const state = runtime?.state ?? Object.create(null);
1166
+ const rawState = require_store.isReactive(state) ? require_store.toRaw(state) : state;
1148
1167
  if (runtime && !runtime.methods) try {
1149
1168
  runtime.methods = methods;
1150
1169
  } catch {}
@@ -1154,6 +1173,16 @@ function applySetupResult(runtime, _target, result) {
1154
1173
  Object.keys(result).forEach((key) => {
1155
1174
  const val = result[key];
1156
1175
  if (typeof val === "function") methods[key] = (...args) => val.apply(runtime?.proxy ?? runtime, args);
1176
+ else if (val === _target || !shouldExposeInSnapshot(val)) try {
1177
+ Object.defineProperty(rawState, key, {
1178
+ value: val,
1179
+ configurable: true,
1180
+ enumerable: false,
1181
+ writable: true
1182
+ });
1183
+ } catch {
1184
+ state[key] = val;
1185
+ }
1157
1186
  else state[key] = val;
1158
1187
  });
1159
1188
  if (runtime) {
@@ -1161,6 +1190,18 @@ function applySetupResult(runtime, _target, result) {
1161
1190
  runtime.state = runtime.state ?? state;
1162
1191
  }
1163
1192
  }
1193
+ function isPlainObject(value) {
1194
+ if (Object.prototype.toString.call(value) !== "[object Object]") return false;
1195
+ const proto = Object.getPrototypeOf(value);
1196
+ return proto === null || proto === Object.prototype;
1197
+ }
1198
+ function shouldExposeInSnapshot(value) {
1199
+ if (value == null) return true;
1200
+ if (typeof value !== "object") return true;
1201
+ if (require_store.isRef(value) || require_store.isReactive(value)) return true;
1202
+ if (Array.isArray(value)) return true;
1203
+ return isPlainObject(value);
1204
+ }
1164
1205
  /**
1165
1206
  * 从 Vue SFC 选项创建 wevu 组件,供 weapp-vite 编译产物直接调用的兼容入口。
1166
1207
  *
@@ -1273,6 +1314,7 @@ function injectGlobal(key, defaultValue) {
1273
1314
  }
1274
1315
 
1275
1316
  //#endregion
1317
+ exports.batch = require_store.batch;
1276
1318
  exports.callHookList = callHookList;
1277
1319
  exports.callHookReturn = callHookReturn;
1278
1320
  exports.callUpdateHooks = callUpdateHooks;
@@ -1283,7 +1325,10 @@ exports.createWevuComponent = createWevuComponent;
1283
1325
  exports.defineComponent = defineComponent;
1284
1326
  exports.defineStore = require_store.defineStore;
1285
1327
  exports.effect = require_store.effect;
1328
+ exports.effectScope = require_store.effectScope;
1329
+ exports.endBatch = require_store.endBatch;
1286
1330
  exports.getCurrentInstance = getCurrentInstance;
1331
+ exports.getCurrentScope = require_store.getCurrentScope;
1287
1332
  exports.getDeepWatchStrategy = getDeepWatchStrategy;
1288
1333
  exports.inject = inject;
1289
1334
  exports.injectGlobal = injectGlobal;
@@ -1311,6 +1356,7 @@ exports.onPageScroll = onPageScroll;
1311
1356
  exports.onReady = onReady;
1312
1357
  exports.onRouteDone = onRouteDone;
1313
1358
  exports.onSaveExitState = onSaveExitState;
1359
+ exports.onScopeDispose = require_store.onScopeDispose;
1314
1360
  exports.onServerPrefetch = onServerPrefetch;
1315
1361
  exports.onShareAppMessage = onShareAppMessage;
1316
1362
  exports.onShareTimeline = onShareTimeline;
@@ -1331,6 +1377,7 @@ exports.setCurrentInstance = setCurrentInstance;
1331
1377
  exports.setDeepWatchStrategy = setDeepWatchStrategy;
1332
1378
  exports.shallowReactive = require_store.shallowReactive;
1333
1379
  exports.shallowRef = shallowRef;
1380
+ exports.startBatch = require_store.startBatch;
1334
1381
  exports.stop = require_store.stop;
1335
1382
  exports.storeToRefs = require_store.storeToRefs;
1336
1383
  exports.teardownRuntimeInstance = teardownRuntimeInstance;
package/dist/index.d.cts CHANGED
@@ -30,9 +30,23 @@ interface ReactiveEffect<T$1 = any> {
30
30
  deps: Dep[];
31
31
  scheduler?: EffectScheduler;
32
32
  active: boolean;
33
+ _running: boolean;
33
34
  _fn: () => T$1;
34
35
  onStop?: () => void;
35
36
  }
37
+ declare function startBatch(): void;
38
+ declare function endBatch(): void;
39
+ declare function batch<T$1>(fn: () => T$1): T$1;
40
+ interface EffectScope {
41
+ active: boolean;
42
+ effects: ReactiveEffect[];
43
+ cleanups: (() => void)[];
44
+ run: <T$1>(fn: () => T$1) => T$1 | undefined;
45
+ stop: () => void;
46
+ }
47
+ declare function effectScope(detached?: boolean): EffectScope;
48
+ declare function getCurrentScope(): EffectScope | undefined;
49
+ declare function onScopeDispose(fn: () => void): void;
36
50
  interface EffectOptions {
37
51
  scheduler?: EffectScheduler;
38
52
  lazy?: boolean;
@@ -551,4 +565,4 @@ declare function teardownRuntimeInstance(target: InternalRuntimeState): void;
551
565
  declare function registerApp<D extends object, C extends ComputedDefinitions, M extends MethodDefinitions>(runtimeApp: RuntimeApp<D, C, M>, methods: MethodDefinitions, watch: WatchMap | undefined, setup: DefineAppOptions<D, C, M>['setup'], mpOptions: Record<string, any>): void;
552
566
  declare function registerComponent<D extends object, C extends ComputedDefinitions, M extends MethodDefinitions>(runtimeApp: RuntimeApp<D, C, M>, methods: MethodDefinitions, watch: WatchMap | undefined, setup: DefineComponentOptions<ComponentPropsOptions, D, C, M>['setup'], mpOptions: Record<string, any>, features?: PageFeatures): void;
553
567
  //#endregion
554
- export { ActionSubscriber, AppConfig, ComponentDefinition, ComponentPropsOptions, ComponentPublicInstance, ComputedDefinitions, ComputedGetter, ComputedRef, ComputedSetter, CreateAppOptions, DefineAppOptions, DefineComponentOptions, DefineStoreOptions, ExtractComputed, ExtractMethods, InferPropType, InferProps, InternalRuntimeState, MethodDefinitions, MiniProgramAdapter, ModelBinding, ModelBindingOptions, MutationType, PageFeatures, PropConstructor, PropOptions, PropType, Ref, RuntimeApp, RuntimeInstance, SetupContext, SetupFunction, StoreManager, SubscriptionCallback, ToRefs, WatchOptions, WatchStopHandle, WevuPlugin, WritableComputedOptions, WritableComputedRef, callHookList, callHookReturn, callUpdateHooks, computed, createApp, createStore, createWevuComponent, defineComponent, defineStore, effect, getCurrentInstance, getDeepWatchStrategy, inject, injectGlobal, isRaw, isReactive, isRef, isShallowReactive, isShallowRef, markRaw, mountRuntimeInstance, nextTick, onActivated, onAddToFavorites, onAppError, onAppHide, onAppShow, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onHide, onMounted, onPageScroll, onReady, onRouteDone, onSaveExitState, onServerPrefetch, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onUnload, onUnmounted, onUpdated, provide, provideGlobal, reactive, readonly, ref, registerApp, registerComponent, runSetupFunction, setCurrentInstance, setDeepWatchStrategy, shallowReactive, shallowRef, stop, storeToRefs, teardownRuntimeInstance, toRaw, toRef, toRefs, touchReactive, traverse, triggerRef, unref, watch, watchEffect };
568
+ export { ActionSubscriber, AppConfig, ComponentDefinition, ComponentPropsOptions, ComponentPublicInstance, ComputedDefinitions, ComputedGetter, ComputedRef, ComputedSetter, CreateAppOptions, DefineAppOptions, DefineComponentOptions, DefineStoreOptions, EffectScope, ExtractComputed, ExtractMethods, InferPropType, InferProps, InternalRuntimeState, MethodDefinitions, MiniProgramAdapter, ModelBinding, ModelBindingOptions, MutationType, PageFeatures, PropConstructor, PropOptions, PropType, Ref, RuntimeApp, RuntimeInstance, SetupContext, SetupFunction, StoreManager, SubscriptionCallback, ToRefs, WatchOptions, WatchStopHandle, WevuPlugin, WritableComputedOptions, WritableComputedRef, batch, callHookList, callHookReturn, callUpdateHooks, computed, createApp, createStore, createWevuComponent, defineComponent, defineStore, effect, effectScope, endBatch, getCurrentInstance, getCurrentScope, getDeepWatchStrategy, inject, injectGlobal, isRaw, isReactive, isRef, isShallowReactive, isShallowRef, markRaw, mountRuntimeInstance, nextTick, onActivated, onAddToFavorites, onAppError, onAppHide, onAppShow, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onHide, onMounted, onPageScroll, onReady, onRouteDone, onSaveExitState, onScopeDispose, onServerPrefetch, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onUnload, onUnmounted, onUpdated, provide, provideGlobal, reactive, readonly, ref, registerApp, registerComponent, runSetupFunction, setCurrentInstance, setDeepWatchStrategy, shallowReactive, shallowRef, startBatch, stop, storeToRefs, teardownRuntimeInstance, toRaw, toRef, toRefs, touchReactive, traverse, triggerRef, unref, watch, watchEffect };
package/dist/index.d.mts CHANGED
@@ -30,9 +30,23 @@ interface ReactiveEffect<T$1 = any> {
30
30
  deps: Dep[];
31
31
  scheduler?: EffectScheduler;
32
32
  active: boolean;
33
+ _running: boolean;
33
34
  _fn: () => T$1;
34
35
  onStop?: () => void;
35
36
  }
37
+ declare function startBatch(): void;
38
+ declare function endBatch(): void;
39
+ declare function batch<T$1>(fn: () => T$1): T$1;
40
+ interface EffectScope {
41
+ active: boolean;
42
+ effects: ReactiveEffect[];
43
+ cleanups: (() => void)[];
44
+ run: <T$1>(fn: () => T$1) => T$1 | undefined;
45
+ stop: () => void;
46
+ }
47
+ declare function effectScope(detached?: boolean): EffectScope;
48
+ declare function getCurrentScope(): EffectScope | undefined;
49
+ declare function onScopeDispose(fn: () => void): void;
36
50
  interface EffectOptions {
37
51
  scheduler?: EffectScheduler;
38
52
  lazy?: boolean;
@@ -551,4 +565,4 @@ declare function teardownRuntimeInstance(target: InternalRuntimeState): void;
551
565
  declare function registerApp<D extends object, C extends ComputedDefinitions, M extends MethodDefinitions>(runtimeApp: RuntimeApp<D, C, M>, methods: MethodDefinitions, watch: WatchMap | undefined, setup: DefineAppOptions<D, C, M>['setup'], mpOptions: Record<string, any>): void;
552
566
  declare function registerComponent<D extends object, C extends ComputedDefinitions, M extends MethodDefinitions>(runtimeApp: RuntimeApp<D, C, M>, methods: MethodDefinitions, watch: WatchMap | undefined, setup: DefineComponentOptions<ComponentPropsOptions, D, C, M>['setup'], mpOptions: Record<string, any>, features?: PageFeatures): void;
553
567
  //#endregion
554
- export { ActionSubscriber, AppConfig, ComponentDefinition, ComponentPropsOptions, ComponentPublicInstance, ComputedDefinitions, ComputedGetter, ComputedRef, ComputedSetter, CreateAppOptions, DefineAppOptions, DefineComponentOptions, DefineStoreOptions, ExtractComputed, ExtractMethods, InferPropType, InferProps, InternalRuntimeState, MethodDefinitions, MiniProgramAdapter, ModelBinding, ModelBindingOptions, MutationType, PageFeatures, PropConstructor, PropOptions, PropType, Ref, RuntimeApp, RuntimeInstance, SetupContext, SetupFunction, StoreManager, SubscriptionCallback, ToRefs, WatchOptions, WatchStopHandle, WevuPlugin, WritableComputedOptions, WritableComputedRef, callHookList, callHookReturn, callUpdateHooks, computed, createApp, createStore, createWevuComponent, defineComponent, defineStore, effect, getCurrentInstance, getDeepWatchStrategy, inject, injectGlobal, isRaw, isReactive, isRef, isShallowReactive, isShallowRef, markRaw, mountRuntimeInstance, nextTick, onActivated, onAddToFavorites, onAppError, onAppHide, onAppShow, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onHide, onMounted, onPageScroll, onReady, onRouteDone, onSaveExitState, onServerPrefetch, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onUnload, onUnmounted, onUpdated, provide, provideGlobal, reactive, readonly, ref, registerApp, registerComponent, runSetupFunction, setCurrentInstance, setDeepWatchStrategy, shallowReactive, shallowRef, stop, storeToRefs, teardownRuntimeInstance, toRaw, toRef, toRefs, touchReactive, traverse, triggerRef, unref, watch, watchEffect };
568
+ export { ActionSubscriber, AppConfig, ComponentDefinition, ComponentPropsOptions, ComponentPublicInstance, ComputedDefinitions, ComputedGetter, ComputedRef, ComputedSetter, CreateAppOptions, DefineAppOptions, DefineComponentOptions, DefineStoreOptions, EffectScope, ExtractComputed, ExtractMethods, InferPropType, InferProps, InternalRuntimeState, MethodDefinitions, MiniProgramAdapter, ModelBinding, ModelBindingOptions, MutationType, PageFeatures, PropConstructor, PropOptions, PropType, Ref, RuntimeApp, RuntimeInstance, SetupContext, SetupFunction, StoreManager, SubscriptionCallback, ToRefs, WatchOptions, WatchStopHandle, WevuPlugin, WritableComputedOptions, WritableComputedRef, batch, callHookList, callHookReturn, callUpdateHooks, computed, createApp, createStore, createWevuComponent, defineComponent, defineStore, effect, effectScope, endBatch, getCurrentInstance, getCurrentScope, getDeepWatchStrategy, inject, injectGlobal, isRaw, isReactive, isRef, isShallowReactive, isShallowRef, markRaw, mountRuntimeInstance, nextTick, onActivated, onAddToFavorites, onAppError, onAppHide, onAppShow, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onHide, onMounted, onPageScroll, onReady, onRouteDone, onSaveExitState, onScopeDispose, onServerPrefetch, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onUnload, onUnmounted, onUpdated, provide, provideGlobal, reactive, readonly, ref, registerApp, registerComponent, runSetupFunction, setCurrentInstance, setDeepWatchStrategy, shallowReactive, shallowRef, startBatch, stop, storeToRefs, teardownRuntimeInstance, toRaw, toRef, toRefs, touchReactive, traverse, triggerRef, unref, watch, watchEffect };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as computed, a as isRef, b as nextTick, c as isObject, d as isShallowReactive, f as markRaw, g as touchReactive, h as toRaw, i as customRef, l as isRaw, m as shallowReactive, n as defineStore, o as ref, p as reactive, r as createStore, s as unref, t as storeToRefs, u as isReactive, v as effect, x as queueJob, y as stop } from "./store-BcU7YVhB.mjs";
1
+ import { C as onScopeDispose, D as queueJob, E as nextTick, S as getCurrentScope, T as stop, _ as computed, a as isRef, b as effectScope, c as isObject, d as isShallowReactive, f as markRaw, g as touchReactive, h as toRaw, i as customRef, l as isRaw, m as shallowReactive, n as defineStore, o as ref, p as reactive, r as createStore, s as unref, t as storeToRefs, u as isReactive, v as batch, w as startBatch, x as endBatch, y as effect } from "./store-2q4qcdBi.mjs";
2
2
 
3
3
  //#region src/reactivity/readonly.ts
4
4
  function readonly(target) {
@@ -155,10 +155,13 @@ function watch(source, cb, options = {}) {
155
155
  });
156
156
  if (options.immediate) job();
157
157
  else oldValue = runner();
158
- return () => {
158
+ const stopHandle = () => {
159
159
  cleanup?.();
160
+ cleanup = void 0;
160
161
  stop(runner);
161
162
  };
163
+ onScopeDispose(stopHandle);
164
+ return stopHandle;
162
165
  }
163
166
  /**
164
167
  * watchEffect 注册一个响应式副作用,可选清理函数。
@@ -173,14 +176,20 @@ function watchEffect(effectFn) {
173
176
  cleanup?.();
174
177
  cleanup = void 0;
175
178
  effectFn(onCleanup);
176
- }, { scheduler: () => queueJob(() => {
177
- if (runner.active) runner();
178
- }) });
179
+ }, {
180
+ lazy: true,
181
+ scheduler: () => queueJob(() => {
182
+ if (runner.active) runner();
183
+ })
184
+ });
179
185
  runner();
180
- return () => {
186
+ const stopHandle = () => {
181
187
  cleanup?.();
188
+ cleanup = void 0;
182
189
  stop(runner);
183
190
  };
191
+ onScopeDispose(stopHandle);
192
+ return stopHandle;
184
193
  }
185
194
 
186
195
  //#endregion
@@ -283,7 +292,7 @@ function createBindModel(publicInstance, state, computedRefs, computedSetters) {
283
292
 
284
293
  //#endregion
285
294
  //#region src/runtime/diff.ts
286
- function isPlainObject(value) {
295
+ function isPlainObject$1(value) {
287
296
  if (Object.prototype.toString.call(value) !== "[object Object]") return false;
288
297
  const proto = Object.getPrototypeOf(value);
289
298
  return proto === null || proto === Object.prototype;
@@ -311,7 +320,7 @@ function toPlain(value, seen = /* @__PURE__ */ new WeakMap()) {
311
320
  function isDeepEqual(a, b) {
312
321
  if (Object.is(a, b)) return true;
313
322
  if (Array.isArray(a) && Array.isArray(b)) return isArrayEqual(a, b);
314
- if (isPlainObject(a) && isPlainObject(b)) return isPlainObjectEqual(a, b);
323
+ if (isPlainObject$1(a) && isPlainObject$1(b)) return isPlainObjectEqual(a, b);
315
324
  return false;
316
325
  }
317
326
  function isArrayEqual(a, b) {
@@ -334,7 +343,7 @@ function normalizeSetDataValue(value) {
334
343
  }
335
344
  function assignNestedDiff(prev, next, path, output) {
336
345
  if (isDeepEqual(prev, next)) return;
337
- if (isPlainObject(prev) && isPlainObject(next)) {
346
+ if (isPlainObject$1(prev) && isPlainObject$1(next)) {
338
347
  new Set([...Object.keys(prev), ...Object.keys(next)]).forEach((key) => {
339
348
  if (!Object.prototype.hasOwnProperty.call(next, key)) {
340
349
  output[`${path}.${key}`] = null;
@@ -1009,6 +1018,7 @@ function createApp(options) {
1009
1018
  };
1010
1019
  const job = () => {
1011
1020
  if (!mounted) return;
1021
+ tracker();
1012
1022
  const snapshot = collectSnapshot();
1013
1023
  const diff = diffSnapshots(latestSnapshot, snapshot);
1014
1024
  latestSnapshot = snapshot;
@@ -1018,10 +1028,18 @@ function createApp(options) {
1018
1028
  if (result && typeof result.then === "function") result.catch(() => {});
1019
1029
  }
1020
1030
  };
1021
- const tracker = effect(() => {
1031
+ let tracker;
1032
+ tracker = effect(() => {
1022
1033
  touchReactive(state);
1034
+ Object.keys(state).forEach((key) => {
1035
+ const v = state[key];
1036
+ if (isRef(v)) v.value;
1037
+ });
1023
1038
  Object.keys(computedRefs).forEach((key) => computedRefs[key].value);
1024
- }, { scheduler: () => queueJob(job) });
1039
+ }, {
1040
+ lazy: true,
1041
+ scheduler: () => queueJob(job)
1042
+ });
1025
1043
  job();
1026
1044
  stopHandles.push(() => stop(tracker));
1027
1045
  function registerWatch(source, cb, watchOptions) {
@@ -1145,6 +1163,7 @@ function defineComponent(options) {
1145
1163
  function applySetupResult(runtime, _target, result) {
1146
1164
  const methods = runtime?.methods ?? Object.create(null);
1147
1165
  const state = runtime?.state ?? Object.create(null);
1166
+ const rawState = isReactive(state) ? toRaw(state) : state;
1148
1167
  if (runtime && !runtime.methods) try {
1149
1168
  runtime.methods = methods;
1150
1169
  } catch {}
@@ -1154,6 +1173,16 @@ function applySetupResult(runtime, _target, result) {
1154
1173
  Object.keys(result).forEach((key) => {
1155
1174
  const val = result[key];
1156
1175
  if (typeof val === "function") methods[key] = (...args) => val.apply(runtime?.proxy ?? runtime, args);
1176
+ else if (val === _target || !shouldExposeInSnapshot(val)) try {
1177
+ Object.defineProperty(rawState, key, {
1178
+ value: val,
1179
+ configurable: true,
1180
+ enumerable: false,
1181
+ writable: true
1182
+ });
1183
+ } catch {
1184
+ state[key] = val;
1185
+ }
1157
1186
  else state[key] = val;
1158
1187
  });
1159
1188
  if (runtime) {
@@ -1161,6 +1190,18 @@ function applySetupResult(runtime, _target, result) {
1161
1190
  runtime.state = runtime.state ?? state;
1162
1191
  }
1163
1192
  }
1193
+ function isPlainObject(value) {
1194
+ if (Object.prototype.toString.call(value) !== "[object Object]") return false;
1195
+ const proto = Object.getPrototypeOf(value);
1196
+ return proto === null || proto === Object.prototype;
1197
+ }
1198
+ function shouldExposeInSnapshot(value) {
1199
+ if (value == null) return true;
1200
+ if (typeof value !== "object") return true;
1201
+ if (isRef(value) || isReactive(value)) return true;
1202
+ if (Array.isArray(value)) return true;
1203
+ return isPlainObject(value);
1204
+ }
1164
1205
  /**
1165
1206
  * 从 Vue SFC 选项创建 wevu 组件,供 weapp-vite 编译产物直接调用的兼容入口。
1166
1207
  *
@@ -1273,4 +1314,4 @@ function injectGlobal(key, defaultValue) {
1273
1314
  }
1274
1315
 
1275
1316
  //#endregion
1276
- export { callHookList, callHookReturn, callUpdateHooks, computed, createApp, createStore, createWevuComponent, defineComponent, defineStore, effect, getCurrentInstance, getDeepWatchStrategy, inject, injectGlobal, isRaw, isReactive, isRef, isShallowReactive, isShallowRef, markRaw, mountRuntimeInstance, nextTick, onActivated, onAddToFavorites, onAppError, onAppHide, onAppShow, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onHide, onMounted, onPageScroll, onReady, onRouteDone, onSaveExitState, onServerPrefetch, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onUnload, onUnmounted, onUpdated, provide, provideGlobal, reactive, readonly, ref, registerApp, registerComponent, runSetupFunction, setCurrentInstance, setDeepWatchStrategy, shallowReactive, shallowRef, stop, storeToRefs, teardownRuntimeInstance, toRaw, toRef, toRefs, touchReactive, traverse, triggerRef, unref, watch, watchEffect };
1317
+ export { batch, callHookList, callHookReturn, callUpdateHooks, computed, createApp, createStore, createWevuComponent, defineComponent, defineStore, effect, effectScope, endBatch, getCurrentInstance, getCurrentScope, getDeepWatchStrategy, inject, injectGlobal, isRaw, isReactive, isRef, isShallowReactive, isShallowRef, markRaw, mountRuntimeInstance, nextTick, onActivated, onAddToFavorites, onAppError, onAppHide, onAppShow, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onHide, onMounted, onPageScroll, onReady, onRouteDone, onSaveExitState, onScopeDispose, onServerPrefetch, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onUnload, onUnmounted, onUpdated, provide, provideGlobal, reactive, readonly, ref, registerApp, registerComponent, runSetupFunction, setCurrentInstance, setDeepWatchStrategy, shallowReactive, shallowRef, startBatch, stop, storeToRefs, teardownRuntimeInstance, toRaw, toRef, toRefs, touchReactive, traverse, triggerRef, unref, watch, watchEffect };
@@ -24,6 +24,85 @@ function nextTick(fn) {
24
24
  const targetMap = /* @__PURE__ */ new WeakMap();
25
25
  let activeEffect = null;
26
26
  const effectStack = [];
27
+ let batchDepth = 0;
28
+ const batchedEffects = /* @__PURE__ */ new Set();
29
+ function startBatch() {
30
+ batchDepth++;
31
+ }
32
+ function endBatch() {
33
+ if (batchDepth === 0) return;
34
+ batchDepth--;
35
+ if (batchDepth === 0) flushBatchedEffects();
36
+ }
37
+ function batch(fn) {
38
+ startBatch();
39
+ try {
40
+ return fn();
41
+ } finally {
42
+ endBatch();
43
+ }
44
+ }
45
+ function flushBatchedEffects() {
46
+ while (batchedEffects.size) {
47
+ const effects = Array.from(batchedEffects);
48
+ batchedEffects.clear();
49
+ for (const ef of effects) ef();
50
+ }
51
+ }
52
+ let activeEffectScope;
53
+ var EffectScopeImpl = class {
54
+ active = true;
55
+ effects = [];
56
+ cleanups = [];
57
+ parent;
58
+ scopes;
59
+ constructor(detached = false) {
60
+ this.detached = detached;
61
+ if (!detached && activeEffectScope) {
62
+ this.parent = activeEffectScope;
63
+ (activeEffectScope.scopes ||= []).push(this);
64
+ }
65
+ }
66
+ run(fn) {
67
+ if (!this.active) return;
68
+ const prev = activeEffectScope;
69
+ activeEffectScope = this;
70
+ try {
71
+ return fn();
72
+ } finally {
73
+ activeEffectScope = prev;
74
+ }
75
+ }
76
+ stop() {
77
+ if (!this.active) return;
78
+ this.active = false;
79
+ for (const effect$1 of this.effects) stop(effect$1);
80
+ this.effects.length = 0;
81
+ for (const cleanup of this.cleanups) cleanup();
82
+ this.cleanups.length = 0;
83
+ if (this.scopes) {
84
+ for (const scope of this.scopes) scope.stop();
85
+ this.scopes.length = 0;
86
+ }
87
+ if (this.parent?.scopes) {
88
+ const index = this.parent.scopes.indexOf(this);
89
+ if (index >= 0) this.parent.scopes.splice(index, 1);
90
+ }
91
+ this.parent = void 0;
92
+ }
93
+ };
94
+ function effectScope(detached = false) {
95
+ return new EffectScopeImpl(detached);
96
+ }
97
+ function getCurrentScope() {
98
+ return activeEffectScope;
99
+ }
100
+ function onScopeDispose(fn) {
101
+ if (activeEffectScope?.active) activeEffectScope.cleanups.push(fn);
102
+ }
103
+ function recordEffectScope(effect$1) {
104
+ if (activeEffectScope?.active) activeEffectScope.effects.push(effect$1);
105
+ }
27
106
  function cleanupEffect(effect$1) {
28
107
  const { deps } = effect$1;
29
108
  for (let i = 0; i < deps.length; i++) deps[i].delete(effect$1);
@@ -32,26 +111,30 @@ function cleanupEffect(effect$1) {
32
111
  function createReactiveEffect(fn, options = {}) {
33
112
  const effect$1 = function reactiveEffect() {
34
113
  if (!effect$1.active) return fn();
35
- if (effectStack.includes(effect$1)) return fn();
114
+ if (effect$1._running) return fn();
36
115
  cleanupEffect(effect$1);
37
116
  try {
117
+ effect$1._running = true;
38
118
  effectStack.push(effect$1);
39
119
  activeEffect = effect$1;
40
120
  return fn();
41
121
  } finally {
42
122
  effectStack.pop();
43
123
  activeEffect = effectStack[effectStack.length - 1] ?? null;
124
+ effect$1._running = false;
44
125
  }
45
126
  };
46
127
  effect$1.deps = [];
47
128
  effect$1.scheduler = options.scheduler;
48
129
  effect$1.onStop = options.onStop;
49
130
  effect$1.active = true;
131
+ effect$1._running = false;
50
132
  effect$1._fn = fn;
51
133
  return effect$1;
52
134
  }
53
135
  function effect(fn, options = {}) {
54
136
  const _effect = createReactiveEffect(fn, options);
137
+ recordEffectScope(_effect);
55
138
  if (!options.lazy) _effect();
56
139
  return _effect;
57
140
  }
@@ -87,10 +170,7 @@ function trigger(target, key) {
87
170
  effects.forEach((ef) => {
88
171
  if (ef !== activeEffect) effectsToRun.add(ef);
89
172
  });
90
- effectsToRun.forEach((ef) => {
91
- if (ef.scheduler) ef.scheduler();
92
- else ef();
93
- });
173
+ effectsToRun.forEach(scheduleEffect);
94
174
  }
95
175
  function trackEffects(dep) {
96
176
  if (!activeEffect) return;
@@ -100,10 +180,18 @@ function trackEffects(dep) {
100
180
  }
101
181
  }
102
182
  function triggerEffects(dep) {
103
- dep.forEach((ef) => {
104
- if (ef.scheduler) ef.scheduler();
105
- else ef();
106
- });
183
+ dep.forEach(scheduleEffect);
184
+ }
185
+ function scheduleEffect(ef) {
186
+ if (ef.scheduler) {
187
+ ef.scheduler();
188
+ return;
189
+ }
190
+ if (batchDepth > 0) {
191
+ batchedEffects.add(ef);
192
+ return;
193
+ }
194
+ ef();
107
195
  }
108
196
 
109
197
  //#endregion
@@ -365,7 +453,7 @@ var RefImpl = class {
365
453
  };
366
454
  function ref(value) {
367
455
  if (isRef(value)) return value;
368
- return new RefImpl(value);
456
+ return markRaw(new RefImpl(value));
369
457
  }
370
458
  function unref(value) {
371
459
  return isRef(value) ? value.value : value;
@@ -389,7 +477,7 @@ var CustomRefImpl = class {
389
477
  }
390
478
  };
391
479
  function customRef(factory, defaultValue) {
392
- return new CustomRefImpl(factory, defaultValue);
480
+ return markRaw(new CustomRefImpl(factory, defaultValue));
393
481
  }
394
482
 
395
483
  //#endregion
@@ -635,4 +723,4 @@ function storeToRefs(store) {
635
723
  }
636
724
 
637
725
  //#endregion
638
- export { computed as _, isRef as a, nextTick as b, isObject$1 as c, isShallowReactive as d, markRaw as f, touchReactive as g, toRaw as h, customRef as i, isRaw as l, shallowReactive as m, defineStore as n, ref as o, reactive as p, createStore as r, unref as s, storeToRefs as t, isReactive as u, effect as v, queueJob as x, stop as y };
726
+ export { onScopeDispose as C, queueJob as D, nextTick as E, getCurrentScope as S, stop as T, computed as _, isRef as a, effectScope as b, isObject$1 as c, isShallowReactive as d, markRaw as f, touchReactive as g, toRaw as h, customRef as i, isRaw as l, shallowReactive as m, defineStore as n, ref as o, reactive as p, createStore as r, unref as s, storeToRefs as t, isReactive as u, batch as v, startBatch as w, endBatch as x, effect as y };
@@ -25,6 +25,85 @@ function nextTick(fn) {
25
25
  const targetMap = /* @__PURE__ */ new WeakMap();
26
26
  let activeEffect = null;
27
27
  const effectStack = [];
28
+ let batchDepth = 0;
29
+ const batchedEffects = /* @__PURE__ */ new Set();
30
+ function startBatch() {
31
+ batchDepth++;
32
+ }
33
+ function endBatch() {
34
+ if (batchDepth === 0) return;
35
+ batchDepth--;
36
+ if (batchDepth === 0) flushBatchedEffects();
37
+ }
38
+ function batch(fn) {
39
+ startBatch();
40
+ try {
41
+ return fn();
42
+ } finally {
43
+ endBatch();
44
+ }
45
+ }
46
+ function flushBatchedEffects() {
47
+ while (batchedEffects.size) {
48
+ const effects = Array.from(batchedEffects);
49
+ batchedEffects.clear();
50
+ for (const ef of effects) ef();
51
+ }
52
+ }
53
+ let activeEffectScope;
54
+ var EffectScopeImpl = class {
55
+ active = true;
56
+ effects = [];
57
+ cleanups = [];
58
+ parent;
59
+ scopes;
60
+ constructor(detached = false) {
61
+ this.detached = detached;
62
+ if (!detached && activeEffectScope) {
63
+ this.parent = activeEffectScope;
64
+ (activeEffectScope.scopes ||= []).push(this);
65
+ }
66
+ }
67
+ run(fn) {
68
+ if (!this.active) return;
69
+ const prev = activeEffectScope;
70
+ activeEffectScope = this;
71
+ try {
72
+ return fn();
73
+ } finally {
74
+ activeEffectScope = prev;
75
+ }
76
+ }
77
+ stop() {
78
+ if (!this.active) return;
79
+ this.active = false;
80
+ for (const effect$1 of this.effects) stop(effect$1);
81
+ this.effects.length = 0;
82
+ for (const cleanup of this.cleanups) cleanup();
83
+ this.cleanups.length = 0;
84
+ if (this.scopes) {
85
+ for (const scope of this.scopes) scope.stop();
86
+ this.scopes.length = 0;
87
+ }
88
+ if (this.parent?.scopes) {
89
+ const index = this.parent.scopes.indexOf(this);
90
+ if (index >= 0) this.parent.scopes.splice(index, 1);
91
+ }
92
+ this.parent = void 0;
93
+ }
94
+ };
95
+ function effectScope(detached = false) {
96
+ return new EffectScopeImpl(detached);
97
+ }
98
+ function getCurrentScope() {
99
+ return activeEffectScope;
100
+ }
101
+ function onScopeDispose(fn) {
102
+ if (activeEffectScope?.active) activeEffectScope.cleanups.push(fn);
103
+ }
104
+ function recordEffectScope(effect$1) {
105
+ if (activeEffectScope?.active) activeEffectScope.effects.push(effect$1);
106
+ }
28
107
  function cleanupEffect(effect$1) {
29
108
  const { deps } = effect$1;
30
109
  for (let i = 0; i < deps.length; i++) deps[i].delete(effect$1);
@@ -33,26 +112,30 @@ function cleanupEffect(effect$1) {
33
112
  function createReactiveEffect(fn, options = {}) {
34
113
  const effect$1 = function reactiveEffect() {
35
114
  if (!effect$1.active) return fn();
36
- if (effectStack.includes(effect$1)) return fn();
115
+ if (effect$1._running) return fn();
37
116
  cleanupEffect(effect$1);
38
117
  try {
118
+ effect$1._running = true;
39
119
  effectStack.push(effect$1);
40
120
  activeEffect = effect$1;
41
121
  return fn();
42
122
  } finally {
43
123
  effectStack.pop();
44
124
  activeEffect = effectStack[effectStack.length - 1] ?? null;
125
+ effect$1._running = false;
45
126
  }
46
127
  };
47
128
  effect$1.deps = [];
48
129
  effect$1.scheduler = options.scheduler;
49
130
  effect$1.onStop = options.onStop;
50
131
  effect$1.active = true;
132
+ effect$1._running = false;
51
133
  effect$1._fn = fn;
52
134
  return effect$1;
53
135
  }
54
136
  function effect(fn, options = {}) {
55
137
  const _effect = createReactiveEffect(fn, options);
138
+ recordEffectScope(_effect);
56
139
  if (!options.lazy) _effect();
57
140
  return _effect;
58
141
  }
@@ -88,10 +171,7 @@ function trigger(target, key) {
88
171
  effects.forEach((ef) => {
89
172
  if (ef !== activeEffect) effectsToRun.add(ef);
90
173
  });
91
- effectsToRun.forEach((ef) => {
92
- if (ef.scheduler) ef.scheduler();
93
- else ef();
94
- });
174
+ effectsToRun.forEach(scheduleEffect);
95
175
  }
96
176
  function trackEffects(dep) {
97
177
  if (!activeEffect) return;
@@ -101,10 +181,18 @@ function trackEffects(dep) {
101
181
  }
102
182
  }
103
183
  function triggerEffects(dep) {
104
- dep.forEach((ef) => {
105
- if (ef.scheduler) ef.scheduler();
106
- else ef();
107
- });
184
+ dep.forEach(scheduleEffect);
185
+ }
186
+ function scheduleEffect(ef) {
187
+ if (ef.scheduler) {
188
+ ef.scheduler();
189
+ return;
190
+ }
191
+ if (batchDepth > 0) {
192
+ batchedEffects.add(ef);
193
+ return;
194
+ }
195
+ ef();
108
196
  }
109
197
 
110
198
  //#endregion
@@ -366,7 +454,7 @@ var RefImpl = class {
366
454
  };
367
455
  function ref(value) {
368
456
  if (isRef(value)) return value;
369
- return new RefImpl(value);
457
+ return markRaw(new RefImpl(value));
370
458
  }
371
459
  function unref(value) {
372
460
  return isRef(value) ? value.value : value;
@@ -390,7 +478,7 @@ var CustomRefImpl = class {
390
478
  }
391
479
  };
392
480
  function customRef(factory, defaultValue) {
393
- return new CustomRefImpl(factory, defaultValue);
481
+ return markRaw(new CustomRefImpl(factory, defaultValue));
394
482
  }
395
483
 
396
484
  //#endregion
@@ -636,6 +724,12 @@ function storeToRefs(store) {
636
724
  }
637
725
 
638
726
  //#endregion
727
+ Object.defineProperty(exports, 'batch', {
728
+ enumerable: true,
729
+ get: function () {
730
+ return batch;
731
+ }
732
+ });
639
733
  Object.defineProperty(exports, 'computed', {
640
734
  enumerable: true,
641
735
  get: function () {
@@ -666,6 +760,24 @@ Object.defineProperty(exports, 'effect', {
666
760
  return effect;
667
761
  }
668
762
  });
763
+ Object.defineProperty(exports, 'effectScope', {
764
+ enumerable: true,
765
+ get: function () {
766
+ return effectScope;
767
+ }
768
+ });
769
+ Object.defineProperty(exports, 'endBatch', {
770
+ enumerable: true,
771
+ get: function () {
772
+ return endBatch;
773
+ }
774
+ });
775
+ Object.defineProperty(exports, 'getCurrentScope', {
776
+ enumerable: true,
777
+ get: function () {
778
+ return getCurrentScope;
779
+ }
780
+ });
669
781
  Object.defineProperty(exports, 'isObject', {
670
782
  enumerable: true,
671
783
  get: function () {
@@ -708,6 +820,12 @@ Object.defineProperty(exports, 'nextTick', {
708
820
  return nextTick;
709
821
  }
710
822
  });
823
+ Object.defineProperty(exports, 'onScopeDispose', {
824
+ enumerable: true,
825
+ get: function () {
826
+ return onScopeDispose;
827
+ }
828
+ });
711
829
  Object.defineProperty(exports, 'queueJob', {
712
830
  enumerable: true,
713
831
  get: function () {
@@ -732,6 +850,12 @@ Object.defineProperty(exports, 'shallowReactive', {
732
850
  return shallowReactive;
733
851
  }
734
852
  });
853
+ Object.defineProperty(exports, 'startBatch', {
854
+ enumerable: true,
855
+ get: function () {
856
+ return startBatch;
857
+ }
858
+ });
735
859
  Object.defineProperty(exports, 'stop', {
736
860
  enumerable: true,
737
861
  get: function () {
package/dist/store.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_store = require('./store-Cmw9vWBT.cjs');
1
+ const require_store = require('./store-D0GD8ulz.cjs');
2
2
 
3
3
  exports.createStore = require_store.createStore;
4
4
  exports.defineStore = require_store.defineStore;
package/dist/store.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as defineStore, r as createStore, t as storeToRefs } from "./store-BcU7YVhB.mjs";
1
+ import { n as defineStore, r as createStore, t as storeToRefs } from "./store-2q4qcdBi.mjs";
2
2
 
3
3
  export { createStore, defineStore, storeToRefs };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wevu",
3
3
  "type": "module",
4
- "version": "1.0.0-alpha.1",
4
+ "version": "1.0.0-alpha.2",
5
5
  "description": "Vue 3 风格的小程序运行时,包含响应式、diff+setData 与轻量状态管理",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",