更改了locale的刷新策略,即使不miss也定期更新,保持i18n的正确性
This commit is contained in:
parent
ff86e9c024
commit
55177d9ce1
|
|
@ -29,11 +29,13 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
||||||
private getFullDataFn;
|
private getFullDataFn;
|
||||||
private refreshRecords;
|
private refreshRecords;
|
||||||
private context?;
|
private context?;
|
||||||
|
private initPromise;
|
||||||
constructor(storageSchema: StorageSchema<ED>, aspectWrapper: AspectWrapper<ED, Cxt, AD>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, getFullData: () => any, localStorage: LocalStorage, savedEntities?: (keyof ED)[], keepFreshPeriod?: number);
|
constructor(storageSchema: StorageSchema<ED>, aspectWrapper: AspectWrapper<ED, Cxt, AD>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, getFullData: () => any, localStorage: LocalStorage, savedEntities?: (keyof ED)[], keepFreshPeriod?: number);
|
||||||
/**
|
/**
|
||||||
* 处理cache中需要缓存的数据
|
* 处理cache中需要缓存的数据
|
||||||
*/
|
*/
|
||||||
private initSavedLogic;
|
private initSavedLogic;
|
||||||
|
onInitialized(): Promise<void>;
|
||||||
getSchema(): StorageSchema<ED>;
|
getSchema(): StorageSchema<ED>;
|
||||||
exec<K extends keyof AD>(name: K, params: Parameters<AD[K]>[0], callback?: (result: Awaited<ReturnType<AD[K]>>, opRecords?: OpRecord<ED>[]) => void, dontPublish?: true): Promise<{
|
exec<K extends keyof AD>(name: K, params: Parameters<AD[K]>[0], callback?: (result: Awaited<ReturnType<AD[K]>>, opRecords?: OpRecord<ED>[]) => void, dontPublish?: true): Promise<{
|
||||||
result: Awaited<ReturnType<AD[K]>>;
|
result: Awaited<ReturnType<AD[K]>>;
|
||||||
|
|
@ -41,6 +43,17 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
||||||
}>;
|
}>;
|
||||||
private saveRefreshRecord;
|
private saveRefreshRecord;
|
||||||
private addRefreshRecord;
|
private addRefreshRecord;
|
||||||
|
/**
|
||||||
|
* 向服务器刷新数据
|
||||||
|
* @param entity
|
||||||
|
* @param selection
|
||||||
|
* @param option
|
||||||
|
* @param callback
|
||||||
|
* @param refreshOption
|
||||||
|
* @returns
|
||||||
|
* @description 支持增量更新,可以使用useLocalCache来将一些metadata级的数据本地缓存,减少更新次数。
|
||||||
|
* 使用增量更新这里要注意,传入的keys如果有一个key是首次更新,会导致所有的keys全部更新。使用模块自己保证这种情况不要出现
|
||||||
|
*/
|
||||||
refresh<T extends keyof ED, OP extends CacheSelectOption>(entity: T, selection: ED[T]['Selection'], option?: OP, callback?: (result: Awaited<ReturnType<AD['select']>>) => void, refreshOption?: RefreshOption): Promise<{
|
refresh<T extends keyof ED, OP extends CacheSelectOption>(entity: T, selection: ED[T]['Selection'], option?: OP, callback?: (result: Awaited<ReturnType<AD['select']>>) => void, refreshOption?: RefreshOption): Promise<{
|
||||||
data: Partial<ED[T]["Schema"]>[];
|
data: Partial<ED[T]["Schema"]>[];
|
||||||
total?: undefined;
|
total?: undefined;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export class Cache extends Feature {
|
||||||
getFullDataFn;
|
getFullDataFn;
|
||||||
refreshRecords = {};
|
refreshRecords = {};
|
||||||
context;
|
context;
|
||||||
|
initPromise;
|
||||||
constructor(storageSchema, aspectWrapper, frontendContextBuilder, checkers, getFullData, localStorage, savedEntities, keepFreshPeriod) {
|
constructor(storageSchema, aspectWrapper, frontendContextBuilder, checkers, getFullData, localStorage, savedEntities, keepFreshPeriod) {
|
||||||
super();
|
super();
|
||||||
this.aspectWrapper = aspectWrapper;
|
this.aspectWrapper = aspectWrapper;
|
||||||
|
|
@ -31,12 +32,12 @@ export class Cache extends Feature {
|
||||||
checkers.forEach((checker) => this.cacheStore.registerChecker(checker));
|
checkers.forEach((checker) => this.cacheStore.registerChecker(checker));
|
||||||
this.getFullDataFn = getFullData;
|
this.getFullDataFn = getFullData;
|
||||||
// 现在这个init变成了异步行为,不知道有没有影响。by Xc 20231126
|
// 现在这个init变成了异步行为,不知道有没有影响。by Xc 20231126
|
||||||
this.initSavedLogic();
|
this.initPromise = new Promise((resolve) => this.initSavedLogic(resolve));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 处理cache中需要缓存的数据
|
* 处理cache中需要缓存的数据
|
||||||
*/
|
*/
|
||||||
async initSavedLogic() {
|
async initSavedLogic(complete) {
|
||||||
const data = {};
|
const data = {};
|
||||||
await Promise.all(this.savedEntities.map(async (entity) => {
|
await Promise.all(this.savedEntities.map(async (entity) => {
|
||||||
// 加载缓存的数据项
|
// 加载缓存的数据项
|
||||||
|
|
@ -64,6 +65,10 @@ export class Cache extends Feature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
async onInitialized() {
|
||||||
|
await this.initPromise;
|
||||||
}
|
}
|
||||||
getSchema() {
|
getSchema() {
|
||||||
return this.cacheStore.getSchema();
|
return this.cacheStore.getSchema();
|
||||||
|
|
@ -127,6 +132,17 @@ export class Cache extends Feature {
|
||||||
}
|
}
|
||||||
return () => undefined;
|
return () => undefined;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 向服务器刷新数据
|
||||||
|
* @param entity
|
||||||
|
* @param selection
|
||||||
|
* @param option
|
||||||
|
* @param callback
|
||||||
|
* @param refreshOption
|
||||||
|
* @returns
|
||||||
|
* @description 支持增量更新,可以使用useLocalCache来将一些metadata级的数据本地缓存,减少更新次数。
|
||||||
|
* 使用增量更新这里要注意,传入的keys如果有一个key是首次更新,会导致所有的keys全部更新。使用模块自己保证这种情况不要出现
|
||||||
|
*/
|
||||||
async refresh(entity, selection, option, callback, refreshOption) {
|
async refresh(entity, selection, option, callback, refreshOption) {
|
||||||
// todo 还要判定没有aggregation
|
// todo 还要判定没有aggregation
|
||||||
const { dontPublish, useLocalCache } = refreshOption || {};
|
const { dontPublish, useLocalCache } = refreshOption || {};
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ export declare class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends
|
||||||
private initializeLng;
|
private initializeLng;
|
||||||
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, localStorage: LocalStorage, environment: Environment, defaultLng: string, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string);
|
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, localStorage: LocalStorage, environment: Environment, defaultLng: string, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string);
|
||||||
private detectLanguange;
|
private detectLanguange;
|
||||||
private resetDataset;
|
private reloadDataset;
|
||||||
|
private loadServerData;
|
||||||
/**
|
/**
|
||||||
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
||||||
* @param ns
|
* @param ns
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export class Locales extends Feature {
|
||||||
defaultLocale: defaultLng,
|
defaultLocale: defaultLng,
|
||||||
locale: this.language,
|
locale: this.language,
|
||||||
});
|
});
|
||||||
this.resetDataset();
|
this.reloadDataset();
|
||||||
// i18n miss的默认策略
|
// i18n miss的默认策略
|
||||||
this.i18n.missingBehavior = 'loadData';
|
this.i18n.missingBehavior = 'loadData';
|
||||||
this.i18n.missingTranslation.register("loadData", (i18n, scope, options) => {
|
this.i18n.missingTranslation.register("loadData", (i18n, scope, options) => {
|
||||||
|
|
@ -53,7 +53,8 @@ export class Locales extends Feature {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
await this.localStorage.save(LOCAL_STORAGE_KEYS.localeLng, language);
|
await this.localStorage.save(LOCAL_STORAGE_KEYS.localeLng, language);
|
||||||
}
|
}
|
||||||
resetDataset() {
|
async reloadDataset() {
|
||||||
|
await this.cache.onInitialized();
|
||||||
const i18ns = this.cache.get('i18n', {
|
const i18ns = this.cache.get('i18n', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -74,14 +75,13 @@ export class Locales extends Feature {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.i18n.store(dataset);
|
this.i18n.store(dataset);
|
||||||
|
if (i18ns.length > 0) {
|
||||||
|
// 启动时刷新数据策略
|
||||||
|
const nss = i18ns.map(ele => ele.namespace);
|
||||||
|
await this.loadServerData(nss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
async loadServerData(nss) {
|
||||||
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
|
||||||
* @param ns
|
|
||||||
*/
|
|
||||||
async loadData(key) {
|
|
||||||
assert(typeof key === 'string');
|
|
||||||
const [ns] = key.split('.');
|
|
||||||
const { data: newI18ns } = await this.cache.refresh('i18n', {
|
const { data: newI18ns } = await this.cache.refresh('i18n', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -92,13 +92,15 @@ export class Locales extends Feature {
|
||||||
$$updateAt$$: 1,
|
$$updateAt$$: 1,
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
namespace: ns,
|
namespace: {
|
||||||
}
|
$in: nss,
|
||||||
|
},
|
||||||
|
},
|
||||||
}, undefined, undefined, {
|
}, undefined, undefined, {
|
||||||
dontPublish: true,
|
dontPublish: true,
|
||||||
useLocalCache: {
|
useLocalCache: {
|
||||||
keys: [ns],
|
keys: nss,
|
||||||
gap: process.env.NODE_ENV === 'development' ? 60 * 1000 : 1200 * 1000,
|
gap: process.env.NODE_ENV === 'development' ? 10 * 1000 : 3600 * 1000,
|
||||||
onlyReturnFresh: true,
|
onlyReturnFresh: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -117,6 +119,15 @@ export class Locales extends Feature {
|
||||||
this.i18n.store(dataset);
|
this.i18n.store(dataset);
|
||||||
this.publish();
|
this.publish();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
||||||
|
* @param ns
|
||||||
|
*/
|
||||||
|
async loadData(key) {
|
||||||
|
assert(typeof key === 'string');
|
||||||
|
const [ns] = key.split('.');
|
||||||
|
await this.loadServerData([key]);
|
||||||
if (!this.hasKey(key)) {
|
if (!this.hasKey(key)) {
|
||||||
console.warn(`命名空间${ns}中的${key}缺失且可能请求不到更新的数据`);
|
console.warn(`命名空间${ns}中的${key}缺失且可能请求不到更新的数据`);
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,13 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
||||||
private getFullDataFn;
|
private getFullDataFn;
|
||||||
private refreshRecords;
|
private refreshRecords;
|
||||||
private context?;
|
private context?;
|
||||||
|
private initPromise;
|
||||||
constructor(storageSchema: StorageSchema<ED>, aspectWrapper: AspectWrapper<ED, Cxt, AD>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, getFullData: () => any, localStorage: LocalStorage, savedEntities?: (keyof ED)[], keepFreshPeriod?: number);
|
constructor(storageSchema: StorageSchema<ED>, aspectWrapper: AspectWrapper<ED, Cxt, AD>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, getFullData: () => any, localStorage: LocalStorage, savedEntities?: (keyof ED)[], keepFreshPeriod?: number);
|
||||||
/**
|
/**
|
||||||
* 处理cache中需要缓存的数据
|
* 处理cache中需要缓存的数据
|
||||||
*/
|
*/
|
||||||
private initSavedLogic;
|
private initSavedLogic;
|
||||||
|
onInitialized(): Promise<void>;
|
||||||
getSchema(): StorageSchema<ED>;
|
getSchema(): StorageSchema<ED>;
|
||||||
exec<K extends keyof AD>(name: K, params: Parameters<AD[K]>[0], callback?: (result: Awaited<ReturnType<AD[K]>>, opRecords?: OpRecord<ED>[]) => void, dontPublish?: true): Promise<{
|
exec<K extends keyof AD>(name: K, params: Parameters<AD[K]>[0], callback?: (result: Awaited<ReturnType<AD[K]>>, opRecords?: OpRecord<ED>[]) => void, dontPublish?: true): Promise<{
|
||||||
result: Awaited<ReturnType<AD[K]>>;
|
result: Awaited<ReturnType<AD[K]>>;
|
||||||
|
|
@ -41,6 +43,17 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
||||||
}>;
|
}>;
|
||||||
private saveRefreshRecord;
|
private saveRefreshRecord;
|
||||||
private addRefreshRecord;
|
private addRefreshRecord;
|
||||||
|
/**
|
||||||
|
* 向服务器刷新数据
|
||||||
|
* @param entity
|
||||||
|
* @param selection
|
||||||
|
* @param option
|
||||||
|
* @param callback
|
||||||
|
* @param refreshOption
|
||||||
|
* @returns
|
||||||
|
* @description 支持增量更新,可以使用useLocalCache来将一些metadata级的数据本地缓存,减少更新次数。
|
||||||
|
* 使用增量更新这里要注意,传入的keys如果有一个key是首次更新,会导致所有的keys全部更新。使用模块自己保证这种情况不要出现
|
||||||
|
*/
|
||||||
refresh<T extends keyof ED, OP extends CacheSelectOption>(entity: T, selection: ED[T]['Selection'], option?: OP, callback?: (result: Awaited<ReturnType<AD['select']>>) => void, refreshOption?: RefreshOption): Promise<{
|
refresh<T extends keyof ED, OP extends CacheSelectOption>(entity: T, selection: ED[T]['Selection'], option?: OP, callback?: (result: Awaited<ReturnType<AD['select']>>) => void, refreshOption?: RefreshOption): Promise<{
|
||||||
data: Partial<ED[T]["Schema"]>[];
|
data: Partial<ED[T]["Schema"]>[];
|
||||||
total?: undefined;
|
total?: undefined;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class Cache extends Feature_1.Feature {
|
||||||
getFullDataFn;
|
getFullDataFn;
|
||||||
refreshRecords = {};
|
refreshRecords = {};
|
||||||
context;
|
context;
|
||||||
|
initPromise;
|
||||||
constructor(storageSchema, aspectWrapper, frontendContextBuilder, checkers, getFullData, localStorage, savedEntities, keepFreshPeriod) {
|
constructor(storageSchema, aspectWrapper, frontendContextBuilder, checkers, getFullData, localStorage, savedEntities, keepFreshPeriod) {
|
||||||
super();
|
super();
|
||||||
this.aspectWrapper = aspectWrapper;
|
this.aspectWrapper = aspectWrapper;
|
||||||
|
|
@ -34,12 +35,12 @@ class Cache extends Feature_1.Feature {
|
||||||
checkers.forEach((checker) => this.cacheStore.registerChecker(checker));
|
checkers.forEach((checker) => this.cacheStore.registerChecker(checker));
|
||||||
this.getFullDataFn = getFullData;
|
this.getFullDataFn = getFullData;
|
||||||
// 现在这个init变成了异步行为,不知道有没有影响。by Xc 20231126
|
// 现在这个init变成了异步行为,不知道有没有影响。by Xc 20231126
|
||||||
this.initSavedLogic();
|
this.initPromise = new Promise((resolve) => this.initSavedLogic(resolve));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 处理cache中需要缓存的数据
|
* 处理cache中需要缓存的数据
|
||||||
*/
|
*/
|
||||||
async initSavedLogic() {
|
async initSavedLogic(complete) {
|
||||||
const data = {};
|
const data = {};
|
||||||
await Promise.all(this.savedEntities.map(async (entity) => {
|
await Promise.all(this.savedEntities.map(async (entity) => {
|
||||||
// 加载缓存的数据项
|
// 加载缓存的数据项
|
||||||
|
|
@ -67,6 +68,10 @@ class Cache extends Feature_1.Feature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
async onInitialized() {
|
||||||
|
await this.initPromise;
|
||||||
}
|
}
|
||||||
getSchema() {
|
getSchema() {
|
||||||
return this.cacheStore.getSchema();
|
return this.cacheStore.getSchema();
|
||||||
|
|
@ -130,6 +135,17 @@ class Cache extends Feature_1.Feature {
|
||||||
}
|
}
|
||||||
return () => undefined;
|
return () => undefined;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 向服务器刷新数据
|
||||||
|
* @param entity
|
||||||
|
* @param selection
|
||||||
|
* @param option
|
||||||
|
* @param callback
|
||||||
|
* @param refreshOption
|
||||||
|
* @returns
|
||||||
|
* @description 支持增量更新,可以使用useLocalCache来将一些metadata级的数据本地缓存,减少更新次数。
|
||||||
|
* 使用增量更新这里要注意,传入的keys如果有一个key是首次更新,会导致所有的keys全部更新。使用模块自己保证这种情况不要出现
|
||||||
|
*/
|
||||||
async refresh(entity, selection, option, callback, refreshOption) {
|
async refresh(entity, selection, option, callback, refreshOption) {
|
||||||
// todo 还要判定没有aggregation
|
// todo 还要判定没有aggregation
|
||||||
const { dontPublish, useLocalCache } = refreshOption || {};
|
const { dontPublish, useLocalCache } = refreshOption || {};
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ export declare class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends
|
||||||
private initializeLng;
|
private initializeLng;
|
||||||
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, localStorage: LocalStorage, environment: Environment, defaultLng: string, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string);
|
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, localStorage: LocalStorage, environment: Environment, defaultLng: string, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string);
|
||||||
private detectLanguange;
|
private detectLanguange;
|
||||||
private resetDataset;
|
private reloadDataset;
|
||||||
|
private loadServerData;
|
||||||
/**
|
/**
|
||||||
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
||||||
* @param ns
|
* @param ns
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class Locales extends Feature_1.Feature {
|
||||||
defaultLocale: defaultLng,
|
defaultLocale: defaultLng,
|
||||||
locale: this.language,
|
locale: this.language,
|
||||||
});
|
});
|
||||||
this.resetDataset();
|
this.reloadDataset();
|
||||||
// i18n miss的默认策略
|
// i18n miss的默认策略
|
||||||
this.i18n.missingBehavior = 'loadData';
|
this.i18n.missingBehavior = 'loadData';
|
||||||
this.i18n.missingTranslation.register("loadData", (i18n, scope, options) => {
|
this.i18n.missingTranslation.register("loadData", (i18n, scope, options) => {
|
||||||
|
|
@ -56,7 +56,8 @@ class Locales extends Feature_1.Feature {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
await this.localStorage.save(constant_1.LOCAL_STORAGE_KEYS.localeLng, language);
|
await this.localStorage.save(constant_1.LOCAL_STORAGE_KEYS.localeLng, language);
|
||||||
}
|
}
|
||||||
resetDataset() {
|
async reloadDataset() {
|
||||||
|
await this.cache.onInitialized();
|
||||||
const i18ns = this.cache.get('i18n', {
|
const i18ns = this.cache.get('i18n', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -77,14 +78,13 @@ class Locales extends Feature_1.Feature {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.i18n.store(dataset);
|
this.i18n.store(dataset);
|
||||||
|
if (i18ns.length > 0) {
|
||||||
|
// 启动时刷新数据策略
|
||||||
|
const nss = i18ns.map(ele => ele.namespace);
|
||||||
|
await this.loadServerData(nss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
async loadServerData(nss) {
|
||||||
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
|
||||||
* @param ns
|
|
||||||
*/
|
|
||||||
async loadData(key) {
|
|
||||||
(0, assert_1.assert)(typeof key === 'string');
|
|
||||||
const [ns] = key.split('.');
|
|
||||||
const { data: newI18ns } = await this.cache.refresh('i18n', {
|
const { data: newI18ns } = await this.cache.refresh('i18n', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -95,13 +95,15 @@ class Locales extends Feature_1.Feature {
|
||||||
$$updateAt$$: 1,
|
$$updateAt$$: 1,
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
namespace: ns,
|
namespace: {
|
||||||
}
|
$in: nss,
|
||||||
|
},
|
||||||
|
},
|
||||||
}, undefined, undefined, {
|
}, undefined, undefined, {
|
||||||
dontPublish: true,
|
dontPublish: true,
|
||||||
useLocalCache: {
|
useLocalCache: {
|
||||||
keys: [ns],
|
keys: nss,
|
||||||
gap: process.env.NODE_ENV === 'development' ? 60 * 1000 : 1200 * 1000,
|
gap: process.env.NODE_ENV === 'development' ? 10 * 1000 : 3600 * 1000,
|
||||||
onlyReturnFresh: true,
|
onlyReturnFresh: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -120,6 +122,15 @@ class Locales extends Feature_1.Feature {
|
||||||
this.i18n.store(dataset);
|
this.i18n.store(dataset);
|
||||||
this.publish();
|
this.publish();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
||||||
|
* @param ns
|
||||||
|
*/
|
||||||
|
async loadData(key) {
|
||||||
|
(0, assert_1.assert)(typeof key === 'string');
|
||||||
|
const [ns] = key.split('.');
|
||||||
|
await this.loadServerData([key]);
|
||||||
if (!this.hasKey(key)) {
|
if (!this.hasKey(key)) {
|
||||||
console.warn(`命名空间${ns}中的${key}缺失且可能请求不到更新的数据`);
|
console.warn(`命名空间${ns}中的${key}缺失且可能请求不到更新的数据`);
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ export class Cache<
|
||||||
[T in keyof ED]?: Record<string, number>;
|
[T in keyof ED]?: Record<string, number>;
|
||||||
} = {};
|
} = {};
|
||||||
private context?: FrontCxt;
|
private context?: FrontCxt;
|
||||||
|
private initPromise: Promise<void>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
storageSchema: StorageSchema<ED>,
|
storageSchema: StorageSchema<ED>,
|
||||||
|
|
@ -77,13 +78,15 @@ export class Cache<
|
||||||
this.getFullDataFn = getFullData;
|
this.getFullDataFn = getFullData;
|
||||||
|
|
||||||
// 现在这个init变成了异步行为,不知道有没有影响。by Xc 20231126
|
// 现在这个init变成了异步行为,不知道有没有影响。by Xc 20231126
|
||||||
this.initSavedLogic();
|
this.initPromise = new Promise(
|
||||||
|
(resolve) => this.initSavedLogic(resolve)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理cache中需要缓存的数据
|
* 处理cache中需要缓存的数据
|
||||||
*/
|
*/
|
||||||
private async initSavedLogic() {
|
private async initSavedLogic(complete: () => void) {
|
||||||
const data: {
|
const data: {
|
||||||
[T in keyof ED]?: ED[T]['OpSchema'][];
|
[T in keyof ED]?: ED[T]['OpSchema'][];
|
||||||
} = {};
|
} = {};
|
||||||
|
|
@ -121,6 +124,11 @@ export class Cache<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
async onInitialized() {
|
||||||
|
await this.initPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSchema() {
|
getSchema() {
|
||||||
|
|
@ -198,6 +206,17 @@ export class Cache<
|
||||||
return () => undefined as void;
|
return () => undefined as void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向服务器刷新数据
|
||||||
|
* @param entity
|
||||||
|
* @param selection
|
||||||
|
* @param option
|
||||||
|
* @param callback
|
||||||
|
* @param refreshOption
|
||||||
|
* @returns
|
||||||
|
* @description 支持增量更新,可以使用useLocalCache来将一些metadata级的数据本地缓存,减少更新次数。
|
||||||
|
* 使用增量更新这里要注意,传入的keys如果有一个key是首次更新,会导致所有的keys全部更新。使用模块自己保证这种情况不要出现
|
||||||
|
*/
|
||||||
async refresh<T extends keyof ED, OP extends CacheSelectOption>(
|
async refresh<T extends keyof ED, OP extends CacheSelectOption>(
|
||||||
entity: T,
|
entity: T,
|
||||||
selection: ED[T]['Selection'],
|
selection: ED[T]['Selection'],
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
||||||
defaultLocale: defaultLng,
|
defaultLocale: defaultLng,
|
||||||
locale: this.language,
|
locale: this.language,
|
||||||
});
|
});
|
||||||
this.resetDataset();
|
this.reloadDataset();
|
||||||
|
|
||||||
// i18n miss的默认策略
|
// i18n miss的默认策略
|
||||||
this.i18n.missingBehavior = 'loadData';
|
this.i18n.missingBehavior = 'loadData';
|
||||||
|
|
@ -75,7 +75,8 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
||||||
await this.localStorage.save(LOCAL_STORAGE_KEYS.localeLng, language);
|
await this.localStorage.save(LOCAL_STORAGE_KEYS.localeLng, language);
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetDataset() {
|
private async reloadDataset() {
|
||||||
|
await this.cache.onInitialized();
|
||||||
const i18ns = this.cache.get('i18n', {
|
const i18ns = this.cache.get('i18n', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -98,16 +99,15 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.i18n.store(dataset);
|
this.i18n.store(dataset);
|
||||||
|
|
||||||
|
if (i18ns.length > 0) {
|
||||||
|
// 启动时刷新数据策略
|
||||||
|
const nss = i18ns.map(ele => ele.namespace!);
|
||||||
|
await this.loadServerData(nss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private async loadServerData(nss: string[]) {
|
||||||
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
|
||||||
* @param ns
|
|
||||||
*/
|
|
||||||
private async loadData(key: Scope) {
|
|
||||||
assert(typeof key === 'string');
|
|
||||||
const [ ns ] = key.split('.');
|
|
||||||
|
|
||||||
const { data: newI18ns } = await this.cache.refresh('i18n', {
|
const { data: newI18ns } = await this.cache.refresh('i18n', {
|
||||||
data: {
|
data: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -118,13 +118,15 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
||||||
$$updateAt$$: 1,
|
$$updateAt$$: 1,
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
namespace: ns,
|
namespace: {
|
||||||
}
|
$in: nss,
|
||||||
|
},
|
||||||
|
},
|
||||||
}, undefined, undefined, {
|
}, undefined, undefined, {
|
||||||
dontPublish: true,
|
dontPublish: true,
|
||||||
useLocalCache: {
|
useLocalCache: {
|
||||||
keys: [ns],
|
keys: nss,
|
||||||
gap: process.env.NODE_ENV === 'development' ? 60 * 1000 : 1200 * 1000,
|
gap: process.env.NODE_ENV === 'development' ? 10 * 1000 : 3600 * 1000,
|
||||||
onlyReturnFresh: true,
|
onlyReturnFresh: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -146,7 +148,16 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
|
||||||
this.i18n.store(dataset);
|
this.i18n.store(dataset);
|
||||||
this.publish();
|
this.publish();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 当发生key缺失时,向服务器请求最新的i18n数据,对i18n缓存数据的行为优化放在cache中统一进行
|
||||||
|
* @param ns
|
||||||
|
*/
|
||||||
|
private async loadData(key: Scope) {
|
||||||
|
assert(typeof key === 'string');
|
||||||
|
const [ ns ] = key.split('.');
|
||||||
|
|
||||||
|
await this.loadServerData([key]);
|
||||||
if (!this.hasKey(key)) {
|
if (!this.hasKey(key)) {
|
||||||
console.warn(`命名空间${ns}中的${key}缺失且可能请求不到更新的数据`);
|
console.warn(`命名空间${ns}中的${key}缺失且可能请求不到更新的数据`);
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue