@kevisual/api 0.0.60 → 0.0.62

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.
@@ -1,5 +1,5 @@
1
1
  import { QueryLogin, QueryLoginOpts } from './query-login.ts';
2
- import { MyCache } from '@kevisual/cache';
2
+ import { MyCache } from './browser-cache/cache.ts';
3
3
  type QueryLoginNodeOptsWithoutCache = Omit<QueryLoginOpts, 'cache'>;
4
4
 
5
5
  export class QueryLoginBrowser extends QueryLogin {
@@ -3,6 +3,7 @@ import type { Result, DataOpts } from '@kevisual/query/query';
3
3
  import { LoginCacheStore, CacheStore, User } from './login-cache.ts';
4
4
  import { Cache } from './login-cache.ts';
5
5
  import { BaseLoad } from '@kevisual/load';
6
+ import { EventEmitter } from 'eventemitter3'
6
7
  export type QueryLoginOpts<T extends Cache = Cache> = {
7
8
  query?: Query;
8
9
  isBrowser?: boolean;
@@ -26,9 +27,11 @@ export class QueryLogin<T extends Cache = Cache> extends BaseQuery {
26
27
  */
27
28
  cacheStore: CacheStore<T>;
28
29
  isBrowser: boolean;
29
- load?: boolean;
30
30
  storage: Storage;
31
+ load: boolean = false;
32
+ status: 'init' | 'logining' | 'loginSuccess' | 'loginError' = 'init';
31
33
  onLoad?: () => void;
34
+ emitter = new EventEmitter();
32
35
 
33
36
  constructor(opts?: QueryLoginOpts<T>) {
34
37
  super({
@@ -42,14 +45,29 @@ export class QueryLogin<T extends Cache = Cache> extends BaseQuery {
42
45
  if (!this.storage) {
43
46
  throw new Error('storage is required');
44
47
  }
48
+ this.cacheStore.init().then(() => {
49
+ this.onLoad?.();
50
+ this.load = true;
51
+ this.emitter.emit('load');
52
+ });
45
53
  }
46
54
  setQuery(query: Query) {
47
55
  this.query = query;
48
56
  }
49
- private async init() {
50
- await this.cacheStore.init();
51
- this.load = true;
52
- this.onLoad?.();
57
+ async init() {
58
+ if (this.load) {
59
+ return this.cacheStore.cacheData;
60
+ }
61
+ return new Promise(async (resolve) => {
62
+ const timer = setTimeout(() => {
63
+ resolve(this.cacheStore.cacheData);
64
+ }, 1000 * 20); // 20秒超时,避免一直等待
65
+ const listener = () => {
66
+ clearTimeout(timer);
67
+ resolve(this.cacheStore.cacheData);
68
+ }
69
+ this.emitter.once('load', listener);
70
+ });
53
71
  }
54
72
  async post<T = any>(data: any, opts?: DataOpts) {
55
73
  try {
@@ -4,6 +4,7 @@ import { filter } from '@kevisual/js-filter'
4
4
  import { EventEmitter } from 'eventemitter3';
5
5
  import { initApi } from './router-api-proxy.ts';
6
6
  import Fuse from 'fuse.js';
7
+ import { cloneDeep } from 'es-toolkit';
7
8
 
8
9
  export const RouteTypeList = ['api', 'context', 'worker', 'page'] as const;
9
10
  export type RouterViewItemInfo = RouterViewApi | RouterViewContext | RouterViewWorker | RouteViewPage;
@@ -26,6 +27,10 @@ type RouteViewBase = {
26
27
  * 默认动作配置
27
28
  */
28
29
  action?: { path?: string; key?: string; id?: string; payload?: any;[key: string]: any };
30
+ /**
31
+ * 本地状态,loading、active、error等
32
+ */
33
+ routerStatus?: 'loading' | 'active' | 'inactive' | 'error';
29
34
  }
30
35
  export type RouterViewApi = {
31
36
  type: 'api',
@@ -67,7 +72,7 @@ export type RouterViewWorker = {
67
72
  * @returns
68
73
  */
69
74
  export const pickRouterViewData = (item: RouterViewItem) => {
70
- const { action, response, _id, ...rest } = item;
75
+ const { action, response, _id, ...rest } = cloneDeep(item);
71
76
  if (rest.type === 'api') {
72
77
  if (rest.api) {
73
78
  delete rest.api.query;
@@ -83,6 +88,7 @@ export const pickRouterViewData = (item: RouterViewItem) => {
83
88
  delete rest.context.router;
84
89
  }
85
90
  }
91
+ delete rest.routerStatus;
86
92
  return rest
87
93
  }
88
94
  /**
@@ -98,7 +104,7 @@ export type RouteViewPage = {
98
104
  export type RouterViewQuery = {
99
105
  id: string,
100
106
  query: string,
101
- title: string
107
+ title: string,
102
108
  }
103
109
  /**
104
110
  * 后端存储结构
@@ -143,6 +149,7 @@ export class QueryProxy {
143
149
  }
144
150
 
145
151
  private initRouterView(item: RouterViewItem) {
152
+ item.routerStatus = 'loading';
146
153
  if (item.type === 'api' && item.api?.url) {
147
154
  const url = item.api.url;
148
155
  if (item?.api?.query) return item;
@@ -245,10 +252,14 @@ export class QueryProxy {
245
252
  // @ts-ignore
246
253
  const context = globalThis['context'] || {}
247
254
  const router = item?.context?.router || context[item?.context?.key] as QueryRouterServer;
255
+ if (item) {
256
+ item.routerStatus = router ? 'active' : 'error';
257
+ }
248
258
  if (!router) {
249
259
  console.warn(`未发现Context router ${item?.context?.key}`);
250
260
  return
251
261
  }
262
+
252
263
  const routes = router.getList();
253
264
  // TODO: args
254
265
  // const args = fromJSONSchema(r);
@@ -308,6 +319,9 @@ export class QueryProxy {
308
319
  }
309
320
  const viewItem = item.worker;
310
321
  const worker = viewItem?.worker;
322
+ if (item) {
323
+ item.routerStatus = worker ? 'active' : 'error';
324
+ }
311
325
  if (!worker) {
312
326
  console.warn('Worker not initialized');
313
327
  return;
@@ -377,11 +391,15 @@ export class QueryProxy {
377
391
  const url = item.page.url;
378
392
  try {
379
393
  if (typeof window !== 'undefined') {
380
- await import(url).then((module) => { }).catch((err) => {
381
- console.error('引入Page脚本失败:', url, err);
382
- });
394
+ await import(url)
395
+ if (item) {
396
+ item.routerStatus = 'active';
397
+ }
383
398
  }
384
399
  } catch (e) {
400
+ if (item) {
401
+ item.routerStatus = 'error';
402
+ }
385
403
  console.warn('引入Page脚本失败:', url, e);
386
404
  return;
387
405
  }
@@ -17,12 +17,16 @@ export const initApi = async (opts: {
17
17
  const token = opts?.token;
18
18
  const query = item?.api?.query || new Query({ url: item?.api?.url || '/api/router' })
19
19
  const res = await query.post<{ list: RouterItem[] }>({ path: "router", key: 'list', token: token });
20
+ if (item) {
21
+ item.routerStatus = res?.code === 200 ? 'active' : 'error';
22
+ }
20
23
  if (res.code !== 200) {
21
24
  return {
22
25
  code: res.code,
23
26
  message: `初始化路由失败: ${res.message}, url: ${query.url}`
24
27
  }
25
28
  }
29
+
26
30
  let _list = res.data?.list || []
27
31
  if (opts?.exclude) {
28
32
  if (opts?.exclude) {