vue-page-store 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -641,6 +641,103 @@ __VUE_PAGE_STORE__.registry.forEach(...)
641
641
  - `__VUE_PAGE_STORE__` 是 dev-only 调试接口,shape 和键名可能在后续版本变化,**不要在生产代码里依赖**
642
642
  - 微前端场景下,多个子应用都加载 vue-page-store 时,最后挂载的会覆盖前面的。如需共存,请退回手动挂载并用自己的命名
643
643
 
644
+ ### `window.PAGE_STORE_DEVTOOLS` —— debug 注册表 *(v0.5.1 新增)*
645
+
646
+ v0.5.1 新增了 dev-only 的 debug 模块,在 `window.PAGE_STORE_DEVTOOLS` 上暴露结构化调试数据:
647
+
648
+ ```js
649
+ window.PAGE_STORE_DEVTOOLS
650
+ // {
651
+ // stores: Map, ← store 元信息(id、active、destroyed、storeRef…)
652
+ // events: [], ← 事件时间线(最近 500 条)
653
+ // seq: number ← 全局递增计数
654
+ // }
655
+ ```
656
+
657
+ #### 自动采集的事件
658
+
659
+ | 事件 | 说明 |
660
+ |---|---|
661
+ | `store:create` | store 实例创建 |
662
+ | `store:destroy` | store 实例销毁 |
663
+ | `action:start` | action 调用开始(含参数快照) |
664
+ | `action:end` | action 调用结束(含 duration) |
665
+ | `action:error` | action 抛错或 reject(含错误信息和 duration) |
666
+
667
+ 每条事件包含 `seq`(全局序号)、`ts`(时间戳)、`storeId`、`type`、`payload`。
668
+
669
+ #### 控制台用法
670
+
671
+ ```js
672
+ // 查看当前存活的 store
673
+ PAGE_STORE_DEVTOOLS.stores
674
+
675
+ // 查看最近的事件
676
+ PAGE_STORE_DEVTOOLS.events.slice(-5)
677
+
678
+ // 筛选某个 store 的 action 事件
679
+ PAGE_STORE_DEVTOOLS.events
680
+ .filter(e => e.storeId === 'orderList' && e.type.startsWith('action:'))
681
+
682
+ // 查看 action 耗时
683
+ PAGE_STORE_DEVTOOLS.events
684
+ .filter(e => e.type === 'action:end')
685
+ .map(e => e.payload.action + ': ' + e.payload.duration + 'ms')
686
+ ```
687
+
688
+ 生产环境下 `PAGE_STORE_DEVTOOLS` 不会被挂载,所有 debug 逻辑为 no-op。
689
+
690
+ ### DevPanel —— 页面内悬浮面板 *(v0.5.1 新增)*
691
+
692
+ v0.5.1 提供了一个最小的页面内调试面板,在右下角悬浮显示:
693
+
694
+ - **左侧**:store 列表(显示 active / idle / destroyed 状态)
695
+ - **右侧四个 tab**:
696
+ - `$state` — 当前选中 store 的业务状态
697
+ - `$source` — 页面输入 / 原始返回
698
+ - `getters` — 派生计算值
699
+ - `events` — 该 store 最近 50 条事件
700
+
701
+ 面板每 500ms 刷新一次,实时反映 store 变化。
702
+
703
+ #### 接入方式
704
+
705
+ ```js
706
+ // main.js — 仅开发环境加载
707
+ if (process.env.NODE_ENV !== 'production') {
708
+ import('vue-page-store/debug/installPanel').then(m => m.installDevPanel())
709
+ }
710
+ ```
711
+
712
+ 面板会自动挂载到 `document.body`,不侵入业务组件树。生产环境下 `installDevPanel()` 是 no-op。
713
+
714
+ #### 注意事项
715
+
716
+ - DevPanel 是独立 Vue 实例,不影响业务组件树
717
+ - 需要构建链能处理 `.vue` SFC(webpack + vue-loader 或 Vite 默认支持)
718
+ - 微前端场景下,多个子应用各自挂面板,互不干扰
719
+ - 这是 dev-only 工具,不要在生产代码里依赖
720
+
721
+ #### 强制开启
722
+
723
+ Vite / webpack 5 等不 polyfill `process` 的环境下,如果 `isDev` 检测失败,可以在**页面加载前**手动设置:
724
+
725
+ ```js
726
+ window.__VUE_PAGE_STORE_DEV__ = true
727
+ ```
728
+
729
+ ### debug 模块文件结构
730
+
731
+ ```
732
+ src/debug/
733
+ ├── registry.js ← window.PAGE_STORE_DEVTOOLS 数据层
734
+ ├── emit.js ← emitDebugEvent 埋点入口
735
+ ├── DevPanel.vue ← 悬浮面板组件
736
+ └── installPanel.js ← 面板挂载器
737
+ ```
738
+
739
+ 所有 debug 文件仅在 dev 环境生效。生产构建中:`registry.js` 和 `emit.js` 中的所有函数早 return / 返回空值,不执行任何逻辑,不挂 `window`,不占内存。如果你的打包器支持 tree-shaking 且 `import('...installPanel')` 走动态导入,面板代码不会进入生产包。
740
+
644
741
  ## 从 v0.3.x 升级
