@kevisual/api 0.0.59 → 0.0.61

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.
@@ -312,6 +312,16 @@ class BaseQuery {
312
312
  }
313
313
 
314
314
  // query/query-login/login-cache.ts
315
+ var defaultCacheData = {
316
+ loginUsers: [],
317
+ user: undefined,
318
+ id: undefined,
319
+ accessToken: undefined,
320
+ refreshToken: undefined,
321
+ accessTokenExpiresIn: undefined,
322
+ createdAt: undefined
323
+ };
324
+
315
325
  class LoginCacheStore {
316
326
  cache;
317
327
  name;
@@ -321,13 +331,7 @@ class LoginCacheStore {
321
331
  throw new Error("cache is required");
322
332
  }
323
333
  this.cache = opts.cache;
324
- this.cacheData = {
325
- loginUsers: [],
326
- user: undefined,
327
- id: undefined,
328
- accessToken: undefined,
329
- refreshToken: undefined
330
- };
334
+ this.cacheData = { ...defaultCacheData };
331
335
  this.name = opts.name;
332
336
  }
333
337
  async setValue(value) {
@@ -337,27 +341,13 @@ class LoginCacheStore {
337
341
  }
338
342
  async delValue() {
339
343
  await this.cache.del();
340
- this.cacheData = {
341
- loginUsers: [],
342
- user: undefined,
343
- id: undefined,
344
- accessToken: undefined,
345
- refreshToken: undefined
346
- };
344
+ this.cacheData = { ...defaultCacheData };
347
345
  }
348
346
  getValue() {
349
347
  return this.cache.get(this.name);
350
348
  }
351
349
  async init() {
352
- const defaultData = {
353
- loginUsers: [],
354
- user: undefined,
355
- id: undefined,
356
- accessToken: undefined,
357
- refreshToken: undefined,
358
- accessTokenExpiresIn: undefined,
359
- createdAt: undefined
360
- };
350
+ const defaultData = { ...this.cacheData };
361
351
  if (this.cache.init) {
362
352
  try {
363
353
  const cacheData = await this.cache.init();
@@ -370,18 +360,18 @@ class LoginCacheStore {
370
360
  }
371
361
  return this.cacheData;
372
362
  }
373
- async setLoginUser(user) {
374
- const has = this.cacheData.loginUsers.find((u) => u.id === user.id);
363
+ async setLoginUser(loginUser) {
364
+ const has = this.cacheData.loginUsers.find((u) => u.id === loginUser.id);
375
365
  if (has) {
376
- this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
377
- }
378
- this.cacheData.loginUsers.push(user);
379
- this.cacheData.user = user.user;
380
- this.cacheData.id = user.id;
381
- this.cacheData.accessToken = user.accessToken;
382
- this.cacheData.refreshToken = user.refreshToken;
383
- this.cacheData.accessTokenExpiresIn = user.accessTokenExpiresIn;
384
- this.cacheData.createdAt = user.createdAt;
366
+ this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== loginUser.id);
367
+ }
368
+ this.cacheData.loginUsers.push(loginUser);
369
+ this.cacheData.user = loginUser.user;
370
+ this.cacheData.id = loginUser.id;
371
+ this.cacheData.accessToken = loginUser.accessToken;
372
+ this.cacheData.refreshToken = loginUser.refreshToken;
373
+ this.cacheData.accessTokenExpiresIn = loginUser.accessTokenExpiresIn;
374
+ this.cacheData.createdAt = loginUser.createdAt;
385
375
  await this.setValue(this.cacheData);
386
376
  }
387
377
  getCurrentUser() {
@@ -417,22 +407,22 @@ class LoginCacheStore {
417
407
  if (has) {
418
408
  this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
419
409
  }
420
- this.cacheData.user = undefined;
421
- this.cacheData.id = undefined;
422
- this.cacheData.accessToken = undefined;
423
- this.cacheData.refreshToken = undefined;
424
- this.cacheData.accessTokenExpiresIn = undefined;
425
- this.cacheData.createdAt = undefined;
410
+ const hasOther = this.cacheData.loginUsers.length > 0;
411
+ const current = this.cacheData.loginUsers[this.cacheData.loginUsers.length - 1];
412
+ if (hasOther && current) {
413
+ this.cacheData.user = current.user;
414
+ this.cacheData.id = current.id;
415
+ this.cacheData.accessToken = current.accessToken;
416
+ this.cacheData.refreshToken = current.refreshToken;
417
+ this.cacheData.accessTokenExpiresIn = current.accessTokenExpiresIn;
418
+ this.cacheData.createdAt = current.createdAt;
419
+ } else {
420
+ this.cacheData = { ...defaultCacheData };
421
+ }
426
422
  await this.setValue(this.cacheData);
427
423
  }
428
424
  async clearAll() {
429
- this.cacheData.loginUsers = [];
430
- this.cacheData.user = undefined;
431
- this.cacheData.id = undefined;
432
- this.cacheData.accessToken = undefined;
433
- this.cacheData.refreshToken = undefined;
434
- this.cacheData.accessTokenExpiresIn = undefined;
435
- this.cacheData.createdAt = undefined;
425
+ this.cacheData = { ...defaultCacheData };
436
426
  await this.setValue(this.cacheData);
437
427
  }
438
428
  }
@@ -1023,7 +1013,7 @@ class QueryLogin extends BaseQuery {
1023
1013
  async queryRefreshToken(opts) {
1024
1014
  const refreshToken = opts?.refreshToken;
1025
1015
  let accessToken = opts?.accessToken;
1026
- const _refreshToken = refreshToken || await this.cacheStore.getRefreshToken();
1016
+ const _refreshToken = refreshToken ?? await this.cacheStore.getRefreshToken();
1027
1017
  let data = {};
1028
1018
  if (accessToken) {
1029
1019
  data.accessToken = accessToken;
@@ -1134,6 +1124,7 @@ class QueryLogin extends BaseQuery {
1134
1124
  }
1135
1125
  const isExpired = await this.cacheStore.getIsExpired();
1136
1126
  if (isExpired) {
1127
+ console.log("token过期,正在刷新token", this.cacheStore.cacheData);
1137
1128
  const res = await this.refreshLoginUser();
1138
1129
  if (res.code === 200) {
1139
1130
  return res.data?.accessToken || null;
@@ -312,6 +312,16 @@ class BaseQuery {
312
312
  }
313
313
 
314
314
  // query/query-login/login-cache.ts
315
+ var defaultCacheData = {
316
+ loginUsers: [],
317
+ user: undefined,
318
+ id: undefined,
319
+ accessToken: undefined,
320
+ refreshToken: undefined,
321
+ accessTokenExpiresIn: undefined,
322
+ createdAt: undefined
323
+ };
324
+
315
325
  class LoginCacheStore {
316
326
  cache;
317
327
  name;
@@ -321,13 +331,7 @@ class LoginCacheStore {
321
331
  throw new Error("cache is required");
322
332
  }
323
333
  this.cache = opts.cache;
324
- this.cacheData = {
325
- loginUsers: [],
326
- user: undefined,
327
- id: undefined,
328
- accessToken: undefined,
329
- refreshToken: undefined
330
- };
334
+ this.cacheData = { ...defaultCacheData };
331
335
  this.name = opts.name;
332
336
  }
333
337
  async setValue(value) {
@@ -337,27 +341,13 @@ class LoginCacheStore {
337
341
  }
338
342
  async delValue() {
339
343
  await this.cache.del();
340
- this.cacheData = {
341
- loginUsers: [],
342
- user: undefined,
343
- id: undefined,
344
- accessToken: undefined,
345
- refreshToken: undefined
346
- };
344
+ this.cacheData = { ...defaultCacheData };
347
345
  }
348
346
  getValue() {
349
347
  return this.cache.get(this.name);
350
348
  }
351
349
  async init() {
352
- const defaultData = {
353
- loginUsers: [],
354
- user: undefined,
355
- id: undefined,
356
- accessToken: undefined,
357
- refreshToken: undefined,
358
- accessTokenExpiresIn: undefined,
359
- createdAt: undefined
360
- };
350
+ const defaultData = { ...this.cacheData };
361
351
  if (this.cache.init) {
362
352
  try {
363
353
  const cacheData = await this.cache.init();
@@ -370,18 +360,18 @@ class LoginCacheStore {
370
360
  }
371
361
  return this.cacheData;
372
362
  }
373
- async setLoginUser(user) {
374
- const has = this.cacheData.loginUsers.find((u) => u.id === user.id);
363
+ async setLoginUser(loginUser) {
364
+ const has = this.cacheData.loginUsers.find((u) => u.id === loginUser.id);
375
365
  if (has) {
376
- this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
377
- }
378
- this.cacheData.loginUsers.push(user);
379
- this.cacheData.user = user.user;
380
- this.cacheData.id = user.id;
381
- this.cacheData.accessToken = user.accessToken;
382
- this.cacheData.refreshToken = user.refreshToken;
383
- this.cacheData.accessTokenExpiresIn = user.accessTokenExpiresIn;
384
- this.cacheData.createdAt = user.createdAt;
366
+ this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== loginUser.id);
367
+ }
368
+ this.cacheData.loginUsers.push(loginUser);
369
+ this.cacheData.user = loginUser.user;
370
+ this.cacheData.id = loginUser.id;
371
+ this.cacheData.accessToken = loginUser.accessToken;
372
+ this.cacheData.refreshToken = loginUser.refreshToken;
373
+ this.cacheData.accessTokenExpiresIn = loginUser.accessTokenExpiresIn;
374
+ this.cacheData.createdAt = loginUser.createdAt;
385
375
  await this.setValue(this.cacheData);
386
376
  }
387
377
  getCurrentUser() {
@@ -417,22 +407,22 @@ class LoginCacheStore {
417
407
  if (has) {
418
408
  this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
419
409
  }
420
- this.cacheData.user = undefined;
421
- this.cacheData.id = undefined;
422
- this.cacheData.accessToken = undefined;
423
- this.cacheData.refreshToken = undefined;
424
- this.cacheData.accessTokenExpiresIn = undefined;
425
- this.cacheData.createdAt = undefined;
410
+ const hasOther = this.cacheData.loginUsers.length > 0;
411
+ const current = this.cacheData.loginUsers[this.cacheData.loginUsers.length - 1];
412
+ if (hasOther && current) {
413
+ this.cacheData.user = current.user;
414
+ this.cacheData.id = current.id;
415
+ this.cacheData.accessToken = current.accessToken;
416
+ this.cacheData.refreshToken = current.refreshToken;
417
+ this.cacheData.accessTokenExpiresIn = current.accessTokenExpiresIn;
418
+ this.cacheData.createdAt = current.createdAt;
419
+ } else {
420
+ this.cacheData = { ...defaultCacheData };
421
+ }
426
422
  await this.setValue(this.cacheData);
427
423
  }
428
424
  async clearAll() {
429
- this.cacheData.loginUsers = [];
430
- this.cacheData.user = undefined;
431
- this.cacheData.id = undefined;
432
- this.cacheData.accessToken = undefined;
433
- this.cacheData.refreshToken = undefined;
434
- this.cacheData.accessTokenExpiresIn = undefined;
435
- this.cacheData.createdAt = undefined;
425
+ this.cacheData = { ...defaultCacheData };
436
426
  await this.setValue(this.cacheData);
437
427
  }
438
428
  }
@@ -1023,7 +1013,7 @@ class QueryLogin extends BaseQuery {
1023
1013
  async queryRefreshToken(opts) {
1024
1014
  const refreshToken = opts?.refreshToken;
1025
1015
  let accessToken = opts?.accessToken;
1026
- const _refreshToken = refreshToken || await this.cacheStore.getRefreshToken();
1016
+ const _refreshToken = refreshToken ?? await this.cacheStore.getRefreshToken();
1027
1017
  let data = {};
1028
1018
  if (accessToken) {
1029
1019
  data.accessToken = accessToken;
@@ -1134,6 +1124,7 @@ class QueryLogin extends BaseQuery {
1134
1124
  }
1135
1125
  const isExpired = await this.cacheStore.getIsExpired();
1136
1126
  if (isExpired) {
1127
+ console.log("token过期,正在刷新token", this.cacheStore.cacheData);
1137
1128
  const res = await this.refreshLoginUser();
1138
1129
  if (res.code === 200) {
1139
1130
  return res.data?.accessToken || null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevisual/api",
3
- "version": "0.0.59",
3
+ "version": "0.0.61",
4
4
  "description": "",
5
5
  "main": "mod.ts",
6
6
  "scripts": {
@@ -0,0 +1,123 @@
1
+ import { createStore, UseStore, get, set, del, clear, keys, values, entries, update, setMany, getMany, delMany } from 'idb-keyval';
2
+
3
+ /**
4
+ * 缓存存储选项
5
+ */
6
+ export type CacheStoreOpts = {
7
+ /**
8
+ * 数据库名称
9
+ */
10
+ dbName?: string;
11
+ /**
12
+ * 存储空间名称
13
+ */
14
+ storeName?: string;
15
+ };
16
+ export class BaseCacheStore {
17
+ store: UseStore;
18
+ constructor(opts?: CacheStoreOpts) {
19
+ this.store = createStore(opts?.dbName || 'default-db', opts?.storeName || 'cache-store');
20
+ }
21
+ async get(key: string) {
22
+ return get(key, this.store);
23
+ }
24
+ async set(key: string, value: any) {
25
+ return set(key, value, this.store);
26
+ }
27
+ async del(key: string) {
28
+ return del(key, this.store);
29
+ }
30
+ async clear() {
31
+ return clear(this.store);
32
+ }
33
+ async keys() {
34
+ return keys(this.store);
35
+ }
36
+ async values() {
37
+ return values(this.store);
38
+ }
39
+ async entries() {
40
+ return entries(this.store);
41
+ }
42
+ async update(key: string, updater: (value: any) => any) {
43
+ return update(key, updater, this.store);
44
+ }
45
+ async setMany(entries: [string, any][]) {
46
+ return setMany(entries, this.store);
47
+ }
48
+ async getMany(keys: string[]) {
49
+ return getMany(keys, this.store);
50
+ }
51
+ async delMany(keys: string[]) {
52
+ return delMany(keys, this.store);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * 缓存存储
58
+ */
59
+ export class CacheStore extends BaseCacheStore {
60
+ constructor(opts?: CacheStoreOpts) {
61
+ super(opts);
62
+ }
63
+ async getData<T = any>(key: string) {
64
+ const data = await this.get(key);
65
+ return data.data as T;
66
+ }
67
+ async setData(key: string, data: any) {
68
+ return this.set(key, data);
69
+ }
70
+ /**
71
+ * 获取缓存数据,并检查是否过期
72
+ * @param key 缓存键
73
+ * @returns 缓存数据
74
+ */
75
+ async getCheckData<T = any>(key: string) {
76
+ const data = await this.get(key);
77
+ if (data.expireTime && data.expireTime < Date.now()) {
78
+ await super.del(key);
79
+ return null;
80
+ }
81
+ return data.data as T;
82
+ }
83
+ /**
84
+ * 设置缓存数据,并检查是否过期
85
+ * @param key 缓存键
86
+ * @param data 缓存数据
87
+ * @param opts 缓存选项
88
+ * @returns 缓存数据
89
+ */
90
+ async setCheckData(key: string, data: any, opts?: { expireTime?: number; updatedAt?: number }) {
91
+ const now = Date.now();
92
+ const expireTime = now + (opts?.expireTime || 1000 * 60 * 60 * 24 * 10);
93
+ const newData = {
94
+ data,
95
+ updatedAt: opts?.updatedAt || Date.now(),
96
+ expireTime,
97
+ };
98
+ await this.set(key, newData);
99
+ return data;
100
+ }
101
+ async checkNew(key: string, data: any): Promise<boolean> {
102
+ const existing = await this.get(key);
103
+ if (!existing) {
104
+ return true;
105
+ }
106
+ if (!data?.updatedAt) {
107
+ return false;
108
+ }
109
+ const updatedAt = new Date(data.updatedAt).getTime();
110
+ if (isNaN(updatedAt)) {
111
+ return false;
112
+ }
113
+ return updatedAt > existing.updatedAt;
114
+ }
115
+ /**
116
+ * 删除缓存数据
117
+ * @param key 缓存键
118
+ * @returns 缓存数据
119
+ */
120
+ async delCheckData(key: string) {
121
+ return this.del(key);
122
+ }
123
+ }
@@ -0,0 +1,29 @@
1
+ export { CacheStore, BaseCacheStore } from './cache-store.ts'
2
+ import { CacheStore } from './cache-store.ts'
3
+
4
+ /**
5
+ * 一个简单的缓存类,用于存储字符串。
6
+ * 对数据进行添加对比内容。
7
+ */
8
+ export class MyCache<T = any> extends CacheStore {
9
+ key: string;
10
+ constructor(opts?: { key?: string }) {
11
+ const { key, ...rest } = opts || {};
12
+ super(rest);
13
+ this.key = key || 'my-cache';
14
+ }
15
+ async getData<U = T>(key: string = this.key): Promise<U> {
16
+ return super.getCheckData<U>(key) as any;
17
+ }
18
+ /**
19
+ * 设置缓存数据,默认过期时间为10天
20
+ * @param data
21
+ * @param opts
22
+ */
23
+ async setData<U = T>(data: U, opts?: { expireTime?: number, updatedAt?: number }) {
24
+ super.setCheckData(this.key, data, opts);
25
+ }
26
+ async del(): Promise<void> {
27
+ await super.del(this.key);
28
+ }
29
+ }
@@ -90,6 +90,15 @@ export type LoginCacheStoreOpts<T extends Cache = Cache> = {
90
90
  name: string;
91
91
  cache: T;
92
92
  };
93
+ const defaultCacheData: CacheLogin = {
94
+ loginUsers: [],
95
+ user: undefined,
96
+ id: undefined,
97
+ accessToken: undefined,
98
+ refreshToken: undefined,
99
+ accessTokenExpiresIn: undefined,
100
+ createdAt: undefined,
101
+ }
93
102
  export class LoginCacheStore<T extends Cache = Cache> implements CacheStore<T> {
94
103
  cache: T;
95
104
  name: string;
@@ -100,12 +109,16 @@ export class LoginCacheStore<T extends Cache = Cache> implements CacheStore<T> {
100
109
  }
101
110
  // @ts-ignore
102
111
  this.cache = opts.cache;
103
- this.cacheData = {
104
- loginUsers: [],
105
- user: undefined,
106
- id: undefined,
107
- accessToken: undefined,
108
- refreshToken: undefined,
112
+ this.cacheData = { ...defaultCacheData };
113
+ this.name = opts.name;
114
+ }
115
+ /**
116
+ * 设置缓存
117
+ * @param key
118
+ * @param value
119
+ * @returns
120
+ accessTokenExpiresIn: undefined,
121
+ createdAt: undefined,
109
122
  };
110
123
  this.name = opts.name;
111
124
  }
@@ -125,13 +138,7 @@ export class LoginCacheStore<T extends Cache = Cache> implements CacheStore<T> {
125
138
  */
126
139
  async delValue() {
127
140
  await this.cache.del();
128
- this.cacheData = {
129
- loginUsers: [],
130
- user: undefined,
131
- id: undefined,
132
- accessToken: undefined,
133
- refreshToken: undefined,
134
- };
141
+ this.cacheData = { ...defaultCacheData };
135
142
  }
136
143
  getValue(): Promise<CacheLogin> {
137
144
  return this.cache.get(this.name);
@@ -139,44 +146,38 @@ export class LoginCacheStore<T extends Cache = Cache> implements CacheStore<T> {
139
146
  /**
140
147
  * 初始化,设置默认值
141
148
  */
142
- async init() {
143
- const defaultData: CacheLogin = {
144
- loginUsers: [],
145
- user: undefined,
146
- id: undefined,
147
- accessToken: undefined,
148
- refreshToken: undefined,
149
- accessTokenExpiresIn: undefined,
150
- createdAt: undefined,
151
- };
152
- if (this.cache.init) {
153
- try {
154
- const cacheData = await this.cache.init();
155
- this.cacheData = cacheData || defaultData;
156
- } catch (error) {
157
- console.log('cacheInit error', error);
149
+ async init(): Promise<CacheLogin> {
150
+ const defaultData: CacheLogin = { ...this.cacheData };
151
+ return new Promise(async (resolve) => {
152
+ if (this.cache.init) {
153
+ try {
154
+ const cacheData = await this.cache.init();
155
+ this.cacheData = cacheData || defaultData;
156
+ } catch (error) {
157
+ console.log('cacheInit error', error);
158
+ }
159
+ } else {
160
+ this.cacheData = (await this.getValue()) || defaultData;
158
161
  }
159
- } else {
160
- this.cacheData = (await this.getValue()) || defaultData;
161
- }
162
- return this.cacheData;
162
+ resolve(this.cacheData);
163
+ });
163
164
  }
164
165
  /**
165
166
  * 设置当前用户
166
167
  * @param user
167
168
  */
168
- async setLoginUser(user: CacheLoginUser) {
169
- const has = this.cacheData.loginUsers.find((u) => u.id === user.id);
169
+ async setLoginUser(loginUser: CacheLoginUser) {
170
+ const has = this.cacheData.loginUsers.find((u) => u.id === loginUser.id);
170
171
  if (has) {
171
- this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
172
+ this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== loginUser.id);
172
173
  }
173
- this.cacheData.loginUsers.push(user);
174
- this.cacheData.user = user.user;
175
- this.cacheData.id = user.id;
176
- this.cacheData.accessToken = user.accessToken;
177
- this.cacheData.refreshToken = user.refreshToken;
178
- this.cacheData.accessTokenExpiresIn = user.accessTokenExpiresIn;
179
- this.cacheData.createdAt = user.createdAt;
174
+ this.cacheData.loginUsers.push(loginUser);
175
+ this.cacheData.user = loginUser.user;
176
+ this.cacheData.id = loginUser.id;
177
+ this.cacheData.accessToken = loginUser.accessToken;
178
+ this.cacheData.refreshToken = loginUser.refreshToken;
179
+ this.cacheData.accessTokenExpiresIn = loginUser.accessTokenExpiresIn;
180
+ this.cacheData.createdAt = loginUser.createdAt;
180
181
  await this.setValue(this.cacheData);
181
182
  }
182
183
 
@@ -214,22 +215,22 @@ export class LoginCacheStore<T extends Cache = Cache> implements CacheStore<T> {
214
215
  if (has) {
215
216
  this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
216
217
  }
217
- this.cacheData.user = undefined;
218
- this.cacheData.id = undefined;
219
- this.cacheData.accessToken = undefined;
220
- this.cacheData.refreshToken = undefined;
221
- this.cacheData.accessTokenExpiresIn = undefined;
222
- this.cacheData.createdAt = undefined;
218
+ const hasOther = this.cacheData.loginUsers.length > 0;
219
+ const current = this.cacheData.loginUsers[this.cacheData.loginUsers.length - 1];
220
+ if (hasOther && current) {
221
+ this.cacheData.user = current.user;
222
+ this.cacheData.id = current.id;
223
+ this.cacheData.accessToken = current.accessToken;
224
+ this.cacheData.refreshToken = current.refreshToken;
225
+ this.cacheData.accessTokenExpiresIn = current.accessTokenExpiresIn;
226
+ this.cacheData.createdAt = current.createdAt;
227
+ } else {
228
+ this.cacheData = { ...defaultCacheData };
229
+ }
223
230
  await this.setValue(this.cacheData);
224
231
  }
225
232
  async clearAll() {
226
- this.cacheData.loginUsers = [];
227
- this.cacheData.user = undefined;
228
- this.cacheData.id = undefined;
229
- this.cacheData.accessToken = undefined;
230
- this.cacheData.refreshToken = undefined;
231
- this.cacheData.accessTokenExpiresIn = undefined;
232
- this.cacheData.createdAt = undefined;
233
+ this.cacheData = { ...defaultCacheData };
233
234
  await this.setValue(this.cacheData);
234
235
  }
235
236
  }
@@ -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 {
@@ -196,7 +214,7 @@ export class QueryLogin<T extends Cache = Cache> extends BaseQuery {
196
214
  async queryRefreshToken(opts?: { refreshToken?: string, accessToken?: string }) {
197
215
  const refreshToken = opts?.refreshToken;
198
216
  let accessToken = opts?.accessToken;
199
- const _refreshToken = refreshToken || (await this.cacheStore.getRefreshToken());
217
+ const _refreshToken = refreshToken ?? (await this.cacheStore.getRefreshToken());
200
218
  let data: any = {};
201
219
  if (accessToken) {
202
220
  data.accessToken = accessToken;
@@ -360,6 +378,7 @@ export class QueryLogin<T extends Cache = Cache> extends BaseQuery {
360
378
  }
361
379
  const isExpired = await this.cacheStore.getIsExpired();
362
380
  if (isExpired) {
381
+ console.log('token过期,正在刷新token', this.cacheStore.cacheData);
363
382
  const res = await this.refreshLoginUser()
364
383
  if (res.code === 200) {
365
384
  // 刷新成功,返回新的token
@@ -0,0 +1,10 @@
1
+ const cacheData = {
2
+ accessTokenExpiresIn: 604800,
3
+ createdAt: 1771926793545
4
+ };
5
+
6
+ const expiresIn = cacheData.createdAt + cacheData.accessTokenExpiresIn * 1000;
7
+ console.log('expiresIn', expiresIn);
8
+ const now = Date.now();
9
+ console.log('now', now);
10
+ console.log('isExpired', now >= expiresIn);
@@ -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) {