zova-module-a-routertabs 5.1.34 → 5.1.35

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.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { BeanInfo, BeanScopeBase, Use, deepEqual, deepExtend, prepareComponentOptions, useController } from "zova";
2
2
  import { mutate } from "mutate-on-copy";
3
+ import { defineComponent, shallowReactive } from "vue";
3
4
  import { BeanModelBase, Model } from "zova-module-a-model";
4
5
  import { Controller, Scope } from "zova-module-a-bean";
5
6
  import { BeanRouterViewBase } from "zova-module-a-router";
6
- import { defineComponent } from "vue";
7
7
  //#region src/model/tabs.ts
8
- var _dec$2, _dec2$2, _class$2;
8
+ var _dec$2;
9
+ var _dec2$2;
10
+ var _class$2;
9
11
  var ModelTabs$1 = (_dec$2 = Model({
10
12
  enableSelector: true,
11
13
  max: -1,
@@ -15,7 +17,10 @@ var ModelTabs$1 = (_dec$2 = Model({
15
17
  constructor(...args) {
16
18
  super(...args);
17
19
  this.tabsOptions = void 0;
18
- this.tabs = void 0;
20
+ this._tabsState = void 0;
21
+ this._tabsReadiness = void 0;
22
+ this._tabsDisposed = false;
23
+ this._offPersistence = void 0;
19
24
  this.componentKeyCurrent = void 0;
20
25
  this.tabKeyCurrent = void 0;
21
26
  this.tabCurrentIndex = void 0;
@@ -23,8 +28,25 @@ var ModelTabs$1 = (_dec$2 = Model({
23
28
  this.keepAliveInclude = void 0;
24
29
  this._eventSsrHmrReload = void 0;
25
30
  }
31
+ get tabs() {
32
+ if (this._tabsDisposed || this.ctx.disposed) return [];
33
+ if (!this.tabsOptions?.cache) return this._tabsState ?? [];
34
+ const readiness = this._getTabsReadiness();
35
+ if (!readiness.ready) {
36
+ this._startTabsRestore(readiness);
37
+ return [];
38
+ }
39
+ return this._tabsState;
40
+ }
41
+ set tabs(value) {
42
+ if (this._tabsDisposed || this.ctx.disposed) return;
43
+ if (this.tabsOptions.cache && !this._getTabsReadiness().ready) return;
44
+ this._tabsState = value;
45
+ }
26
46
  async __init__(scene, options) {
47
+ const ctx = this.ctx;
27
48
  await super.__init__(scene);
49
+ if (this._tabsDisposed || ctx.disposed) return;
28
50
  this.bean._setBean("$$modelTabs", this);
29
51
  this.tabsOptions = deepExtend({}, this.$onionOptions, options);
30
52
  this.tabCurrentIndex = this.$computed(() => {
@@ -44,13 +66,24 @@ var ModelTabs$1 = (_dec$2 = Model({
44
66
  this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);
45
67
  const queryOptionsTabs = {
46
68
  queryKey: ["tabs"],
47
- meta: { defaultData: this._getInitialTabs() }
69
+ meta: { defaultData: this.tabsOptions.cache ? () => this._getInitialTabs() : this._getInitialTabs() }
48
70
  };
49
- if (this.tabsOptions.cache) this.tabs = this.$useStateLocalAsync(queryOptionsTabs);
50
- else this.tabs = this.$useStateMem(queryOptionsTabs);
51
- if (this.tabsOptions.cache) await this.$ensureStateLocalAsync(this.tabs);
52
- this._resetAllPageDirty();
53
- if (this.$currentRoute) this.forwardRoute(this.$currentRoute);
71
+ if (this.tabsOptions.cache) {
72
+ this._tabsState = this.$useStateLocalAsync(queryOptionsTabs);
73
+ const persistence = this.$modelPersistence;
74
+ this._offPersistence = persistence.subscribe(() => {
75
+ if (!this._tabsDisposed && !this.ctx.disposed) this._startTabsRestore(this._getTabsReadiness());
76
+ });
77
+ while (!this._tabsDisposed && !this.ctx.disposed) {
78
+ const readiness = this._getTabsReadiness();
79
+ await this._startTabsRestore(readiness);
80
+ if (this._isTabsReadinessCurrent(readiness)) break;
81
+ }
82
+ } else {
83
+ this._tabsState = this.$useStateMem(queryOptionsTabs);
84
+ this._initializeTabs();
85
+ }
86
+ if (this._tabsDisposed || this.ctx.disposed) return;
54
87
  if (process.env.CLIENT && this.sys.config.ssr.hmr) this._eventSsrHmrReload = this.sys.meta.event.on("a-ssrhmr:reload", async (_data, next) => {
55
88
  this.updateAllTabInfos();
56
89
  return next();
@@ -62,18 +95,82 @@ var ModelTabs$1 = (_dec$2 = Model({
62
95
  });
63
96
  }
64
97
  __dispose__() {
65
- if (this._eventSsrHmrReload) this._eventSsrHmrReload();
98
+ this._tabsDisposed = true;
99
+ this._offPersistence?.();
100
+ this._tabsReadiness?.work.splice(0);
101
+ if (this._eventSsrHmrReload) {
102
+ this._eventSsrHmrReload();
103
+ this._eventSsrHmrReload = void 0;
104
+ }
105
+ }
106
+ _getTabsReadiness() {
107
+ const persistence = this.$modelPersistence;
108
+ let readiness = this._tabsReadiness;
109
+ if (!readiness || !persistence.current(readiness.token)) {
110
+ readiness?.work.splice(0);
111
+ readiness = shallowReactive({
112
+ ctx: this.ctx,
113
+ persistence,
114
+ token: persistence.capture(),
115
+ ready: false,
116
+ work: []
117
+ });
118
+ this._tabsReadiness = readiness;
119
+ }
120
+ return readiness;
121
+ }
122
+ _isTabsReadinessCurrent(readiness) {
123
+ return !this._tabsDisposed && !readiness.ctx.disposed && this._tabsReadiness === readiness && readiness.persistence.current(readiness.token);
124
+ }
125
+ _startTabsRestore(readiness) {
126
+ if (!readiness.promise) {
127
+ const state = this._tabsState;
128
+ readiness.promise = this.$ensureStateLocalAsync(state).then(() => {
129
+ if (!this._isTabsReadinessCurrent(readiness)) return;
130
+ readiness.ready = true;
131
+ this._initializeTabs();
132
+ for (const work of readiness.work.splice(0)) {
133
+ if (!this._isTabsReadinessCurrent(readiness)) break;
134
+ work();
135
+ }
136
+ });
137
+ readiness.promise.catch((error) => {
138
+ if (this._isTabsReadinessCurrent(readiness)) this.$errorHandler(error);
139
+ });
140
+ }
141
+ return readiness.promise;
142
+ }
143
+ _initializeTabs() {
144
+ this._resetAllPageDirty();
145
+ if (this.$currentRoute) this.forwardRoute(this.$currentRoute);
146
+ }
147
+ _deferTabsWork(work) {
148
+ if (this._tabsDisposed || this.ctx.disposed) return true;
149
+ if (!this.tabsOptions.cache) return false;
150
+ const readiness = this._getTabsReadiness();
151
+ if (readiness.ready) return false;
152
+ readiness.work.push(work);
153
+ this._startTabsRestore(readiness);
154
+ return true;
155
+ }
156
+ _captureTabsOperation() {
157
+ const ctx = this.ctx;
158
+ const persistence = this.$modelPersistence;
159
+ const token = persistence.capture();
160
+ return () => !this._tabsDisposed && !ctx.disposed && persistence.current(token);
66
161
  }
67
162
  get cache() {
68
163
  return this.tabsOptions.cache;
69
164
  }
70
165
  addTab(tab, affix) {
166
+ if (this._deferTabsWork(() => this.addTab(tab, affix))) return false;
71
167
  const res = this._addTab(tab, affix);
72
168
  this.tabKeyCurrent = res ? tab.tabKey : void 0;
73
169
  this.componentKeyCurrent = res ? tab.componentKey : void 0;
74
170
  return res;
75
171
  }
76
172
  _addTab(tab, affix) {
173
+ if (this._deferTabsWork(() => this._addTab(tab, affix))) return false;
77
174
  const tabKey = tab.tabKey;
78
175
  if (!tabKey) return false;
79
176
  const [index, tabOld] = this.findTab(tabKey);
@@ -106,15 +203,18 @@ var ModelTabs$1 = (_dec$2 = Model({
106
203
  return true;
107
204
  }
108
205
  resetAllTabInfos() {
206
+ if (this._deferTabsWork(() => this.resetAllTabInfos())) return;
109
207
  this.tabs = this._getInitialTabs();
110
208
  }
111
209
  updateAllTabInfos(tabInitials) {
210
+ if (this._deferTabsWork(() => this.updateAllTabInfos(tabInitials))) return;
112
211
  for (const tab of this.tabs) {
113
212
  const tabInitial = tabInitials?.find((item) => item.tabKey === tab.tabKey);
114
213
  this.updateTabInfo(tab.tabKey, tabInitial);
115
214
  }
116
215
  }
117
216
  updateTabInfo(tabKey, tabInitial) {
217
+ if (this._deferTabsWork(() => this.updateTabInfo(tabKey, tabInitial))) return;
118
218
  if (!tabKey) return;
119
219
  const [index, tabOld] = this.findTab(tabKey);
120
220
  if (index === -1) return;
@@ -127,6 +227,7 @@ var ModelTabs$1 = (_dec$2 = Model({
127
227
  this.updateTab(tabNew);
128
228
  }
129
229
  updateTabItemPageMeta(tabKey, componentKey, pageMeta) {
230
+ if (this._deferTabsWork(() => this.updateTabItemPageMeta(tabKey, componentKey, pageMeta))) return false;
130
231
  if (!tabKey || !componentKey) return false;
131
232
  const [index, tab] = this.findTab(tabKey);
132
233
  if (index === -1 || !tab) return false;
@@ -154,10 +255,16 @@ var ModelTabs$1 = (_dec$2 = Model({
154
255
  });
155
256
  return true;
156
257
  }
157
- async deleteTab(tabKey, noActiveNext) {
158
- if (!tabKey) return;
159
- const [index] = this.findTab(tabKey);
160
- if (index === -1) return;
258
+ async deleteTab(tabKey, noActiveNext, reason = "workspaceClose") {
259
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;
260
+ const current = this._captureTabsOperation();
261
+ const [index, tab] = this.findTab(tabKey);
262
+ if (index === -1 || !tab) return;
263
+ const cleanup = reason ? this.$router.notifyRouteDiscard(reason, (tab.items ?? []).map((item) => ({
264
+ fullPath: item.fullPath,
265
+ componentKey: item.componentKey,
266
+ tabKey
267
+ })), this.selector) : void 0;
161
268
  let tabKeyActiveNext;
162
269
  if (!noActiveNext && index === this.tabCurrentIndex) {
163
270
  const tabCurrentIndex = index + 1 < this.tabs.length ? index + 1 : index - 1 > -1 ? index - 1 : -1;
@@ -166,10 +273,13 @@ var ModelTabs$1 = (_dec$2 = Model({
166
273
  this.tabs = mutate(this.tabs, (copyState) => {
167
274
  copyState.splice(index, 1);
168
275
  });
276
+ await cleanup;
277
+ if (!current()) return;
169
278
  if (tabKeyActiveNext) await this.activeTab(tabKeyActiveNext);
170
279
  }
171
- async deleteTabItem(tabKey, componentKey, noActiveNext) {
172
- if (!tabKey || !componentKey) return false;
280
+ async deleteTabItem(tabKey, componentKey, noActiveNext, reason = "taskClose") {
281
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey || !componentKey) return false;
282
+ const current = this._captureTabsOperation();
173
283
  if (tabKey === componentKey) return false;
174
284
  const [index, tab] = this.findTab(tabKey);
175
285
  if (index === -1 || !tab) return false;
@@ -177,9 +287,14 @@ var ModelTabs$1 = (_dec$2 = Model({
177
287
  const indexItem = tab.items.findIndex((item) => item.componentKey === componentKey);
178
288
  if (indexItem === -1) return false;
179
289
  if (tab.items.length === 1 && !tab.affix) {
180
- await this.deleteTab(tabKey, noActiveNext);
290
+ await this.deleteTab(tabKey, noActiveNext, reason);
181
291
  return true;
182
292
  }
293
+ const cleanup = reason ? this.$router.notifyRouteDiscard(reason, [{
294
+ fullPath: tab.items[indexItem].fullPath,
295
+ componentKey,
296
+ tabKey
297
+ }], this.selector) : void 0;
183
298
  let componentKeyActiveNext;
184
299
  if (!noActiveNext && componentKey === this.componentKeyCurrent) {
185
300
  const tabItemCurrentIndex = indexItem + 1 < tab.items.length ? indexItem + 1 : indexItem - 1 > -1 ? indexItem - 1 : -1;
@@ -195,6 +310,8 @@ var ModelTabs$1 = (_dec$2 = Model({
195
310
  this.tabs = mutate(this.tabs, (copyState) => {
196
311
  copyState.splice(index, 1, tabNew);
197
312
  });
313
+ await cleanup;
314
+ if (!current()) return false;
198
315
  if (componentKeyActiveNext) await this.activeTabItem(tabKey, componentKeyActiveNext);
199
316
  return true;
200
317
  }
@@ -206,6 +323,7 @@ var ModelTabs$1 = (_dec$2 = Model({
206
323
  return [];
207
324
  }
208
325
  updateTab(tab) {
326
+ if (this._deferTabsWork(() => this.updateTab(tab))) return;
209
327
  const tabKey = tab.tabKey;
210
328
  const [index, tabOld] = this.findTab(tabKey);
211
329
  if (index === -1 || !tabOld) return;
@@ -242,7 +360,7 @@ var ModelTabs$1 = (_dec$2 = Model({
242
360
  });
243
361
  }
244
362
  async activeTab(tabKey) {
245
- if (!tabKey) return;
363
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;
246
364
  const [_, tab] = this.findTab(tabKey);
247
365
  if (!tab) return;
248
366
  const tabItemFirst = tab.items?.[0];
@@ -250,7 +368,7 @@ var ModelTabs$1 = (_dec$2 = Model({
250
368
  await this.$router.push(path);
251
369
  }
252
370
  async activeTabItem(tabKey, componentKey) {
253
- if (!tabKey || !componentKey) return;
371
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey || !componentKey) return;
254
372
  const [_, tab] = this.findTab(tabKey);
255
373
  if (!tab) return;
256
374
  const tabItem = tab.items?.find((item) => item.componentKey === componentKey);
@@ -299,6 +417,8 @@ var ModelTabs$1 = (_dec$2 = Model({
299
417
  items.unshift(anchorItem);
300
418
  }
301
419
  async pruneTabs() {
420
+ if (this._tabsDisposed || this.ctx.disposed) return;
421
+ const current = this._captureTabsOperation();
302
422
  let max = this.tabsOptions.max;
303
423
  if (max === void 0 || max === -1) return;
304
424
  if (max < 1) max = 1;
@@ -312,11 +432,13 @@ var ModelTabs$1 = (_dec$2 = Model({
312
432
  updatedAt = tab.updatedAt;
313
433
  }
314
434
  if (!tabKey) break;
315
- await this.deleteTab(tabKey, true);
435
+ await this.deleteTab(tabKey, true, false);
436
+ if (!current()) return;
316
437
  }
317
438
  }
318
439
  async pruneTabItems(tabKey) {
319
- if (!tabKey) return;
440
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;
441
+ const current = this._captureTabsOperation();
320
442
  let maxItems = this.tabsOptions.maxItems;
321
443
  if (maxItems === void 0 || maxItems === -1) return;
322
444
  if (maxItems < 1) maxItems = 1;
@@ -332,7 +454,8 @@ var ModelTabs$1 = (_dec$2 = Model({
332
454
  updatedAt = tabItem.updatedAt;
333
455
  }
334
456
  if (!componentKey) break;
335
- await this.deleteTabItem(tabKey, componentKey, true);
457
+ await this.deleteTabItem(tabKey, componentKey, true, false);
458
+ if (!current()) return;
336
459
  }
337
460
  }
338
461
  _checkIfTabNeedUpdate(tabOld, tabNew) {
@@ -374,14 +497,17 @@ var ModelTabs$1 = (_dec$2 = Model({
374
497
  });
375
498
  }
376
499
  backRoute(route) {
500
+ if (this._deferTabsWork(() => this.backRoute(route))) return;
377
501
  const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);
378
- this.deleteTabItem(tabKey, componentKey, true);
502
+ this.deleteTabItem(tabKey, componentKey, true, false);
379
503
  }
380
504
  forwardRoute(route) {
505
+ if (this._deferTabsWork(() => this.forwardRoute(route))) return;
381
506
  const routeMeta = this.prepareRouteMeta(route);
382
507
  this.addTab(routeMeta);
383
508
  }
384
509
  setPageMeta(route, pageMeta) {
510
+ if (this._deferTabsWork(() => this.setPageMeta(route, pageMeta))) return;
385
511
  const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);
386
512
  this.updateTabItemPageMeta(tabKey, componentKey, pageMeta);
387
513
  }
@@ -419,7 +545,14 @@ var ModelTabs$1 = (_dec$2 = Model({
419
545
  }) || _class$2) || _class$2);
420
546
  //#endregion
421
547
  //#region src/component/routerViewTabs/controller.tsx
422
- var _dec$1, _dec2$1, _dec3, _dec4, _class$1, _class2, _descriptor, _ControllerRouterViewTabs;
548
+ var _dec$1;
549
+ var _dec2$1;
550
+ var _dec3;
551
+ var _dec4;
552
+ var _class$1;
553
+ var _class2;
554
+ var _descriptor;
555
+ var _ControllerRouterViewTabs;
423
556
  function _initializerDefineProperty(e, i, r, l) {
424
557
  r && Object.defineProperty(e, i, {
425
558
  enumerable: r.enumerable,
@@ -474,7 +607,9 @@ var ZRouterViewTabs = defineComponent((_props) => {
474
607
  //#region src/.metadata/index.ts
475
608
  /** components: end */
476
609
  /** scope: begin */
477
- var _dec, _dec2, _class;
610
+ var _dec;
611
+ var _dec2;
612
+ var _class;
478
613
  var components = { "routerViewTabs": ZRouterViewTabs };
479
614
  var ScopeModuleARoutertabs = (_dec = Scope(), _dec2 = BeanInfo({ module: "a-routertabs" }), _dec(_class = _dec2(_class = class ScopeModuleARoutertabs extends BeanScopeBase {}) || _class) || _class);
480
615
  /** scope: end */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Use","Controller","BeanRouterViewBase","ControllerRouterViewTabs","_dec","_dec2","__z_BeanInfo","module","_dec3","injectionScope","_dec4","Reflect","metadata","ModelTabs","Object","_class","_class2","_ControllerRouterViewTabs","constructor","args","_initializerDefineProperty","_descriptor","backRoute","route","$$modelTabs","forwardRoute","setPageMeta","pageMeta","prepareRouteMeta","getKeepAliveInclude","keepAliveInclude","$propsDefault","_applyDecoratedDescriptor","prototype","configurable","enumerable","writable","initializer"],"sources":["../src/model/tabs.ts","../src/component/routerViewTabs/controller.tsx","../src/.metadata/component/routerViewTabs.ts","../src/.metadata/index.ts"],"sourcesContent":["var _dec, _dec2, _class;\nimport { \"BeanInfo\" as __z_BeanInfo } from \"zova\";\nimport { mutate } from 'mutate-on-copy';\nimport { deepEqual, deepExtend } from 'zova';\nimport { BeanModelBase, Model } from 'zova-module-a-model';\nexport let ModelTabs = (_dec = Model({\n enableSelector: true,\n max: -1,\n maxItems: -1,\n cache: false\n}), _dec2 = __z_BeanInfo({\n module: \"a-routertabs\"\n}), _dec(_class = _dec2(_class = class ModelTabs extends BeanModelBase {\n constructor(...args) {\n super(...args);\n this.tabsOptions = void 0;\n this.tabs = void 0;\n this.componentKeyCurrent = void 0;\n this.tabKeyCurrent = void 0;\n this.tabCurrentIndex = void 0;\n this.tabCurrent = void 0;\n this.keepAliveInclude = void 0;\n this._eventSsrHmrReload = void 0;\n }\n async __init__(scene, options) {\n await super.__init__(scene);\n this.bean._setBean('$$modelTabs', this);\n // options\n this.tabsOptions = deepExtend({}, this.$onionOptions, options);\n // computed\n this.tabCurrentIndex = this.$computed(() => {\n const [index] = this.findTab(this.tabKeyCurrent);\n return index;\n });\n this.tabCurrent = this.$computed(() => {\n const [, tab] = this.findTab(this.tabKeyCurrent);\n return tab;\n });\n this.keepAliveInclude = this.$computed(() => {\n return this._getKeepAliveInclude();\n });\n // componentKeyCurrent\n const queryOptionsComponentKeyCurrent = {\n queryKey: ['componentKeyCurrent']\n };\n this.componentKeyCurrent = this.$useStateMem(queryOptionsComponentKeyCurrent);\n // tabKeyCurrent\n const queryOptionsTabKeyCurrent = {\n queryKey: ['tabKeyCurrent']\n };\n this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);\n // if (this.tabsOptions.cache) {\n // this.tabKeyCurrent = this.$useStateLocalAsync(queryOptionsTabKeyCurrent);\n // } else {\n // this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);\n // }\n // tabs\n const queryOptionsTabs = {\n queryKey: ['tabs'],\n meta: {\n defaultData: this._getInitialTabs()\n }\n };\n if (this.tabsOptions.cache) {\n this.tabs = this.$useStateLocalAsync(queryOptionsTabs);\n } else {\n this.tabs = this.$useStateMem(queryOptionsTabs);\n }\n // load cache\n if (this.tabsOptions.cache) {\n // await this.$ensureStateLocalAsync(this.tabKeyCurrent);\n await this.$ensureStateLocalAsync(this.tabs);\n }\n // reset pageDirty\n this._resetAllPageDirty();\n // first route\n if (this.$currentRoute) {\n this.forwardRoute(this.$currentRoute);\n }\n // event\n if (process.env.CLIENT && this.sys.config.ssr.hmr) {\n this._eventSsrHmrReload = this.sys.meta.event.on('a-ssrhmr:reload', async (_data, next) => {\n this.updateAllTabInfos();\n return next();\n });\n }\n // locale\n this.$watch(() => {\n return this.app.meta.locale.current;\n }, () => {\n this.updateAllTabInfos();\n });\n }\n __dispose__() {\n if (this._eventSsrHmrReload) {\n this._eventSsrHmrReload();\n }\n }\n get cache() {\n return this.tabsOptions.cache;\n }\n\n // need not async\n addTab(tab, affix) {\n const res = this._addTab(tab, affix);\n // current\n this.tabKeyCurrent = res ? tab.tabKey : undefined;\n this.componentKeyCurrent = res ? tab.componentKey : undefined;\n return res;\n }\n\n // need not async\n _addTab(tab, affix) {\n const tabKey = tab.tabKey;\n if (!tabKey) return false;\n // tab\n const [index, tabOld] = this.findTab(tabKey);\n // tabInfo\n const tabInfo = this.tabsOptions.getTabInfo?.(tabKey) ?? tabOld?.info;\n if (!tabInfo) return false;\n // tabs\n if (index === -1) {\n // new\n const items = tab.componentKey ? [{\n componentKey: tab.componentKey,\n fullPath: tab.fullPath,\n keepAlive: tab.keepAlive,\n updatedAt: Date.now()\n }] : [];\n const tabNew = {\n tabKey,\n affix,\n items,\n updatedAt: Date.now(),\n info: tabInfo\n };\n const insertIndex = this._getInsertIndexForNewTab(tabNew);\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(insertIndex, 0, tabNew);\n });\n // need not await\n this.pruneTabs();\n } else {\n // update tabInfo\n if (!deepEqual(tabInfo, tabOld?.info)) {\n this.updateTabInfo(tabKey);\n }\n // update\n if (!this._checkIfTabNeedUpdate(tabOld, tab)) {\n return true;\n }\n this.updateTab(tab);\n // need not await\n this.pruneTabItems(tabKey);\n }\n return true;\n }\n resetAllTabInfos() {\n this.tabs = this._getInitialTabs();\n }\n updateAllTabInfos(tabInitials) {\n for (const tab of this.tabs) {\n const tabInitial = tabInitials?.find(item => item.tabKey === tab.tabKey);\n this.updateTabInfo(tab.tabKey, tabInitial);\n }\n }\n updateTabInfo(tabKey, tabInitial) {\n if (!tabKey) return;\n // tabs\n const [index, tabOld] = this.findTab(tabKey);\n if (index === -1) return;\n // tabInfo\n const tabInfo = this.tabsOptions.getTabInfo ? this.tabsOptions.getTabInfo(tabKey) : tabInitial?.info ?? tabOld?.info;\n if (!tabInfo) return;\n // update\n const tabNew = {\n ...tabOld,\n info: tabInfo\n };\n this.updateTab(tabNew);\n }\n updateTabItemPageMeta(tabKey, componentKey, pageMeta) {\n if (!tabKey || !componentKey) return false;\n // tab\n const [index, tab] = this.findTab(tabKey);\n if (index === -1 || !tab) return false;\n // tabItem\n if (!tab.items) return false;\n const indexItem = tab.items.findIndex(item => item.componentKey === componentKey);\n if (indexItem === -1) return false;\n const tabItem = tab.items[indexItem];\n // change tab item\n const pageMetaNew = {\n ...tabItem.pageMeta,\n ...pageMeta\n };\n const tabItemNew = {\n ...tabItem,\n pageMeta: pageMetaNew\n };\n const items = mutate(tab.items, copyState => {\n copyState.splice(indexItem, 1, tabItemNew);\n });\n const tabNew = {\n ...tab,\n items\n };\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1, tabNew);\n });\n return true;\n }\n async deleteTab(tabKey, noActiveNext) {\n if (!tabKey) return;\n // tabs\n const [index] = this.findTab(tabKey);\n if (index === -1) return;\n // active next\n let tabKeyActiveNext;\n if (!noActiveNext && index === this.tabCurrentIndex) {\n // prev/next\n const tabCurrentIndex = index + 1 < this.tabs.length ? index + 1 : index - 1 > -1 ? index - 1 : -1;\n if (tabCurrentIndex > -1) {\n tabKeyActiveNext = this.tabs[tabCurrentIndex]?.tabKey;\n }\n }\n // tabs\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1);\n });\n // active next\n if (tabKeyActiveNext) {\n await this.activeTab(tabKeyActiveNext);\n }\n }\n async deleteTabItem(tabKey, componentKey, noActiveNext) {\n if (!tabKey || !componentKey) return false;\n if (tabKey === componentKey) return false; // not delete first tabItem\n // tab\n const [index, tab] = this.findTab(tabKey);\n if (index === -1 || !tab) return false;\n // indexItem\n if (!tab.items) return false;\n const indexItem = tab.items.findIndex(item => item.componentKey === componentKey);\n if (indexItem === -1) return false;\n // deleteTab if length===1\n if (tab.items.length === 1 && !tab.affix) {\n // delete tab\n await this.deleteTab(tabKey, noActiveNext);\n return true;\n }\n // active next\n let componentKeyActiveNext;\n if (!noActiveNext && componentKey === this.componentKeyCurrent) {\n // prev/next\n const tabItemCurrentIndex = indexItem + 1 < tab.items.length ? indexItem + 1 : indexItem - 1 > -1 ? indexItem - 1 : -1;\n if (tabItemCurrentIndex > -1) {\n componentKeyActiveNext = tab.items[tabItemCurrentIndex]?.componentKey;\n }\n }\n // delete tab item\n const items = mutate(tab.items, copyState => {\n copyState.splice(indexItem, 1);\n });\n const tabNew = {\n ...tab,\n items\n };\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1, tabNew);\n });\n // active next\n if (componentKeyActiveNext) {\n await this.activeTabItem(tabKey, componentKeyActiveNext);\n }\n return true;\n }\n findTabItemByFullPath(fullPath) {\n for (const tab of this.tabs) {\n if (!tab.items) continue;\n for (const item of tab.items) {\n if (item.fullPath === fullPath) {\n return [tab.tabKey, item.componentKey];\n }\n }\n }\n return [];\n }\n updateTab(tab) {\n const tabKey = tab.tabKey;\n const [index, tabOld] = this.findTab(tabKey);\n if (index === -1 || !tabOld) return;\n const items = tabOld.items ? [].concat(tabOld.items) : [];\n if (tab.componentKey) {\n const tabItem = {\n componentKey: tab.componentKey,\n fullPath: tab.fullPath,\n keepAlive: tab.keepAlive,\n updatedAt: Date.now()\n };\n const itemIndex = this._findTabItemIndex(items, tab.componentKey);\n if (itemIndex === -1) {\n const insertIndex = this._getInsertIndexForNewTabItem(tabOld, items);\n items.splice(insertIndex, 0, tabItem);\n } else {\n const tabItemNew = {\n ...items[itemIndex],\n ...tabItem\n };\n items.splice(itemIndex, 1, tabItemNew);\n }\n this._moveAnchorItemFirst(items, tabKey);\n }\n const tabNew = {\n ...tabOld,\n ...tab,\n tabKey,\n items,\n updatedAt: Date.now()\n };\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1, tabNew);\n });\n }\n async activeTab(tabKey) {\n if (!tabKey) return;\n const [_, tab] = this.findTab(tabKey);\n if (!tab) return;\n // should not updateTab here\n // this.updateTab({ tabKey });\n // this.tabKeyCurrent = tabKey;\n // first check tab.items?.[0]?.fullPath, because fullPath maybe has query string\n const tabItemFirst = tab.items?.[0];\n const path = tabItemFirst?.componentKey === tabKey ? tabItemFirst.fullPath : tabKey;\n await this.$router.push(path);\n }\n async activeTabItem(tabKey, componentKey) {\n if (!tabKey || !componentKey) return;\n const [_, tab] = this.findTab(tabKey);\n if (!tab) return;\n const tabItem = tab.items?.find(item => item.componentKey === componentKey);\n if (!tabItem) return;\n //\n const path = tabItem.fullPath;\n await this.$router.push(path);\n }\n findTab(tabKey) {\n if (!tabKey) return [-1, undefined];\n const index = this.tabs.findIndex(item => item.tabKey === tabKey);\n if (index === -1) return [index, undefined];\n return [index, this.tabs[index]];\n }\n _getInsertIndexForNewTab(tabNew) {\n const lastAffixTabIndex = this._getLastAffixTabIndex();\n if (this.tabCurrentIndex === -1) {\n return lastAffixTabIndex + 1;\n }\n if (tabNew.affix) {\n return lastAffixTabIndex + 1;\n }\n const tabCurrent = this.tabs[this.tabCurrentIndex];\n if (tabCurrent?.affix) {\n return lastAffixTabIndex + 1;\n }\n return this.tabCurrentIndex + 1;\n }\n _getLastAffixTabIndex() {\n let lastAffixTabIndex = -1;\n for (let index = 0; index < this.tabs.length; index++) {\n if (!this.tabs[index].affix) break;\n lastAffixTabIndex = index;\n }\n return lastAffixTabIndex;\n }\n _findTabItemIndex(items, componentKey) {\n if (!componentKey) return -1;\n return items.findIndex(item => item.componentKey === componentKey);\n }\n _getCurrentTabItemIndex(tab, items) {\n if (this.tabKeyCurrent !== tab.tabKey) return -1;\n return this._findTabItemIndex(items, this.componentKeyCurrent);\n }\n _getInsertIndexForNewTabItem(tab, items) {\n const indexCurrentTabItem = this._getCurrentTabItemIndex(tab, items);\n if (indexCurrentTabItem > -1) {\n return indexCurrentTabItem + 1;\n }\n return items.length;\n }\n _moveAnchorItemFirst(items, tabKey) {\n const indexAnchor = items.findIndex(item => item.componentKey === tabKey);\n if (indexAnchor <= 0) return;\n const [anchorItem] = items.splice(indexAnchor, 1);\n items.unshift(anchorItem);\n }\n async pruneTabs() {\n let max = this.tabsOptions.max;\n if (max === undefined || max === -1) return;\n if (max < 1) max = 1;\n while (true) {\n const affixCount = this.tabs.filter(item => item.affix).length;\n if (this.tabs.length - affixCount <= max) break;\n let tabKey;\n let updatedAt = Date.now();\n for (const tab of this.tabs) {\n if (!tab.affix && tab.updatedAt < updatedAt) {\n tabKey = tab.tabKey;\n updatedAt = tab.updatedAt;\n }\n }\n if (!tabKey) break;\n await this.deleteTab(tabKey, true);\n }\n }\n async pruneTabItems(tabKey) {\n if (!tabKey) return;\n let maxItems = this.tabsOptions.maxItems;\n if (maxItems === undefined || maxItems === -1) return;\n if (maxItems < 1) maxItems = 1;\n while (true) {\n const [_, tab] = this.findTab(tabKey);\n if (!tab || !tab.items) break;\n const ignoreCount = tab.items.filter(item => item.componentKey === tabKey).length;\n if (tab.items.length - ignoreCount <= maxItems) break;\n let componentKey;\n let updatedAt = Date.now();\n for (const tabItem of tab.items) {\n if (tabItem.componentKey !== tabKey && tabItem.updatedAt < updatedAt) {\n componentKey = tabItem.componentKey;\n updatedAt = tabItem.updatedAt;\n }\n }\n if (!componentKey) break;\n await this.deleteTabItem(tabKey, componentKey, true);\n }\n }\n\n // special for _addTab\n _checkIfTabNeedUpdate(tabOld, tabNew) {\n for (const key in tabNew) {\n if (['fullPath', 'keepAlive', 'updatedAt'].includes(key)) continue;\n if (['componentKey'].includes(key)) {\n if (!tabOld.items) return true;\n const tabItemOld = tabOld.items.find(item => item[key] === tabNew[key]);\n if (!tabItemOld) return true;\n for (const key2 of ['fullPath', 'keepAlive']) {\n if (tabItemOld[key2] !== tabNew[key2]) return true;\n }\n const recentItemIndex = tabOld.items.findIndex(item => item[key] !== tabItemOld[key] && (item.updatedAt ?? 0) >= (tabItemOld.updatedAt ?? 0));\n if (recentItemIndex > -1) return true;\n } else if (tabNew[key] !== tabOld[key]) {\n return true;\n }\n }\n const recentTabIndex = this.tabs.findIndex(item => item.tabKey !== tabOld.tabKey && (item.updatedAt ?? 0) >= (tabOld.updatedAt ?? 0));\n if (recentTabIndex > -1) return true;\n return false;\n }\n _getKeepAliveInclude() {\n const include = [];\n for (const tab of this.tabs) {\n if (!tab.items) continue;\n for (const item of tab.items) {\n if (item.keepAlive !== false && item.componentKey) {\n if (!include.includes(item.componentKey)) {\n include.push(item.componentKey);\n }\n }\n }\n }\n return include;\n }\n _getInitialTabs() {\n const tabs = this.tabsOptions.getInitialTabs?.() ?? [];\n if (!this.tabsOptions.getTabInfo) return tabs;\n return tabs.map(tab => {\n return {\n ...tab,\n info: this.tabsOptions.getTabInfo?.(tab.tabKey) ?? tab.info\n };\n });\n }\n backRoute(route) {\n const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);\n this.deleteTabItem(tabKey, componentKey, true);\n }\n forwardRoute(route) {\n const routeMeta = this.prepareRouteMeta(route);\n this.addTab(routeMeta);\n }\n setPageMeta(route, pageMeta) {\n const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);\n this.updateTabItemPageMeta(tabKey, componentKey, pageMeta);\n }\n prepareRouteMeta(route) {\n // fullPath\n const fullPath = route.fullPath;\n // componentKey\n const componentKey = this.__handleRoutePropComponentKey(route);\n // tabKey\n const tabKey = this._handleRouteProp(route, 'tabKey') || componentKey;\n // keepAlive\n const keepAlive = this._handleRouteProp(route, 'keepAlive');\n // tab\n return {\n tabKey,\n componentKey,\n fullPath,\n keepAlive\n };\n }\n _handleRouteProp(route, prop) {\n let value = route.meta[prop];\n if (typeof value === 'function') {\n value = value.call(this.app, route);\n }\n return value;\n }\n __handleRoutePropComponentKey(route) {\n const componentKey = this._handleRouteProp(route, 'componentKey');\n if (componentKey) return componentKey;\n // name\n const name = this.$router.getRealRouteName(route.name);\n // path\n if (!name) return route.path;\n // name: nameOnly\n if (route.meta.componentKeyMode === 'nameOnly') return name;\n // name: withParams\n return route.path;\n }\n _resetAllPageDirty() {\n const tabItems = [];\n for (const tab of this.tabs) {\n if (!tab.items) continue;\n for (const tabItem of tab.items) {\n if (tabItem.pageMeta?.pageDirty) {\n tabItems.push([tab.tabKey, tabItem.componentKey]);\n }\n }\n }\n for (const [tabKey, componentKey] of tabItems) {\n this.updateTabItemPageMeta(tabKey, componentKey, {\n pageDirty: false\n });\n }\n }\n}) || _class) || _class);","import { RouteLocationNormalizedLoadedGeneric } from '@cabloy/vue-router';\nimport { Use } from 'zova';\nimport { Controller } from 'zova-module-a-bean';\nimport {\n BeanRouterViewBase,\n IPageMeta,\n IRouterViewPropsBase,\n IRouteViewRouteMeta,\n} from 'zova-module-a-router';\n\nimport type { ModelTabs } from '../../model/tabs.js';\n\nexport interface ControllerRouterViewTabsProps extends IRouterViewPropsBase {}\n\n@Controller()\nexport class ControllerRouterViewTabs extends BeanRouterViewBase {\n static $propsDefault = {};\n\n @Use({ injectionScope: 'skipSelf' })\n $$modelTabs: ModelTabs;\n\n public backRoute(route: RouteLocationNormalizedLoadedGeneric) {\n this.$$modelTabs.backRoute(route);\n return true;\n }\n\n public forwardRoute(route: RouteLocationNormalizedLoadedGeneric) {\n this.$$modelTabs.forwardRoute(route);\n return true;\n }\n\n public setPageMeta(route: RouteLocationNormalizedLoadedGeneric, pageMeta: IPageMeta) {\n this.$$modelTabs.setPageMeta(route, pageMeta);\n }\n\n protected prepareRouteMeta(route: RouteLocationNormalizedLoadedGeneric): IRouteViewRouteMeta {\n return this.$$modelTabs.prepareRouteMeta(route);\n }\n\n protected getKeepAliveInclude(): string[] | undefined {\n return this.$$modelTabs.keepAliveInclude;\n }\n}\n","import { defineComponent } from 'vue';\nimport { prepareComponentOptions, useController } from 'zova';\nimport { ControllerRouterViewTabs } from '../../component/routerViewTabs/controller.jsx';\nexport const ZRouterViewTabs = defineComponent(_props => {\n useController(ControllerRouterViewTabs, undefined, undefined);\n return () => {};\n}, prepareComponentOptions());","var _dec, _dec2, _class;\nimport { \"BeanInfo\" as __z_BeanInfo } from \"zova\";\n// eslint-disable\n/** model: begin */\nexport * from '../model/tabs.js';\nimport 'zova-module-a-model';\n/** model: end */\n/** model: begin */\nimport { ModelTabs } from '../model/tabs.js';\nimport 'zova';\n/** model: end */\n/** controller: begin */\nexport * from '../component/routerViewTabs/controller.jsx';\nimport 'zova';\n/** controller: end */\n/** controller: begin */\nimport { ControllerRouterViewTabs } from '../component/routerViewTabs/controller.jsx';\nimport 'zova';\n/** controller: end */\n\n/** components: begin */\nexport * from './component/routerViewTabs.js';\nimport { ZRouterViewTabs } from './component/routerViewTabs.js';\nexport const components = {\n 'routerViewTabs': ZRouterViewTabs\n};\nimport 'zova';\n/** components: end */\n/** scope: begin */\nimport { BeanScopeBase } from 'zova';\nimport { Scope } from 'zova-module-a-bean';\nexport let ScopeModuleARoutertabs = (_dec = Scope(), _dec2 = __z_BeanInfo({\n module: \"a-routertabs\"\n}), _dec(_class = _dec2(_class = class ScopeModuleARoutertabs extends BeanScopeBase {}) || _class) || _class);\nimport 'zova';\n\n/** scope: end */"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["Use","Controller","BeanRouterViewBase","ControllerRouterViewTabs","_dec","_dec2","__z_BeanInfo","module","_dec3","injectionScope","_dec4","Reflect","metadata","ModelTabs","Object","_class","_class2","_ControllerRouterViewTabs","constructor","args","_initializerDefineProperty","_descriptor","backRoute","route","$$modelTabs","forwardRoute","setPageMeta","pageMeta","prepareRouteMeta","getKeepAliveInclude","keepAliveInclude","$propsDefault","_applyDecoratedDescriptor","prototype","configurable","enumerable","writable","initializer"],"sources":["../src/model/tabs.ts","../src/component/routerViewTabs/controller.tsx","../src/.metadata/component/routerViewTabs.ts","../src/.metadata/index.ts"],"sourcesContent":["var _dec, _dec2, _class;\nimport { \"BeanInfo\" as __z_BeanInfo } from \"zova\";\nimport { mutate } from 'mutate-on-copy';\nimport { shallowReactive } from 'vue';\nimport { deepEqual, deepExtend } from 'zova';\nimport { BeanModelBase, Model } from 'zova-module-a-model';\nexport let ModelTabs = (_dec = Model({\n enableSelector: true,\n max: -1,\n maxItems: -1,\n cache: false\n}), _dec2 = __z_BeanInfo({\n module: \"a-routertabs\"\n}), _dec(_class = _dec2(_class = class ModelTabs extends BeanModelBase {\n constructor(...args) {\n super(...args);\n this.tabsOptions = void 0;\n this._tabsState = void 0;\n this._tabsReadiness = void 0;\n this._tabsDisposed = false;\n this._offPersistence = void 0;\n this.componentKeyCurrent = void 0;\n this.tabKeyCurrent = void 0;\n this.tabCurrentIndex = void 0;\n this.tabCurrent = void 0;\n this.keepAliveInclude = void 0;\n this._eventSsrHmrReload = void 0;\n }\n get tabs() {\n if (this._tabsDisposed || this.ctx.disposed) return [];\n if (!this.tabsOptions?.cache) return this._tabsState ?? [];\n const readiness = this._getTabsReadiness();\n if (!readiness.ready) {\n this._startTabsRestore(readiness);\n return [];\n }\n return this._tabsState;\n }\n set tabs(value) {\n if (this._tabsDisposed || this.ctx.disposed) return;\n // The pending array is only a projection, never a write/default for storage.\n if (this.tabsOptions.cache && !this._getTabsReadiness().ready) return;\n this._tabsState = value;\n }\n async __init__(scene, options) {\n const ctx = this.ctx;\n await super.__init__(scene);\n if (this._tabsDisposed || ctx.disposed) return;\n this.bean._setBean('$$modelTabs', this);\n // options\n this.tabsOptions = deepExtend({}, this.$onionOptions, options);\n // computed\n this.tabCurrentIndex = this.$computed(() => {\n const [index] = this.findTab(this.tabKeyCurrent);\n return index;\n });\n this.tabCurrent = this.$computed(() => {\n const [, tab] = this.findTab(this.tabKeyCurrent);\n return tab;\n });\n this.keepAliveInclude = this.$computed(() => {\n return this._getKeepAliveInclude();\n });\n // componentKeyCurrent\n const queryOptionsComponentKeyCurrent = {\n queryKey: ['componentKeyCurrent']\n };\n this.componentKeyCurrent = this.$useStateMem(queryOptionsComponentKeyCurrent);\n // tabKeyCurrent\n const queryOptionsTabKeyCurrent = {\n queryKey: ['tabKeyCurrent']\n };\n this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);\n // if (this.tabsOptions.cache) {\n // this.tabKeyCurrent = this.$useStateLocalAsync(queryOptionsTabKeyCurrent);\n // } else {\n // this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);\n // }\n // tabs\n const queryOptionsTabs = {\n queryKey: ['tabs'],\n meta: {\n // Memory query metadata is dehydrated; only DB state can retain a factory.\n defaultData: this.tabsOptions.cache ? () => this._getInitialTabs() : this._getInitialTabs()\n }\n };\n if (this.tabsOptions.cache) {\n this._tabsState = this.$useStateLocalAsync(queryOptionsTabs);\n const persistence = this.$modelPersistence;\n this._offPersistence = persistence.subscribe(() => {\n if (!this._tabsDisposed && !this.ctx.disposed) {\n this._startTabsRestore(this._getTabsReadiness());\n }\n });\n // Keep initial ordering, but do not initialize a route from an obsolete\n // restore if identity changes while the model itself is being loaded.\n while (!this._tabsDisposed && !this.ctx.disposed) {\n const readiness = this._getTabsReadiness();\n await this._startTabsRestore(readiness);\n if (this._isTabsReadinessCurrent(readiness)) break;\n }\n } else {\n this._tabsState = this.$useStateMem(queryOptionsTabs);\n this._initializeTabs();\n }\n if (this._tabsDisposed || this.ctx.disposed) return;\n // event\n if (process.env.CLIENT && this.sys.config.ssr.hmr) {\n this._eventSsrHmrReload = this.sys.meta.event.on('a-ssrhmr:reload', async (_data, next) => {\n this.updateAllTabInfos();\n return next();\n });\n }\n // locale\n this.$watch(() => {\n return this.app.meta.locale.current;\n }, () => {\n this.updateAllTabInfos();\n });\n }\n __dispose__() {\n this._tabsDisposed = true;\n this._offPersistence?.();\n this._tabsReadiness?.work.splice(0);\n if (this._eventSsrHmrReload) {\n this._eventSsrHmrReload();\n this._eventSsrHmrReload = undefined;\n }\n }\n _getTabsReadiness() {\n const persistence = this.$modelPersistence;\n let readiness = this._tabsReadiness;\n if (!readiness || !persistence.current(readiness.token)) {\n readiness?.work.splice(0);\n readiness = shallowReactive({\n ctx: this.ctx,\n persistence,\n token: persistence.capture(),\n ready: false,\n work: []\n });\n this._tabsReadiness = readiness;\n }\n return readiness;\n }\n _isTabsReadinessCurrent(readiness) {\n return !this._tabsDisposed && !readiness.ctx.disposed && this._tabsReadiness === readiness && readiness.persistence.current(readiness.token);\n }\n _startTabsRestore(readiness) {\n if (!readiness.promise) {\n // One actual backing read per epoch: repeated render/watch reads share it.\n const state = this._tabsState;\n readiness.promise = this.$ensureStateLocalAsync(state).then(() => {\n if (!this._isTabsReadinessCurrent(readiness)) return;\n readiness.ready = true;\n this._initializeTabs();\n for (const work of readiness.work.splice(0)) {\n if (!this._isTabsReadinessCurrent(readiness)) break;\n work();\n }\n });\n void readiness.promise.catch(error => {\n if (this._isTabsReadinessCurrent(readiness)) this.$errorHandler(error);\n });\n }\n return readiness.promise;\n }\n _initializeTabs() {\n this._resetAllPageDirty();\n if (this.$currentRoute) this.forwardRoute(this.$currentRoute);\n }\n _deferTabsWork(work) {\n if (this._tabsDisposed || this.ctx.disposed) return true;\n if (!this.tabsOptions.cache) return false;\n const readiness = this._getTabsReadiness();\n if (readiness.ready) return false;\n readiness.work.push(work);\n this._startTabsRestore(readiness);\n return true;\n }\n _captureTabsOperation() {\n const ctx = this.ctx;\n const persistence = this.$modelPersistence;\n const token = persistence.capture();\n return () => !this._tabsDisposed && !ctx.disposed && persistence.current(token);\n }\n get cache() {\n return this.tabsOptions.cache;\n }\n\n // need not async\n addTab(tab, affix) {\n if (this._deferTabsWork(() => this.addTab(tab, affix))) return false;\n const res = this._addTab(tab, affix);\n // current\n this.tabKeyCurrent = res ? tab.tabKey : undefined;\n this.componentKeyCurrent = res ? tab.componentKey : undefined;\n return res;\n }\n\n // need not async\n _addTab(tab, affix) {\n if (this._deferTabsWork(() => this._addTab(tab, affix))) return false;\n const tabKey = tab.tabKey;\n if (!tabKey) return false;\n // tab\n const [index, tabOld] = this.findTab(tabKey);\n // tabInfo\n const tabInfo = this.tabsOptions.getTabInfo?.(tabKey) ?? tabOld?.info;\n if (!tabInfo) return false;\n // tabs\n if (index === -1) {\n // new\n const items = tab.componentKey ? [{\n componentKey: tab.componentKey,\n fullPath: tab.fullPath,\n keepAlive: tab.keepAlive,\n updatedAt: Date.now()\n }] : [];\n const tabNew = {\n tabKey,\n affix,\n items,\n updatedAt: Date.now(),\n info: tabInfo\n };\n const insertIndex = this._getInsertIndexForNewTab(tabNew);\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(insertIndex, 0, tabNew);\n });\n // need not await\n this.pruneTabs();\n } else {\n // update tabInfo\n if (!deepEqual(tabInfo, tabOld?.info)) {\n this.updateTabInfo(tabKey);\n }\n // update\n if (!this._checkIfTabNeedUpdate(tabOld, tab)) {\n return true;\n }\n this.updateTab(tab);\n // need not await\n this.pruneTabItems(tabKey);\n }\n return true;\n }\n resetAllTabInfos() {\n if (this._deferTabsWork(() => this.resetAllTabInfos())) return;\n this.tabs = this._getInitialTabs();\n }\n updateAllTabInfos(tabInitials) {\n if (this._deferTabsWork(() => this.updateAllTabInfos(tabInitials))) return;\n for (const tab of this.tabs) {\n const tabInitial = tabInitials?.find(item => item.tabKey === tab.tabKey);\n this.updateTabInfo(tab.tabKey, tabInitial);\n }\n }\n updateTabInfo(tabKey, tabInitial) {\n if (this._deferTabsWork(() => this.updateTabInfo(tabKey, tabInitial))) return;\n if (!tabKey) return;\n // tabs\n const [index, tabOld] = this.findTab(tabKey);\n if (index === -1) return;\n // tabInfo\n const tabInfo = this.tabsOptions.getTabInfo ? this.tabsOptions.getTabInfo(tabKey) : tabInitial?.info ?? tabOld?.info;\n if (!tabInfo) return;\n // update\n const tabNew = {\n ...tabOld,\n info: tabInfo\n };\n this.updateTab(tabNew);\n }\n updateTabItemPageMeta(tabKey, componentKey, pageMeta) {\n if (this._deferTabsWork(() => this.updateTabItemPageMeta(tabKey, componentKey, pageMeta))) {\n return false;\n }\n if (!tabKey || !componentKey) return false;\n // tab\n const [index, tab] = this.findTab(tabKey);\n if (index === -1 || !tab) return false;\n // tabItem\n if (!tab.items) return false;\n const indexItem = tab.items.findIndex(item => item.componentKey === componentKey);\n if (indexItem === -1) return false;\n const tabItem = tab.items[indexItem];\n // change tab item\n const pageMetaNew = {\n ...tabItem.pageMeta,\n ...pageMeta\n };\n const tabItemNew = {\n ...tabItem,\n pageMeta: pageMetaNew\n };\n const items = mutate(tab.items, copyState => {\n copyState.splice(indexItem, 1, tabItemNew);\n });\n const tabNew = {\n ...tab,\n items\n };\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1, tabNew);\n });\n return true;\n }\n async deleteTab(tabKey, noActiveNext, reason = 'workspaceClose') {\n if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;\n const current = this._captureTabsOperation();\n // tabs\n const [index, tab] = this.findTab(tabKey);\n if (index === -1 || !tab) return;\n const cleanup = reason ? this.$router.notifyRouteDiscard(reason, (tab.items ?? []).map(item => ({\n fullPath: item.fullPath,\n componentKey: item.componentKey,\n tabKey\n })), this.selector) : undefined;\n // active next\n let tabKeyActiveNext;\n if (!noActiveNext && index === this.tabCurrentIndex) {\n // prev/next\n const tabCurrentIndex = index + 1 < this.tabs.length ? index + 1 : index - 1 > -1 ? index - 1 : -1;\n if (tabCurrentIndex > -1) {\n tabKeyActiveNext = this.tabs[tabCurrentIndex]?.tabKey;\n }\n }\n // tabs\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1);\n });\n await cleanup;\n if (!current()) return;\n // active next\n if (tabKeyActiveNext) {\n await this.activeTab(tabKeyActiveNext);\n }\n }\n async deleteTabItem(tabKey, componentKey, noActiveNext, reason = 'taskClose') {\n if (this._tabsDisposed || this.ctx.disposed || !tabKey || !componentKey) return false;\n const current = this._captureTabsOperation();\n if (tabKey === componentKey) return false; // not delete first tabItem\n // tab\n const [index, tab] = this.findTab(tabKey);\n if (index === -1 || !tab) return false;\n // indexItem\n if (!tab.items) return false;\n const indexItem = tab.items.findIndex(item => item.componentKey === componentKey);\n if (indexItem === -1) return false;\n // deleteTab if length===1\n if (tab.items.length === 1 && !tab.affix) {\n // delete tab\n await this.deleteTab(tabKey, noActiveNext, reason);\n return true;\n }\n const cleanup = reason ? this.$router.notifyRouteDiscard(reason, [{\n fullPath: tab.items[indexItem].fullPath,\n componentKey,\n tabKey\n }], this.selector) : undefined;\n // active next\n let componentKeyActiveNext;\n if (!noActiveNext && componentKey === this.componentKeyCurrent) {\n // prev/next\n const tabItemCurrentIndex = indexItem + 1 < tab.items.length ? indexItem + 1 : indexItem - 1 > -1 ? indexItem - 1 : -1;\n if (tabItemCurrentIndex > -1) {\n componentKeyActiveNext = tab.items[tabItemCurrentIndex]?.componentKey;\n }\n }\n // delete tab item\n const items = mutate(tab.items, copyState => {\n copyState.splice(indexItem, 1);\n });\n const tabNew = {\n ...tab,\n items\n };\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1, tabNew);\n });\n await cleanup;\n if (!current()) return false;\n // active next\n if (componentKeyActiveNext) {\n await this.activeTabItem(tabKey, componentKeyActiveNext);\n }\n return true;\n }\n findTabItemByFullPath(fullPath) {\n for (const tab of this.tabs) {\n if (!tab.items) continue;\n for (const item of tab.items) {\n if (item.fullPath === fullPath) {\n return [tab.tabKey, item.componentKey];\n }\n }\n }\n return [];\n }\n updateTab(tab) {\n if (this._deferTabsWork(() => this.updateTab(tab))) return;\n const tabKey = tab.tabKey;\n const [index, tabOld] = this.findTab(tabKey);\n if (index === -1 || !tabOld) return;\n const items = tabOld.items ? [].concat(tabOld.items) : [];\n if (tab.componentKey) {\n const tabItem = {\n componentKey: tab.componentKey,\n fullPath: tab.fullPath,\n keepAlive: tab.keepAlive,\n updatedAt: Date.now()\n };\n const itemIndex = this._findTabItemIndex(items, tab.componentKey);\n if (itemIndex === -1) {\n const insertIndex = this._getInsertIndexForNewTabItem(tabOld, items);\n items.splice(insertIndex, 0, tabItem);\n } else {\n const tabItemNew = {\n ...items[itemIndex],\n ...tabItem\n };\n items.splice(itemIndex, 1, tabItemNew);\n }\n this._moveAnchorItemFirst(items, tabKey);\n }\n const tabNew = {\n ...tabOld,\n ...tab,\n tabKey,\n items,\n updatedAt: Date.now()\n };\n this.tabs = mutate(this.tabs, copyState => {\n copyState.splice(index, 1, tabNew);\n });\n }\n async activeTab(tabKey) {\n if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;\n const [_, tab] = this.findTab(tabKey);\n if (!tab) return;\n // should not updateTab here\n // this.updateTab({ tabKey });\n // this.tabKeyCurrent = tabKey;\n // first check tab.items?.[0]?.fullPath, because fullPath maybe has query string\n const tabItemFirst = tab.items?.[0];\n const path = tabItemFirst?.componentKey === tabKey ? tabItemFirst.fullPath : tabKey;\n await this.$router.push(path);\n }\n async activeTabItem(tabKey, componentKey) {\n if (this._tabsDisposed || this.ctx.disposed || !tabKey || !componentKey) return;\n const [_, tab] = this.findTab(tabKey);\n if (!tab) return;\n const tabItem = tab.items?.find(item => item.componentKey === componentKey);\n if (!tabItem) return;\n //\n const path = tabItem.fullPath;\n await this.$router.push(path);\n }\n findTab(tabKey) {\n if (!tabKey) return [-1, undefined];\n const index = this.tabs.findIndex(item => item.tabKey === tabKey);\n if (index === -1) return [index, undefined];\n return [index, this.tabs[index]];\n }\n _getInsertIndexForNewTab(tabNew) {\n const lastAffixTabIndex = this._getLastAffixTabIndex();\n if (this.tabCurrentIndex === -1) {\n return lastAffixTabIndex + 1;\n }\n if (tabNew.affix) {\n return lastAffixTabIndex + 1;\n }\n const tabCurrent = this.tabs[this.tabCurrentIndex];\n if (tabCurrent?.affix) {\n return lastAffixTabIndex + 1;\n }\n return this.tabCurrentIndex + 1;\n }\n _getLastAffixTabIndex() {\n let lastAffixTabIndex = -1;\n for (let index = 0; index < this.tabs.length; index++) {\n if (!this.tabs[index].affix) break;\n lastAffixTabIndex = index;\n }\n return lastAffixTabIndex;\n }\n _findTabItemIndex(items, componentKey) {\n if (!componentKey) return -1;\n return items.findIndex(item => item.componentKey === componentKey);\n }\n _getCurrentTabItemIndex(tab, items) {\n if (this.tabKeyCurrent !== tab.tabKey) return -1;\n return this._findTabItemIndex(items, this.componentKeyCurrent);\n }\n _getInsertIndexForNewTabItem(tab, items) {\n const indexCurrentTabItem = this._getCurrentTabItemIndex(tab, items);\n if (indexCurrentTabItem > -1) {\n return indexCurrentTabItem + 1;\n }\n return items.length;\n }\n _moveAnchorItemFirst(items, tabKey) {\n const indexAnchor = items.findIndex(item => item.componentKey === tabKey);\n if (indexAnchor <= 0) return;\n const [anchorItem] = items.splice(indexAnchor, 1);\n items.unshift(anchorItem);\n }\n async pruneTabs() {\n if (this._tabsDisposed || this.ctx.disposed) return;\n const current = this._captureTabsOperation();\n let max = this.tabsOptions.max;\n if (max === undefined || max === -1) return;\n if (max < 1) max = 1;\n while (true) {\n const affixCount = this.tabs.filter(item => item.affix).length;\n if (this.tabs.length - affixCount <= max) break;\n let tabKey;\n let updatedAt = Date.now();\n for (const tab of this.tabs) {\n if (!tab.affix && tab.updatedAt < updatedAt) {\n tabKey = tab.tabKey;\n updatedAt = tab.updatedAt;\n }\n }\n if (!tabKey) break;\n await this.deleteTab(tabKey, true, false);\n if (!current()) return;\n }\n }\n async pruneTabItems(tabKey) {\n if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;\n const current = this._captureTabsOperation();\n let maxItems = this.tabsOptions.maxItems;\n if (maxItems === undefined || maxItems === -1) return;\n if (maxItems < 1) maxItems = 1;\n while (true) {\n const [_, tab] = this.findTab(tabKey);\n if (!tab || !tab.items) break;\n const ignoreCount = tab.items.filter(item => item.componentKey === tabKey).length;\n if (tab.items.length - ignoreCount <= maxItems) break;\n let componentKey;\n let updatedAt = Date.now();\n for (const tabItem of tab.items) {\n if (tabItem.componentKey !== tabKey && tabItem.updatedAt < updatedAt) {\n componentKey = tabItem.componentKey;\n updatedAt = tabItem.updatedAt;\n }\n }\n if (!componentKey) break;\n await this.deleteTabItem(tabKey, componentKey, true, false);\n if (!current()) return;\n }\n }\n\n // special for _addTab\n _checkIfTabNeedUpdate(tabOld, tabNew) {\n for (const key in tabNew) {\n if (['fullPath', 'keepAlive', 'updatedAt'].includes(key)) continue;\n if (['componentKey'].includes(key)) {\n if (!tabOld.items) return true;\n const tabItemOld = tabOld.items.find(item => item[key] === tabNew[key]);\n if (!tabItemOld) return true;\n for (const key2 of ['fullPath', 'keepAlive']) {\n if (tabItemOld[key2] !== tabNew[key2]) return true;\n }\n const recentItemIndex = tabOld.items.findIndex(item => item[key] !== tabItemOld[key] && (item.updatedAt ?? 0) >= (tabItemOld.updatedAt ?? 0));\n if (recentItemIndex > -1) return true;\n } else if (tabNew[key] !== tabOld[key]) {\n return true;\n }\n }\n const recentTabIndex = this.tabs.findIndex(item => item.tabKey !== tabOld.tabKey && (item.updatedAt ?? 0) >= (tabOld.updatedAt ?? 0));\n if (recentTabIndex > -1) return true;\n return false;\n }\n _getKeepAliveInclude() {\n const include = [];\n for (const tab of this.tabs) {\n if (!tab.items) continue;\n for (const item of tab.items) {\n if (item.keepAlive !== false && item.componentKey) {\n if (!include.includes(item.componentKey)) {\n include.push(item.componentKey);\n }\n }\n }\n }\n return include;\n }\n _getInitialTabs() {\n const tabs = this.tabsOptions.getInitialTabs?.() ?? [];\n if (!this.tabsOptions.getTabInfo) return tabs;\n return tabs.map(tab => {\n return {\n ...tab,\n info: this.tabsOptions.getTabInfo?.(tab.tabKey) ?? tab.info\n };\n });\n }\n backRoute(route) {\n if (this._deferTabsWork(() => this.backRoute(route))) return;\n const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);\n // The router emits the Back notification once; replace/pruning are not explicit discards.\n void this.deleteTabItem(tabKey, componentKey, true, false);\n }\n forwardRoute(route) {\n if (this._deferTabsWork(() => this.forwardRoute(route))) return;\n const routeMeta = this.prepareRouteMeta(route);\n this.addTab(routeMeta);\n }\n setPageMeta(route, pageMeta) {\n if (this._deferTabsWork(() => this.setPageMeta(route, pageMeta))) return;\n const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);\n this.updateTabItemPageMeta(tabKey, componentKey, pageMeta);\n }\n prepareRouteMeta(route) {\n // fullPath\n const fullPath = route.fullPath;\n // componentKey\n const componentKey = this.__handleRoutePropComponentKey(route);\n // tabKey\n const tabKey = this._handleRouteProp(route, 'tabKey') || componentKey;\n // keepAlive\n const keepAlive = this._handleRouteProp(route, 'keepAlive');\n // tab\n return {\n tabKey,\n componentKey,\n fullPath,\n keepAlive\n };\n }\n _handleRouteProp(route, prop) {\n let value = route.meta[prop];\n if (typeof value === 'function') {\n value = value.call(this.app, route);\n }\n return value;\n }\n __handleRoutePropComponentKey(route) {\n const componentKey = this._handleRouteProp(route, 'componentKey');\n if (componentKey) return componentKey;\n // name\n const name = this.$router.getRealRouteName(route.name);\n // path\n if (!name) return route.path;\n // name: nameOnly\n if (route.meta.componentKeyMode === 'nameOnly') return name;\n // name: withParams\n return route.path;\n }\n _resetAllPageDirty() {\n const tabItems = [];\n for (const tab of this.tabs) {\n if (!tab.items) continue;\n for (const tabItem of tab.items) {\n if (tabItem.pageMeta?.pageDirty) {\n tabItems.push([tab.tabKey, tabItem.componentKey]);\n }\n }\n }\n for (const [tabKey, componentKey] of tabItems) {\n this.updateTabItemPageMeta(tabKey, componentKey, {\n pageDirty: false\n });\n }\n }\n}) || _class) || _class);","import { RouteLocationNormalizedLoadedGeneric } from '@cabloy/vue-router';\nimport { Use } from 'zova';\nimport { Controller } from 'zova-module-a-bean';\nimport {\n BeanRouterViewBase,\n IPageMeta,\n IRouterViewPropsBase,\n IRouteViewRouteMeta,\n} from 'zova-module-a-router';\n\nimport type { ModelTabs } from '../../model/tabs.js';\n\nexport interface ControllerRouterViewTabsProps extends IRouterViewPropsBase {}\n\n@Controller()\nexport class ControllerRouterViewTabs extends BeanRouterViewBase {\n static $propsDefault = {};\n\n @Use({ injectionScope: 'skipSelf' })\n $$modelTabs: ModelTabs;\n\n public backRoute(route: RouteLocationNormalizedLoadedGeneric) {\n this.$$modelTabs.backRoute(route);\n return true;\n }\n\n public forwardRoute(route: RouteLocationNormalizedLoadedGeneric) {\n this.$$modelTabs.forwardRoute(route);\n return true;\n }\n\n public setPageMeta(route: RouteLocationNormalizedLoadedGeneric, pageMeta: IPageMeta) {\n this.$$modelTabs.setPageMeta(route, pageMeta);\n }\n\n protected prepareRouteMeta(route: RouteLocationNormalizedLoadedGeneric): IRouteViewRouteMeta {\n return this.$$modelTabs.prepareRouteMeta(route);\n }\n\n protected getKeepAliveInclude(): string[] | undefined {\n return this.$$modelTabs.keepAliveInclude;\n }\n}\n","import { defineComponent } from 'vue';\nimport { prepareComponentOptions, useController } from 'zova';\nimport { ControllerRouterViewTabs } from '../../component/routerViewTabs/controller.jsx';\nexport const ZRouterViewTabs = defineComponent(_props => {\n useController(ControllerRouterViewTabs, undefined, undefined);\n return () => {};\n}, prepareComponentOptions());","var _dec, _dec2, _class;\nimport { \"BeanInfo\" as __z_BeanInfo } from \"zova\";\n// eslint-disable\n/** model: begin */\nexport * from '../model/tabs.js';\nimport 'zova-module-a-model';\n/** model: end */\n/** model: begin */\nimport { ModelTabs } from '../model/tabs.js';\nimport 'zova';\n/** model: end */\n/** controller: begin */\nexport * from '../component/routerViewTabs/controller.jsx';\nimport 'zova';\n/** controller: end */\n/** controller: begin */\nimport { ControllerRouterViewTabs } from '../component/routerViewTabs/controller.jsx';\nimport 'zova';\n/** controller: end */\n\n/** components: begin */\nexport * from './component/routerViewTabs.js';\nimport { ZRouterViewTabs } from './component/routerViewTabs.js';\nexport const components = {\n 'routerViewTabs': ZRouterViewTabs\n};\nimport 'zova';\n/** components: end */\n/** scope: begin */\nimport { BeanScopeBase } from 'zova';\nimport { Scope } from 'zova-module-a-bean';\nexport let ScopeModuleARoutertabs = (_dec = Scope(), _dec2 = __z_BeanInfo({\n module: \"a-routertabs\"\n}), _dec(_class = _dec2(_class = class ScopeModuleARoutertabs extends BeanScopeBase {}) || _class) || _class);\nimport 'zova';\n\n/** scope: end */"],"mappings":"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"}
@@ -1,13 +1,18 @@
1
1
  import type { IDecoratorModelOptions } from 'zova-module-a-model';
2
2
  import { RouteLocationNormalizedLoadedGeneric } from '@cabloy/vue-router';
3
3
  import { BeanModelBase } from 'zova-module-a-model';
4
- import { IPageMeta, IRouteViewRouteMeta } from 'zova-module-a-router';
4
+ import { IPageMeta, IRouteViewRouteMeta, TypeRouteDiscardReason } from 'zova-module-a-router';
5
5
  import { ModelTabsOptions, ModelTabsOptionsBase, RouteTab, RouteTabInitial, RouteTabTransient } from '../types/tabs.js';
6
6
  export interface IModelOptionsTabs extends IDecoratorModelOptions, ModelTabsOptionsBase {
7
7
  }
8
8
  export declare class ModelTabs extends BeanModelBase {
9
9
  tabsOptions: ModelTabsOptions;
10
- tabs: RouteTab[];
10
+ private _tabsState;
11
+ private _tabsReadiness?;
12
+ private _tabsDisposed;
13
+ private _offPersistence?;
14
+ get tabs(): RouteTab[];
15
+ set tabs(value: RouteTab[]);
11
16
  componentKeyCurrent?: string;
12
17
  tabKeyCurrent?: string;
13
18
  tabCurrentIndex: number;
@@ -16,6 +21,12 @@ export declare class ModelTabs extends BeanModelBase {
16
21
  private _eventSsrHmrReload;
17
22
  protected __init__(scene: string, options?: ModelTabsOptions): Promise<void>;
18
23
  protected __dispose__(): void;
24
+ private _getTabsReadiness;
25
+ private _isTabsReadinessCurrent;
26
+ private _startTabsRestore;
27
+ private _initializeTabs;
28
+ private _deferTabsWork;
29
+ private _captureTabsOperation;
19
30
  get cache(): boolean | undefined;
20
31
  addTab(tab: RouteTabTransient, affix?: boolean): boolean;
21
32
  _addTab(tab: Partial<RouteTabTransient>, affix?: boolean): boolean;
@@ -23,8 +34,8 @@ export declare class ModelTabs extends BeanModelBase {
23
34
  updateAllTabInfos(tabInitials?: RouteTabInitial[]): void;
24
35
  updateTabInfo(tabKey?: string, tabInitial?: RouteTabInitial): void;
25
36
  updateTabItemPageMeta(tabKey?: string, componentKey?: string, pageMeta?: IPageMeta): boolean;
26
- deleteTab(tabKey?: string, noActiveNext?: boolean): Promise<void>;
27
- deleteTabItem(tabKey?: string, componentKey?: string, noActiveNext?: boolean): Promise<boolean>;
37
+ deleteTab(tabKey?: string, noActiveNext?: boolean, reason?: TypeRouteDiscardReason | false): Promise<void>;
38
+ deleteTabItem(tabKey?: string, componentKey?: string, noActiveNext?: boolean, reason?: TypeRouteDiscardReason | false): Promise<boolean>;
28
39
  findTabItemByFullPath(fullPath: string): string[];
29
40
  updateTab(tab: Partial<RouteTabTransient>): void;
30
41
  activeTab(tabKey?: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/model/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAmB,MAAM,qBAAqB,CAAC;AAEnF,OAAO,EAEL,oCAAoC,EACrC,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAS,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAuB,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3F,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,QAAQ,EACR,eAAe,EACf,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAkB,SAAQ,sBAAsB,EAAE,oBAAoB;CAAG;AAE1F,qBAMa,SAAU,SAAQ,aAAa;IAC1C,WAAW,EAAE,gBAAgB,CAAC;IAC9B,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,kBAAkB,CAAe;cAEzB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAyElE,SAAS,CAAC,WAAW;IAMrB,IAAI,KAAK,wBAER;IAGD,MAAM,CAAC,GAAG,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO;IASxD,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO;IAkDlE,gBAAgB;IAIhB,iBAAiB,CAAC,WAAW,CAAC,EAAE,eAAe,EAAE;IAOjD,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,eAAe;IAe3D,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;IAuB5E,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO;IAyBjD,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO;IAyClF,qBAAqB,CAAC,QAAQ,EAAE,MAAM;IAYtC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAoCnC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM;IAazB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;IAW1D,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAOxD,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,oBAAoB;IAOtB,SAAS;IAoBT,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM;IAwBnC,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,eAAe;IAWvB,SAAS,CAAC,KAAK,EAAE,oCAAoC;IAKrD,YAAY,CAAC,KAAK,EAAE,oCAAoC;IAKjD,WAAW,CAAC,KAAK,EAAE,oCAAoC,EAAE,QAAQ,EAAE,SAAS;IAKnF,gBAAgB,CAAC,KAAK,EAAE,oCAAoC,GAAG,mBAAmB;IAalF,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,kBAAkB;CAc3B"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/model/tabs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zova-module-a-routertabs",
3
- "version": "5.1.34",
4
- "gitHead": "eb85d771ef75776a439e56df3af8be6a3a36c1c2",
3
+ "version": "5.1.35",
4
+ "gitHead": "6293b79d977b9e40695262a5ca11cd98dfaa9241",
5
5
  "description": "routertabs",
6
6
  "keywords": [
7
7
  "Zova Module"
package/src/model/tabs.ts CHANGED
@@ -1,13 +1,24 @@
1
- import type { IDecoratorModelOptions, UseQueryOptions } from 'zova-module-a-model';
1
+ import type {
2
+ IDecoratorModelOptions,
3
+ ModelPersistenceToken,
4
+ ServiceStorage,
5
+ UseQueryOptions,
6
+ } from 'zova-module-a-model';
2
7
 
3
8
  import {
4
9
  RouteLocationNormalizedLoaded,
5
10
  RouteLocationNormalizedLoadedGeneric,
6
11
  } from '@cabloy/vue-router';
7
12
  import { mutate } from 'mutate-on-copy';
13
+ import { shallowReactive } from 'vue';
8
14
  import { deepEqual, deepExtend, TypeEventOff } from 'zova';
9
15
  import { BeanModelBase, Model } from 'zova-module-a-model';
10
- import { IPageMeta, IRouteViewRouteItem, IRouteViewRouteMeta } from 'zova-module-a-router';
16
+ import {
17
+ IPageMeta,
18
+ IRouteViewRouteItem,
19
+ IRouteViewRouteMeta,
20
+ TypeRouteDiscardReason,
21
+ } from 'zova-module-a-router';
11
22
 
12
23
  import {
13
24
  ModelTabsOptions,
@@ -19,6 +30,15 @@ import {
19
30
 
20
31
  export interface IModelOptionsTabs extends IDecoratorModelOptions, ModelTabsOptionsBase {}
21
32
 
33
+ interface TabsReadiness {
34
+ ctx: { disposed: boolean };
35
+ persistence: ServiceStorage;
36
+ token: ModelPersistenceToken;
37
+ ready: boolean;
38
+ promise?: Promise<void>;
39
+ work: (() => void)[];
40
+ }
41
+
22
42
  @Model<IModelOptionsTabs>({
23
43
  enableSelector: true,
24
44
  max: -1,
@@ -27,7 +47,29 @@ export interface IModelOptionsTabs extends IDecoratorModelOptions, ModelTabsOpti
27
47
  })
28
48
  export class ModelTabs extends BeanModelBase {
29
49
  tabsOptions: ModelTabsOptions;
30
- tabs: RouteTab[];
50
+ private _tabsState: RouteTab[];
51
+ private _tabsReadiness?: TabsReadiness;
52
+ private _tabsDisposed = false;
53
+ private _offPersistence?: () => void;
54
+
55
+ get tabs(): RouteTab[] {
56
+ if (this._tabsDisposed || this.ctx.disposed) return [];
57
+ if (!this.tabsOptions?.cache) return this._tabsState ?? [];
58
+ const readiness = this._getTabsReadiness();
59
+ if (!readiness.ready) {
60
+ this._startTabsRestore(readiness);
61
+ return [];
62
+ }
63
+ return this._tabsState;
64
+ }
65
+
66
+ set tabs(value: RouteTab[]) {
67
+ if (this._tabsDisposed || this.ctx.disposed) return;
68
+ // The pending array is only a projection, never a write/default for storage.
69
+ if (this.tabsOptions.cache && !this._getTabsReadiness().ready) return;
70
+ this._tabsState = value;
71
+ }
72
+
31
73
  componentKeyCurrent?: string;
32
74
  tabKeyCurrent?: string;
33
75
  tabCurrentIndex: number;
@@ -36,7 +78,9 @@ export class ModelTabs extends BeanModelBase {
36
78
  private _eventSsrHmrReload: TypeEventOff;
37
79
 
38
80
  protected async __init__(scene: string, options?: ModelTabsOptions) {
81
+ const ctx = this.ctx;
39
82
  await super.__init__(scene);
83
+ if (this._tabsDisposed || ctx.disposed) return;
40
84
  this.bean._setBean('$$modelTabs', this);
41
85
  // options
42
86
  this.tabsOptions = deepExtend({}, this.$onionOptions, options);
@@ -71,25 +115,30 @@ export class ModelTabs extends BeanModelBase {
71
115
  const queryOptionsTabs: UseQueryOptions<RouteTab[]> = {
72
116
  queryKey: ['tabs'],
73
117
  meta: {
74
- defaultData: this._getInitialTabs(),
118
+ // Memory query metadata is dehydrated; only DB state can retain a factory.
119
+ defaultData: this.tabsOptions.cache ? () => this._getInitialTabs() : this._getInitialTabs(),
75
120
  },
76
121
  };
77
122
  if (this.tabsOptions.cache) {
78
- this.tabs = this.$useStateLocalAsync(queryOptionsTabs);
123
+ this._tabsState = this.$useStateLocalAsync(queryOptionsTabs);
124
+ const persistence = this.$modelPersistence;
125
+ this._offPersistence = persistence.subscribe(() => {
126
+ if (!this._tabsDisposed && !this.ctx.disposed) {
127
+ this._startTabsRestore(this._getTabsReadiness());
128
+ }
129
+ });
130
+ // Keep initial ordering, but do not initialize a route from an obsolete
131
+ // restore if identity changes while the model itself is being loaded.
132
+ while (!this._tabsDisposed && !this.ctx.disposed) {
133
+ const readiness = this._getTabsReadiness();
134
+ await this._startTabsRestore(readiness);
135
+ if (this._isTabsReadinessCurrent(readiness)) break;
136
+ }
79
137
  } else {
80
- this.tabs = this.$useStateMem(queryOptionsTabs);
81
- }
82
- // load cache
83
- if (this.tabsOptions.cache) {
84
- // await this.$ensureStateLocalAsync(this.tabKeyCurrent);
85
- await this.$ensureStateLocalAsync(this.tabs);
86
- }
87
- // reset pageDirty
88
- this._resetAllPageDirty();
89
- // first route
90
- if (this.$currentRoute) {
91
- this.forwardRoute(this.$currentRoute);
138
+ this._tabsState = this.$useStateMem(queryOptionsTabs);
139
+ this._initializeTabs();
92
140
  }
141
+ if (this._tabsDisposed || this.ctx.disposed) return;
93
142
  // event
94
143
  if (process.env.CLIENT && this.sys.config.ssr.hmr) {
95
144
  this._eventSsrHmrReload = this.sys.meta.event.on('a-ssrhmr:reload', async (_data, next) => {
@@ -109,17 +158,90 @@ export class ModelTabs extends BeanModelBase {
109
158
  }
110
159
 
111
160
  protected __dispose__() {
161
+ this._tabsDisposed = true;
162
+ this._offPersistence?.();
163
+ this._tabsReadiness?.work.splice(0);
112
164
  if (this._eventSsrHmrReload) {
113
165
  this._eventSsrHmrReload();
166
+ this._eventSsrHmrReload = undefined!;
114
167
  }
115
168
  }
116
169
 
170
+ private _getTabsReadiness(): TabsReadiness {
171
+ const persistence = this.$modelPersistence;
172
+ let readiness = this._tabsReadiness;
173
+ if (!readiness || !persistence.current(readiness.token)) {
174
+ readiness?.work.splice(0);
175
+ readiness = shallowReactive({
176
+ ctx: this.ctx,
177
+ persistence,
178
+ token: persistence.capture(),
179
+ ready: false,
180
+ work: [],
181
+ });
182
+ this._tabsReadiness = readiness;
183
+ }
184
+ return readiness;
185
+ }
186
+
187
+ private _isTabsReadinessCurrent(readiness: TabsReadiness) {
188
+ return (
189
+ !this._tabsDisposed &&
190
+ !readiness.ctx.disposed &&
191
+ this._tabsReadiness === readiness &&
192
+ readiness.persistence.current(readiness.token)
193
+ );
194
+ }
195
+
196
+ private _startTabsRestore(readiness: TabsReadiness): Promise<void> {
197
+ if (!readiness.promise) {
198
+ // One actual backing read per epoch: repeated render/watch reads share it.
199
+ const state = this._tabsState;
200
+ readiness.promise = this.$ensureStateLocalAsync(state).then(() => {
201
+ if (!this._isTabsReadinessCurrent(readiness)) return;
202
+ readiness.ready = true;
203
+ this._initializeTabs();
204
+ for (const work of readiness.work.splice(0)) {
205
+ if (!this._isTabsReadinessCurrent(readiness)) break;
206
+ work();
207
+ }
208
+ });
209
+ void readiness.promise.catch(error => {
210
+ if (this._isTabsReadinessCurrent(readiness)) this.$errorHandler(error);
211
+ });
212
+ }
213
+ return readiness.promise;
214
+ }
215
+
216
+ private _initializeTabs() {
217
+ this._resetAllPageDirty();
218
+ if (this.$currentRoute) this.forwardRoute(this.$currentRoute);
219
+ }
220
+
221
+ private _deferTabsWork(work: () => void): boolean {
222
+ if (this._tabsDisposed || this.ctx.disposed) return true;
223
+ if (!this.tabsOptions.cache) return false;
224
+ const readiness = this._getTabsReadiness();
225
+ if (readiness.ready) return false;
226
+ readiness.work.push(work);
227
+ this._startTabsRestore(readiness);
228
+ return true;
229
+ }
230
+
231
+ private _captureTabsOperation() {
232
+ const ctx = this.ctx;
233
+ const persistence = this.$modelPersistence;
234
+ const token = persistence.capture();
235
+ return () => !this._tabsDisposed && !ctx.disposed && persistence.current(token);
236
+ }
237
+
117
238
  get cache() {
118
239
  return this.tabsOptions.cache;
119
240
  }
120
241
 
121
242
  // need not async
122
243
  addTab(tab: RouteTabTransient, affix?: boolean): boolean {
244
+ if (this._deferTabsWork(() => this.addTab(tab, affix))) return false;
123
245
  const res = this._addTab(tab, affix);
124
246
  // current
125
247
  this.tabKeyCurrent = res ? tab.tabKey : undefined;
@@ -129,6 +251,7 @@ export class ModelTabs extends BeanModelBase {
129
251
 
130
252
  // need not async
131
253
  _addTab(tab: Partial<RouteTabTransient>, affix?: boolean): boolean {
254
+ if (this._deferTabsWork(() => this._addTab(tab, affix))) return false;
132
255
  const tabKey = tab.tabKey;
133
256
  if (!tabKey) return false;
134
257
  // tab
@@ -179,10 +302,12 @@ export class ModelTabs extends BeanModelBase {
179
302
  }
180
303
 
181
304
  resetAllTabInfos() {
305
+ if (this._deferTabsWork(() => this.resetAllTabInfos())) return;
182
306
  this.tabs = this._getInitialTabs() as RouteTab[];
183
307
  }
184
308
 
185
309
  updateAllTabInfos(tabInitials?: RouteTabInitial[]) {
310
+ if (this._deferTabsWork(() => this.updateAllTabInfos(tabInitials))) return;
186
311
  for (const tab of this.tabs) {
187
312
  const tabInitial = tabInitials?.find(item => item.tabKey === tab.tabKey);
188
313
  this.updateTabInfo(tab.tabKey, tabInitial);
@@ -190,6 +315,7 @@ export class ModelTabs extends BeanModelBase {
190
315
  }
191
316
 
192
317
  updateTabInfo(tabKey?: string, tabInitial?: RouteTabInitial) {
318
+ if (this._deferTabsWork(() => this.updateTabInfo(tabKey, tabInitial))) return;
193
319
  if (!tabKey) return;
194
320
  // tabs
195
321
  const [index, tabOld] = this.findTab(tabKey);
@@ -205,6 +331,9 @@ export class ModelTabs extends BeanModelBase {
205
331
  }
206
332
 
207
333
  updateTabItemPageMeta(tabKey?: string, componentKey?: string, pageMeta?: IPageMeta) {
334
+ if (this._deferTabsWork(() => this.updateTabItemPageMeta(tabKey, componentKey, pageMeta))) {
335
+ return false;
336
+ }
208
337
  if (!tabKey || !componentKey) return false;
209
338
  // tab
210
339
  const [index, tab] = this.findTab(tabKey);
@@ -227,11 +356,27 @@ export class ModelTabs extends BeanModelBase {
227
356
  return true;
228
357
  }
229
358
 
230
- async deleteTab(tabKey?: string, noActiveNext?: boolean) {
231
- if (!tabKey) return;
359
+ async deleteTab(
360
+ tabKey?: string,
361
+ noActiveNext?: boolean,
362
+ reason: TypeRouteDiscardReason | false = 'workspaceClose',
363
+ ) {
364
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;
365
+ const current = this._captureTabsOperation();
232
366
  // tabs
233
- const [index] = this.findTab(tabKey);
234
- if (index === -1) return;
367
+ const [index, tab] = this.findTab(tabKey);
368
+ if (index === -1 || !tab) return;
369
+ const cleanup = reason
370
+ ? this.$router.notifyRouteDiscard(
371
+ reason,
372
+ (tab.items ?? []).map(item => ({
373
+ fullPath: item.fullPath,
374
+ componentKey: item.componentKey,
375
+ tabKey,
376
+ })),
377
+ this.selector,
378
+ )
379
+ : undefined;
235
380
  // active next
236
381
  let tabKeyActiveNext;
237
382
  if (!noActiveNext && index === this.tabCurrentIndex) {
@@ -246,14 +391,22 @@ export class ModelTabs extends BeanModelBase {
246
391
  this.tabs = mutate(this.tabs, copyState => {
247
392
  copyState.splice(index, 1);
248
393
  });
394
+ await cleanup;
395
+ if (!current()) return;
249
396
  // active next
250
397
  if (tabKeyActiveNext) {
251
398
  await this.activeTab(tabKeyActiveNext);
252
399
  }
253
400
  }
254
401
 
255
- async deleteTabItem(tabKey?: string, componentKey?: string, noActiveNext?: boolean) {
256
- if (!tabKey || !componentKey) return false;
402
+ async deleteTabItem(
403
+ tabKey?: string,
404
+ componentKey?: string,
405
+ noActiveNext?: boolean,
406
+ reason: TypeRouteDiscardReason | false = 'taskClose',
407
+ ) {
408
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey || !componentKey) return false;
409
+ const current = this._captureTabsOperation();
257
410
  if (tabKey === componentKey) return false; // not delete first tabItem
258
411
  // tab
259
412
  const [index, tab] = this.findTab(tabKey);
@@ -265,9 +418,16 @@ export class ModelTabs extends BeanModelBase {
265
418
  // deleteTab if length===1
266
419
  if (tab.items.length === 1 && !tab.affix) {
267
420
  // delete tab
268
- await this.deleteTab(tabKey, noActiveNext);
421
+ await this.deleteTab(tabKey, noActiveNext, reason);
269
422
  return true;
270
423
  }
424
+ const cleanup = reason
425
+ ? this.$router.notifyRouteDiscard(
426
+ reason,
427
+ [{ fullPath: tab.items[indexItem].fullPath, componentKey, tabKey }],
428
+ this.selector,
429
+ )
430
+ : undefined;
271
431
  // active next
272
432
  let componentKeyActiveNext;
273
433
  if (!noActiveNext && componentKey === this.componentKeyCurrent) {
@@ -286,6 +446,8 @@ export class ModelTabs extends BeanModelBase {
286
446
  this.tabs = mutate(this.tabs, copyState => {
287
447
  copyState.splice(index, 1, tabNew);
288
448
  });
449
+ await cleanup;
450
+ if (!current()) return false;
289
451
  // active next
290
452
  if (componentKeyActiveNext) {
291
453
  await this.activeTabItem(tabKey, componentKeyActiveNext);
@@ -306,6 +468,7 @@ export class ModelTabs extends BeanModelBase {
306
468
  }
307
469
 
308
470
  updateTab(tab: Partial<RouteTabTransient>) {
471
+ if (this._deferTabsWork(() => this.updateTab(tab))) return;
309
472
  const tabKey = tab.tabKey!;
310
473
  const [index, tabOld] = this.findTab(tabKey);
311
474
  if (index === -1 || !tabOld) return;
@@ -342,7 +505,7 @@ export class ModelTabs extends BeanModelBase {
342
505
  }
343
506
 
344
507
  async activeTab(tabKey?: string) {
345
- if (!tabKey) return;
508
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;
346
509
  const [_, tab] = this.findTab(tabKey);
347
510
  if (!tab) return;
348
511
  // should not updateTab here
@@ -355,7 +518,7 @@ export class ModelTabs extends BeanModelBase {
355
518
  }
356
519
 
357
520
  async activeTabItem(tabKey?: string, componentKey?: string) {
358
- if (!tabKey || !componentKey) return;
521
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey || !componentKey) return;
359
522
  const [_, tab] = this.findTab(tabKey);
360
523
  if (!tab) return;
361
524
  const tabItem = tab.items?.find(item => item.componentKey === componentKey);
@@ -422,6 +585,8 @@ export class ModelTabs extends BeanModelBase {
422
585
  }
423
586
 
424
587
  async pruneTabs() {
588
+ if (this._tabsDisposed || this.ctx.disposed) return;
589
+ const current = this._captureTabsOperation();
425
590
  let max = this.tabsOptions.max;
426
591
  if (max === undefined || max === -1) return;
427
592
  if (max < 1) max = 1;
@@ -437,12 +602,14 @@ export class ModelTabs extends BeanModelBase {
437
602
  }
438
603
  }
439
604
  if (!tabKey) break;
440
- await this.deleteTab(tabKey, true);
605
+ await this.deleteTab(tabKey, true, false);
606
+ if (!current()) return;
441
607
  }
442
608
  }
443
609
 
444
610
  async pruneTabItems(tabKey?: string) {
445
- if (!tabKey) return;
611
+ if (this._tabsDisposed || this.ctx.disposed || !tabKey) return;
612
+ const current = this._captureTabsOperation();
446
613
  let maxItems = this.tabsOptions.maxItems;
447
614
  if (maxItems === undefined || maxItems === -1) return;
448
615
  if (maxItems < 1) maxItems = 1;
@@ -460,7 +627,8 @@ export class ModelTabs extends BeanModelBase {
460
627
  }
461
628
  }
462
629
  if (!componentKey) break;
463
- await this.deleteTabItem(tabKey, componentKey, true);
630
+ await this.deleteTabItem(tabKey, componentKey, true, false);
631
+ if (!current()) return;
464
632
  }
465
633
  }
466
634
 
@@ -518,16 +686,20 @@ export class ModelTabs extends BeanModelBase {
518
686
  }
519
687
 
520
688
  backRoute(route: RouteLocationNormalizedLoadedGeneric) {
689
+ if (this._deferTabsWork(() => this.backRoute(route))) return;
521
690
  const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);
522
- this.deleteTabItem(tabKey, componentKey, true);
691
+ // The router emits the Back notification once; replace/pruning are not explicit discards.
692
+ void this.deleteTabItem(tabKey, componentKey, true, false);
523
693
  }
524
694
 
525
695
  forwardRoute(route: RouteLocationNormalizedLoadedGeneric) {
696
+ if (this._deferTabsWork(() => this.forwardRoute(route))) return;
526
697
  const routeMeta = this.prepareRouteMeta(route);
527
698
  this.addTab(routeMeta);
528
699
  }
529
700
 
530
701
  public setPageMeta(route: RouteLocationNormalizedLoadedGeneric, pageMeta: IPageMeta) {
702
+ if (this._deferTabsWork(() => this.setPageMeta(route, pageMeta))) return;
531
703
  const [tabKey, componentKey] = this.findTabItemByFullPath(route.fullPath);
532
704
  this.updateTabItemPageMeta(tabKey, componentKey, pageMeta);
533
705
  }