645
742
 
646
743
  ### Breaking Changes
@@ -708,11 +805,23 @@ v0.5 **完全向后兼容** v0.4.x:
708
805
 
709
806
  升级只需要改版本号,无需改代码。
710
807
 
808
+ ## 从 v0.5.0 升级到 v0.5.1
809
+
810
+ v0.5.1 **完全向后兼容** v0.5.0:
811
+
812
+ - **修复**:`isDev` 检测改用 `try/catch` 兜底,修复 Vite / webpack 5 不 polyfill `process` 时模块加载报错的问题
813
+ - **新增**:dev-only debug 模块(`debug/registry.js`、`debug/emit.js`、`debug/DevPanel.vue`、`debug/installPanel.js`)
814
+ - **新增**:`window.PAGE_STORE_DEVTOOLS` 调试注册表,自动采集 store 创建/销毁和 action 调用事件
815
+ - **新增**:DevPanel 悬浮面板,可视化查看 store 列表、state/source/getters、事件时间线
816
+
817
+ 升级只需要改版本号。debug 模块为可选接入,不接入等同于 v0.5.0 行为。
818
+
711
819
  ## Roadmap
712
820
 
713
821
  - **Keyed instance** — `useStore(vm, scopeKey)` 支持同定义多实例
714
822
  - **Official plugins** — 随着 `vue-page-runtime` 等生态库成熟,补充第一方 plugin 文档
715
823
  - **More page runtime helpers** — 在不增加心智负担的前提下继续补页面层能力
824
+ - **Vue Devtools 集成** — 在 debug 模块基础上对接 Vue Devtools inspector / timeline API
716
825
 
717
826
  ## License
718
827
 
package/dist/index.cjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * vue-page-store v0.5.0
2
+ * vue-page-store v0.5.1
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
@@ -9,13 +9,221 @@ Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
10
  var Vue = require('vue');
11
11
 
12
+ /**
13
+ * vue-page-store debug / registry
14
+ *
15
+ * 纯 JS 数据层:不依赖 Vue,不涉及 UI。
16
+ *
17
+ * 对外:
18
+ * window.PAGE_STORE_DEVTOOLS = { stores: Map, events: [], seq: number }
19
+ *
20
+ * API:
21
+ * nextId() — 递增并返回 seq
22
+ * addStore(meta) — stores.set(meta.id, meta)
23
+ * updateStore(id, patch) — 浅合并进已有 meta
24
+ * removeStore(id) — stores.delete(id)
25
+ * addEvent(event) — events.push + 环形裁剪
26
+ * getStores() — 返回 Map(生产返回空 Map)
27
+ * getEvents() — 返回数组(生产返回空数组)
28
+ *
29
+ * 仅开发环境生效。生产环境下 ensure() 返回 null,
30
+ * 所有写 API 静默 no-op,不挂 window,不占内存。
31
+ */
32
+
33
+ var MAX_EVENTS = 500;
34
+
35
+ // ---- isDev:稳健检测 ----
36
+ // webpack 4 / 旧 CRA 有 process;Vite / webpack 5 不 polyfill process 的情况用 try/catch 兜住。
37
+ // 额外允许 window.__VUE_PAGE_STORE_DEV__ = true 强制开启(staging 临开调试面板用)。
38
+ var _isDev = false;
39
+ try {
40
+ if (typeof process !== 'undefined'
41
+ && process.env
42
+ && process.env.NODE_ENV !== 'production') {
43
+ _isDev = true;
44
+ }
45
+ } catch (e) { /* no process polyfill */ }
46
+ try {
47
+ if (typeof window !== 'undefined' && window.__VUE_PAGE_STORE_DEV__ === true) {
48
+ _isDev = true;
49
+ }
50
+ } catch (e) { /* SSR */ }
51
+
52
+ var isDev$1 = _isDev;
53
+
54
+ // ---- 单例 ----
55
+ var _devtools = null;
56
+
57
+ function ensure() {
58
+ if (!isDev$1) return null;
59
+ if (_devtools) return _devtools;
60
+
61
+ _devtools = {
62
+ stores: new Map(),
63
+ events: [],
64
+ seq: 0,
65
+ };
66
+
67
+ if (typeof window !== 'undefined') {
68
+ try { window.PAGE_STORE_DEVTOOLS = _devtools; } catch (e) { /* locked window */ }
69
+ }
70
+
71
+ return _devtools;
72
+ }
73
+
74
+ // ---- API ----
75
+
76
+ function nextId() {
77
+ var dt = ensure();
78
+ if (!dt) return 0;
79
+ dt.seq++;
80
+ return dt.seq;
81
+ }
82
+
83
+ function addStore(meta) {
84
+ var dt = ensure();
85
+ if (!dt) return;
86
+ if (!meta || !meta.id) return;
87
+ dt.stores.set(meta.id, meta);
88
+ }
89
+
90
+ function updateStore(id, patch) {
91
+ var dt = ensure();
92
+ if (!dt) return;
93
+ if (!id || !patch) return;
94
+ var m = dt.stores.get(id);
95
+ if (!m) return;
96
+ for (var k in patch) {
97
+ if (Object.prototype.hasOwnProperty.call(patch, k)) {
98
+ m[k] = patch[k];
99
+ }
100
+ }
101
+ }
102
+
103
+ function addEvent(event) {
104
+ var dt = ensure();
105
+ if (!dt) return;
106
+ if (!event) return;
107
+ dt.events.push(event);
108
+ // 环形裁剪,防止长时间开发内存无限增长
109
+ var overflow = dt.events.length - MAX_EVENTS;
110
+ if (overflow > 0) dt.events.splice(0, overflow);
111
+ }
112
+
113
+ /**
114
+ * vue-page-store debug / emit
115
+ *
116
+ * 唯一对外高层入口:
117
+ * emitDebugEvent(store, type, payload)
118
+ *
119
+ * 职责:
120
+ * 1. 把一次领域调用写入 events 时间线(带 seq + ts)
121
+ * 2. 对特定 type 顺带同步 stores meta(create / destroy / lifecycle)
122
+ * 3. payload 做序列化快照,避免后续持有活引用
123
+ * 4. 仅 dev 生效;任何异常一律吞掉,绝不拖累业务
124
+ *
125
+ * 支持的 type:
126
+ * store:create payload = { name? } → addStore(meta)
127
+ * store:destroy payload = undefined → updateStore(id, { destroyed: true, active: false })
128
+ * lifecycle:init payload = undefined → updateStore(id, { route })
129
+ * lifecycle:enter payload = undefined → updateStore(id, { active: true, route })
130
+ * lifecycle:leave payload = undefined → updateStore(id, { active: false })
131
+ * action:start payload = { action, args } → 仅写事件
132
+ * action:end payload = { action, duration } → 仅写事件
133
+ * action:error payload = { action, duration, error } → 仅写事件
134
+ * state:set payload = { key, value } → 仅写事件
135
+ * state:patch payload = { patch } → 仅写事件
136
+ */
137
+
138
+
139
+ // ---- helpers ----
140
+
141
+ function readRoute(store) {
142
+ try {
143
+ var vm = store && store.$vm;
144
+ if (vm && vm.$route) {
145
+ return {
146
+ path: vm.$route.path,
147
+ fullPath: vm.$route.fullPath,
148
+ name: vm.$route.name,
149
+ };
150
+ }
151
+ } catch (e) { /* ignore */ }
152
+ return null;
153
+ }
154
+
155
+ function snapshot(v) {
156
+ if (v === undefined) return undefined;
157
+ if (v === null) return null;
158
+ var t = typeof v;
159
+ if (t === 'function') return '[Function]';
160
+ if (t !== 'object') return v;
161
+ try {
162
+ return JSON.parse(JSON.stringify(v));
163
+ } catch (e) {
164
+ return '[Unserializable]';
165
+ }
166
+ }
167
+
168
+ // ---- 主入口 ----
169
+
170
+ function emitDebugEvent(store, type, payload) {
171
+ if (!isDev$1) return null;
172
+
173
+ try {
174
+ var id = store && store.$id;
175
+
176
+ // 必要的 meta 同步
177
+ switch (type) {
178
+ case 'store:create':
179
+ addStore({
180
+ id: id,
181
+ name: (payload && payload.name) || id,
182
+ route: readRoute(store),
183
+ createdAt: Date.now(),
184
+ active: false,
185
+ destroyed: false,
186
+ keepAlive: false,
187
+ storeRef: store,
188
+ });
189
+ break;
190
+ case 'store:destroy':
191
+ updateStore(id, { destroyed: true, active: false });
192
+ break;
193
+ case 'lifecycle:init':
194
+ updateStore(id, { route: readRoute(store) });
195
+ break;
196
+ case 'lifecycle:enter':
197
+ updateStore(id, { active: true, route: readRoute(store) });
198
+ break;
199
+ case 'lifecycle:leave':
200
+ updateStore(id, { active: false });
201
+ break;
202
+ default:
203
+ break;
204
+ }
205
+
206
+ var event = {
207
+ seq: nextId(),
208
+ ts: Date.now(),
209
+ storeId: id,
210
+ type: type,
211
+ payload: snapshot(payload),
212
+ };
213
+ addEvent(event);
214
+ return event;
215
+ } catch (e) {
216
+ return null;
217
+ }
218
+ }
219
+
12
220
  /*!
13
- * vue-page-store v0.5.0
221
+ * vue-page-store v0.5.1
14
222
  * (c) 2026 weijianjun
15
223
  * @license MIT
16
224
  */
17
225
  /**
18
- * vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
226
+ * vue-page-store 0.5.1 — Vue 2.6 Page Scope Runtime
19
227
  *
20
228
  * 页面级作用域运行时容器:
21
229
  * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus · plugin
@@ -32,15 +240,25 @@ var Vue = require('vue');
32
240
  * v0.5 新增:
33
241
  * plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
34
242
  *
243
+ * v0.5.1 修复/新增:
244
+ * isDev → try/catch 兜底,修复 Vite / webpack 5 不 polyfill process 时报错
245
+ * debug → dev-only 调试工具:store 创建/销毁追踪、action 埋点、DevPanel
246
+ *
35
247
  * @author weijianjun
36
248
  * @license MIT
37
249
  */
38
250
 
39
251
 
40
252
  // ====== dev-only warning ======
41
- var isDev = typeof process !== 'undefined'
42
- && process.env
43
- && process.env.NODE_ENV !== 'production';
253
+ // v0.5.1 修复:try/catch 兜底,Vite / webpack 5 不 polyfill process 时不再报错
254
+ var isDev = false;
255
+ try {
256
+ isDev = typeof process !== 'undefined'
257
+ && process.env
258
+ && process.env.NODE_ENV !== 'production';
259
+ } catch (e) {
260
+ // Vite / webpack 5 等环境下 process 未定义或 process.env 被 getter 拦截
261
+ }
44
262
 
45
263
  function warn(msg) {
46
264
  if (isDev) {
@@ -48,6 +266,54 @@ function warn(msg) {
48
266
  }
49
267
  }
50
268
 
269
+ // ====== debug: wrapAction helper ======
270
+ function _now() {
271
+ return typeof performance !== 'undefined' && performance.now
272
+ ? performance.now()
273
+ : Date.now();
274
+ }
275
+ function wrapAction(store, name, boundFn) {
276
+ return function () {
277
+ var args = Array.prototype.slice.call(arguments);
278
+ var t0 = _now();
279
+ emitDebugEvent(store, 'action:start', { action: name, args: args });
280
+ var result;
281
+ try {
282
+ result = boundFn.apply(null, args);
283
+ } catch (syncErr) {
284
+ emitDebugEvent(store, 'action:error', {
285
+ action: name,
286
+ duration: +(_now() - t0).toFixed(2),
287
+ error: (syncErr && syncErr.message) || String(syncErr),
288
+ });
289
+ throw syncErr;
290
+ }
291
+ if (result && typeof result.then === 'function') {
292
+ Promise.resolve(result).then(
293
+ function () {
294
+ emitDebugEvent(store, 'action:end', {
295
+ action: name,
296
+ duration: +(_now() - t0).toFixed(2),
297
+ });
298
+ },
299
+ function (err) {
300
+ emitDebugEvent(store, 'action:error', {
301
+ action: name,
302
+ duration: +(_now() - t0).toFixed(2),
303
+ error: (err && err.message) || String(err),
304
+ });
305
+ },
306
+ );
307
+ } else {
308
+ emitDebugEvent(store, 'action:end', {
309
+ action: name,
310
+ duration: +(_now() - t0).toFixed(2),
311
+ });
312
+ }
313
+ return result;
314
+ };
315
+ }
316
+
51
317
  // Store 注册表(导出供调试 / devtools 使用)
52
318
  var storeRegistry = new Map();
53
319
 
@@ -57,7 +323,9 @@ if (isDev && typeof window !== 'undefined') {
57
323
  registry: storeRegistry,
58
324
  get stores() {
59
325
  var result = {};
60
- storeRegistry.forEach(function (s, id) { result[id] = s; });
326
+ storeRegistry.forEach(function (s, id) {
327
+ result[id] = s;
328
+ });
61
329
  return result;
62
330
  },
63
331
  };
@@ -80,9 +348,15 @@ function registerPlugin(plugin) {
80
348
  throw new Error('[vue-page-store] plugin 需要一个 name 属性');
81
349
  }
82
350
  if (typeof plugin.install !== 'function') {
83
- throw new Error('[vue-page-store] plugin "' + plugin.name + '" 需要一个 install 方法');
351
+ throw new Error(
352
+ '[vue-page-store] plugin "' + plugin.name + '" 需要一个 install 方法',
353
+ );
84
354
  }
85
- if (_plugins.some(function (p) { return p.name === plugin.name; })) {
355
+ if (
356
+ _plugins.some(function (p) {
357
+ return p.name === plugin.name;
358
+ })
359
+ ) {
86
360
  warn('plugin "' + plugin.name + '" 已注册,跳过重复注册');
87
361
  return;
88
362
  }
@@ -93,7 +367,8 @@ function createStoreInstance(Vue, id, options) {
93
367
  var initialState = options.state();
94
368
 
95
369
  // ====== v0.4 新增:source ======
96
- var initialSource = (typeof options.source === 'function') ? options.source() : {};
370
+ var initialSource =
371
+ typeof options.source === 'function' ? options.source() : {};
97
372
 
98
373
  var getters = options.getters || {};
99
374
  var actions = options.actions || {};
@@ -119,19 +394,19 @@ function createStoreInstance(Vue, id, options) {
119
394
  data: function () {
120
395
  return {
121
396
  $$state: initialState,
122
- $$source: initialSource, // v0.4 新增
123
- $$loading: {}, // v0.4 新增
397
+ $$source: initialSource, // v0.4 新增
398
+ $$loading: {}, // v0.4 新增
124
399
  $$status: {
125
400
  mounted: false,
126
- active: false
127
- }
401
+ active: false,
402
+ },
128
403
  };
129
404
  },
130
405
  computed: computedDefs,
131
406
  });
132
407
 
133
408
  var rawState = vm.$data.$$state;
134
- var rawSource = vm.$data.$$source; // v0.4 新增
409
+ var rawSource = vm.$data.$$source; // v0.4 新增
135
410
  var rawLoading = vm.$data.$$loading; // v0.4 新增
136
411
  var rawStatus = vm.$data.$$status;
137
412
 
@@ -140,7 +415,9 @@ function createStoreInstance(Vue, id, options) {
140
415
  Object.defineProperty(store, key, {
141
416
  enumerable: true,
142
417
  configurable: true,
143
- get: function () { return rawState[key]; },
418
+ get: function () {
419
+ return rawState[key];
420
+ },
144
421
  set: function (val) {
145
422
  if (store.$disposed) {
146
423
  warn('store "' + id + '" 已销毁,忽略对 "' + key + '" 的写入');
@@ -161,12 +438,14 @@ function createStoreInstance(Vue, id, options) {
161
438
  Object.keys(getters).forEach(function (key) {
162
439
  Object.defineProperty(store, key, {
163
440
  enumerable: true,
164
- get: function () { return vm[key]; },
441
+ get: function () {
442
+ return vm[key];
443
+ },
165
444
  });
166
445
  });
167
446
 
168
447
  // ====== actions —— v0.4 变更:自动增强 async action ======
169
- var _loadingCounts = {}; // 并发计数器,防止先返回的 finally 提前关 loading
448
+ var _loadingCounts = {}; // 并发计数器,防止先返回的 finally 提前关 loading
170
449
 
171
450
  function finishLoading(key) {
172
451
  _loadingCounts[key]--;
@@ -180,7 +459,7 @@ function createStoreInstance(Vue, id, options) {
180
459
  var originalFn = actions[key];
181
460
  var boundFn = originalFn.bind(store);
182
461
 
183
- store[key] = function () {
462
+ var withLoading = function () {
184
463
  var result = boundFn.apply(null, arguments);
185
464
 
186
465
  // 检测是否返回 Promise,如果是则自动追踪 loading
@@ -191,13 +470,20 @@ function createStoreInstance(Vue, id, options) {
191
470
 
192
471
  var tracked = Promise.resolve(result);
193
472
  tracked.then(
194
- function () { finishLoading(key); },
195
- function () { finishLoading(key); }
473
+ function () {
474
+ finishLoading(key);
475
+ },
476
+ function () {
477
+ finishLoading(key);
478
+ },
196
479
  );
197
480
  }
198
481
 
199
482
  return result;
200
483
  };
484
+
485
+ // v0.5.1:debug 包装套在 $loading 追踪外层
486
+ store[key] = wrapAction(store, key, withLoading);
201
487
  });
202
488
 
203
489
  // ====== watch —— 声明式副作用,生命周期自动回收 ======
@@ -219,14 +505,20 @@ function createStoreInstance(Vue, id, options) {
219
505
 
220
506
  if (!handler) {
221
507
  warn(
222
- 'watch "' + path + '" in store "' + id + '" 缺少 handler,该 watcher 将被跳过'
508
+ 'watch "' +
509
+ path +
510
+ '" in store "' +
511
+ id +
512
+ '" 缺少 handler,该 watcher 将被跳过',
223
513
  );
224
514
  return;
225
515
  }
226
516
  }
227
517
 
228
518
  var expr = function () {
229
- return path.split('.').reduce(function (obj, k) { return obj && obj[k]; }, store);
519
+ return path.split('.').reduce(function (obj, k) {
520
+ return obj && obj[k];
521
+ }, store);
230
522
  };
231
523
  vm.$watch(expr, handler.bind(store), watchOpts);
232
524
  });
@@ -241,7 +533,9 @@ function createStoreInstance(Vue, id, options) {
241
533
  Object.defineProperty(store, '$vm', {
242
534
  enumerable: true,
243
535
  configurable: false,
244
- get: function () { return _vm_ref; },
536
+ get: function () {
537
+ return _vm_ref;
538
+ },
245
539
  set: function () {
246
540
  warn('$vm 是只读属性,不允许业务侧重写');
247
541
  },
@@ -281,7 +575,8 @@ function createStoreInstance(Vue, id, options) {
281
575
  });
282
576
 
283
577
  // v0.4 新增:重置 source
284
- var freshSource = (typeof options.source === 'function') ? options.source() : {};
578
+ var freshSource =
579
+ typeof options.source === 'function' ? options.source() : {};
285
580
  Object.keys(freshSource).forEach(function (key) {
286
581
  Vue.set(rawSource, key, freshSource[key]);
287
582
  });
@@ -297,7 +592,10 @@ function createStoreInstance(Vue, id, options) {
297
592
 
298
593
  store.$emit = function (event, payload) {
299
594
  var fns = _listeners[event];
300
- if (fns) fns.slice().forEach(function (fn) { fn(payload); });
595
+ if (fns)
596
+ fns.slice().forEach(function (fn) {
597
+ fn(payload);
598
+ });
301
599
  };
302
600
 
303
601
  store.$on = function (event, handler) {
@@ -373,7 +671,9 @@ function createStoreInstance(Vue, id, options) {
373
671
  }
374
672
  store.$emit('page:enter');
375
673
  // v0.5: plugin enter hooks
376
- _pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
674
+ _pluginHooks.forEach(function (h) {
675
+ if (h.enter) h.enter();
676
+ });
377
677
  }
378
678
 
379
679
  function runLeave() {
@@ -387,7 +687,9 @@ function createStoreInstance(Vue, id, options) {
387
687
  }
388
688
  store.$emit('page:leave');
389
689
  // v0.5: plugin leave hooks
390
- _pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
690
+ _pluginHooks.forEach(function (h) {
691
+ if (h.leave) h.leave();
692
+ });
391
693
  }
392
694
 
393
695
  // ====== bindTo 去重标记 ======
@@ -401,7 +703,10 @@ function createStoreInstance(Vue, id, options) {
401
703
  }
402
704
 
403
705
  function addBoundVm(vm) {
404
- if (_boundVms) { _boundVms.add(vm); return; }
706
+ if (_boundVms) {
707
+ _boundVms.add(vm);
708
+ return;
709
+ }
405
710
  _boundVmsFallback.push(vm);
406
711
  }
407
712
 
@@ -466,12 +771,19 @@ function createStoreInstance(Vue, id, options) {
466
771
  clearAllIntervals();
467
772
 
468
773
  // v0.5: plugin destroy hooks
469
- _pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
774
+ _pluginHooks.forEach(function (h) {
775
+ if (h.destroy) h.destroy();
776
+ });
470
777
 
471
778
  store.$disposed = true;
472
- Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
779
+ Object.keys(_listeners).forEach(function (key) {
780
+ delete _listeners[key];
781
+ });
473
782
  vm.$destroy();
474
783
  storeRegistry.delete(id);
784
+
785
+ // v0.5.1 debug: 放在所有清理之后
786
+ emitDebugEvent(store, 'store:destroy');
475
787
  };
476
788
 
477
789
  store._vm = vm;
@@ -485,6 +797,16 @@ function createStoreInstance(Vue, id, options) {
485
797
  if (hooks) _pluginHooks.push(hooks);
486
798
  });
487
799
 
800
+ // ====== v0.5.1 debug: 注册到 devtools registry ======
801
+ var _debugId = nextId();
802
+ Object.defineProperty(store, '_debugId', {
803
+ value: _debugId,
804
+ writable: false,
805
+ enumerable: false,
806
+ configurable: false,
807
+ });
808
+ emitDebugEvent(store, 'store:create', { debugId: _debugId });
809
+
488
810
  return store;
489
811
  }
490
812
 
@@ -503,10 +825,14 @@ function createStoreInstance(Vue, id, options) {
503
825
  function definePageStore(id, options) {
504
826
  // 入参校验
505
827
  if (!id || typeof id !== 'string') {
506
- throw new Error('[vue-page-store] definePageStore 需要一个非空字符串作为 id');
828
+ throw new Error(
829
+ '[vue-page-store] definePageStore 需要一个非空字符串作为 id',
830
+ );
507
831
  }
508
832
  if (!options || typeof options.state !== 'function') {
509
- throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
833
+ throw new Error(
834
+ '[vue-page-store] definePageStore("' + id + '") 需要 state 为函数',
835
+ );
510
836
  }
511
837
 
512
838
  var _Vue = Vue;
@@ -534,7 +860,7 @@ function definePageStore(id, options) {
534
860
  var index = {
535
861
  definePageStore: definePageStore,
536
862
  registerPlugin: registerPlugin,
537
- storeRegistry: storeRegistry
863
+ storeRegistry: storeRegistry,
538
864
  };
539
865
 
540
866
  exports.default = index;