重新整理了localStorage相关的key值

This commit is contained in:
Xu Chang 2023-08-19 17:02:08 +08:00
parent 90cd65d0a0
commit b232d0c4c4
26 changed files with 256 additions and 306 deletions

View File

@ -9,9 +9,7 @@ interface CachStoreOperation extends TreeStoreOperateOption {
}
export declare class CacheStore<ED extends EntityDict & BaseEntityDict, Cxt extends SyncContext<ED>> extends TreeStore<ED> implements SyncRowStore<ED, SyncContext<ED>> {
private triggerExecutor;
private getFullDataFn?;
private resetInitialDataFn?;
constructor(storageSchema: StorageSchema<ED>, getFullDataFn?: () => any, resetInitialDataFn?: () => void);
constructor(storageSchema: StorageSchema<ED>);
aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: SyncContext<ED>, option: OP): AggregationResult<ED[T]['Schema']>;
protected cascadeUpdate<T extends keyof ED, OP extends CachStoreOperation>(entity: T, operation: ED[T]['Operation'], context: SyncContext<ED>, option: OP): OperationResult<ED>;
operate<T extends keyof ED, OP extends CachStoreOperation>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): OperationResult<ED>;
@ -19,16 +17,6 @@ export declare class CacheStore<ED extends EntityDict & BaseEntityDict, Cxt exte
check<T extends keyof ED>(entity: T, operation: Omit<ED[T]['Operation'], 'id'>, context: Cxt, checkerTypes?: CheckerType[]): void;
select<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Partial<ED[T]["Schema"]>[];
registerChecker<T extends keyof ED>(checker: Checker<ED, T, Cxt>): void;
/**
* debug下用来获取debugStore的数据release下不能使用
* @returns
*/
getFullData(): any;
/**
* debug下用来初始化debugStore的数据release下不能使用
* @returns
*/
resetInitialData(): void;
count<T extends keyof ED, OP extends SelectOption>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: SyncContext<ED>, option: OP): number;
begin(option?: TxnOption): string;
commit(txnId: string): void;

View File

@ -9,11 +9,9 @@ var SyncTriggerExecutor_1 = tslib_1.__importDefault(require("./SyncTriggerExecut
;
var CacheStore = /** @class */ (function (_super) {
tslib_1.__extends(CacheStore, _super);
function CacheStore(storageSchema, getFullDataFn, resetInitialDataFn) {
function CacheStore(storageSchema) {
var _this = _super.call(this, storageSchema) || this;
_this.triggerExecutor = new SyncTriggerExecutor_1.default();
_this.getFullDataFn = getFullDataFn;
_this.resetInitialDataFn = resetInitialDataFn;
return _this;
}
CacheStore.prototype.aggregate = function (entity, aggregation, context, option) {
@ -97,20 +95,6 @@ var CacheStore = /** @class */ (function (_super) {
/* registerTrigger<T extends keyof ED>(trigger: Trigger<ED, T, Cxt>) {
this.triggerExecutor.registerTrigger(trigger);
} */
/**
* 这个函数是在debug下用来获取debugStore的数据release下不能使用
* @returns
*/
CacheStore.prototype.getFullData = function () {
return this.getFullDataFn();
};
/**
* 这个函数是在debug下用来初始化debugStore的数据release下不能使用
* @returns
*/
CacheStore.prototype.resetInitialData = function () {
return this.resetInitialDataFn();
};
CacheStore.prototype.count = function (entity, selection, context, option) {
var autoCommit = !context.getCurrentTxnId();
if (autoCommit) {

View File

@ -1,4 +1,5 @@
export declare const LOCAL_STORAGE_KEYS: {
debugStore: string;
debugStoreStat: string;
localeLng: string;
};

View File

@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.LOCAL_STORAGE_KEYS = void 0;
exports.LOCAL_STORAGE_KEYS = {
debugStore: 'debugStore',
debugStoreStat: 'debugStoreStat',
debugStore: 'oak-fronted-base:debugStore',
debugStoreStat: 'oak-fronted-base:debugStoreStat',
localeLng: 'oak-frontend-base:feature-locale-lng',
};

View File

@ -5,4 +5,4 @@ import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
export declare function clearMaterializedData(): void;
export declare function createDebugStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(storageSchema: StorageSchema<ED>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, triggers: Array<Trigger<ED, keyof ED, Cxt>>, checkers: Array<Checker<ED, keyof ED, Cxt>>, watchers: Array<Watcher<ED, keyof ED, Cxt>>, timers: Array<Timer<ED, Cxt>>, startRoutines: Array<Routine<ED, Cxt>>, initialData: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
}, actionDict: ActionDictOfEntityDict<ED>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities: (keyof ED)[], createFreeEntities: (keyof ED)[], updateFreeEntities: (keyof ED)[]): DebugStore<ED, Cxt>;
}, actionDict: ActionDictOfEntityDict<ED>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities: (keyof ED)[], createFreeEntities: (keyof ED)[], updateFreeEntities: (keyof ED)[], saveFn: (key: string, data: any) => void, loadFn: (key: string) => any): DebugStore<ED, Cxt>;

View File

@ -15,73 +15,32 @@ function initDataInStore(store, initialData, stat) {
});
});
}
function getMaterializedData() {
if (process.env.OAK_PLATFORM === 'wechatMp') {
try {
var data = wx.getStorageSync(constant_1.LOCAL_STORAGE_KEYS.debugStore);
var stat = wx.getStorageSync(constant_1.LOCAL_STORAGE_KEYS.debugStoreStat);
if (data && stat) {
return {
data: data,
stat: stat,
};
}
return;
}
catch (e) {
return;
function getMaterializedData(loadFn) {
try {
var data = loadFn(constant_1.LOCAL_STORAGE_KEYS.debugStore);
var stat = loadFn(constant_1.LOCAL_STORAGE_KEYS.debugStoreStat);
if (data && stat) {
return {
data: data,
stat: stat,
};
}
return;
}
else if (process.env.OAK_PLATFORM === 'web') {
try {
var data = JSON.parse(window.localStorage.getItem(constant_1.LOCAL_STORAGE_KEYS.debugStore));
var stat = JSON.parse(window.localStorage.getItem(constant_1.LOCAL_STORAGE_KEYS.debugStoreStat));
if (data && stat) {
return {
data: data,
stat: stat,
};
}
return;
}
catch (e) {
return;
}
catch (e) {
return;
}
}
var lastMaterializedVersion = 0;
function materializeData(data, stat) {
if (process.env.OAK_PLATFORM === 'wechatMp') {
try {
wx.setStorageSync(constant_1.LOCAL_STORAGE_KEYS.debugStore, data);
wx.setStorageSync(constant_1.LOCAL_STORAGE_KEYS.debugStoreStat, stat);
lastMaterializedVersion = stat.commit;
wx.showToast({
title: '数据已物化',
icon: 'success',
});
console.log('物化数据', data);
}
catch (e) {
console.error(e);
wx.showToast({
title: '物化数据失败',
icon: 'error',
});
}
function materializeData(data, stat, saveFn) {
try {
saveFn(constant_1.LOCAL_STORAGE_KEYS.debugStore, data);
saveFn(constant_1.LOCAL_STORAGE_KEYS.debugStoreStat, stat);
lastMaterializedVersion = stat.commit;
console.log('物化数据', data);
}
else if (process.env.OAK_PLATFORM === 'web') {
try {
window.localStorage.setItem(constant_1.LOCAL_STORAGE_KEYS.debugStore, typeof data === 'string' ? data : JSON.stringify(data));
window.localStorage.setItem(constant_1.LOCAL_STORAGE_KEYS.debugStoreStat, JSON.stringify(stat));
lastMaterializedVersion = stat.commit;
console.log('物化数据', data);
// alert('数据已物化');
}
catch (e) {
console.error(e);
// alert('物化数据失败');
}
catch (e) {
console.error(e);
}
}
function clearMaterializedData() {
@ -381,13 +340,13 @@ function doRoutines(store, contextBuilder, routines) {
});
});
}
function createDebugStore(storageSchema, contextBuilder, triggers, checkers, watchers, timers, startRoutines, initialData, actionDict, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities) {
function createDebugStore(storageSchema, contextBuilder, triggers, checkers, watchers, timers, startRoutines, initialData, actionDict, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, saveFn, loadFn) {
var store = new DebugStore_1.DebugStore(storageSchema, contextBuilder, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
triggers.forEach(function (ele) { return store.registerTrigger(ele); });
checkers.forEach(function (ele) { return store.registerChecker(ele); });
(0, assert_1.assert)(actionDict);
// 如果没有物化数据则使用initialData初始化debugStore
var data = getMaterializedData();
var data = getMaterializedData(loadFn);
if (!data) {
initDataInStore(store, initialData);
console.log('使用初始化数据建立debugStore', initialData);
@ -403,15 +362,14 @@ function createDebugStore(storageSchema, contextBuilder, triggers, checkers, wat
console.log('使用物化数据建立debugStore', data);
}
lastMaterializedVersion = store.getStat().commit;
// 启动定期的物化例程
setInterval(function () {
var stat = store.getStat();
if (stat.commit === lastMaterializedVersion) {
return;
// 当store中有更新事务提交时物化store数据
store.onCommit(function (result) {
if (Object.keys(result).length > 0) {
var stat = store.getStat();
var data_1 = store.getCurrentData();
materializeData(data_1, stat, saveFn);
}
var data = store.getCurrentData();
materializeData(data, stat);
}, 10000);
});
// 启动watcher
initializeWatchers(store, contextBuilder, watchers);
// 启动timer

View File

@ -11,7 +11,8 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
private syncEventsCallbacks;
private contextBuilder?;
private refreshing;
constructor(aspectWrapper: AspectWrapper<ED, Cxt, AD>, contextBuilder: () => FrontCxt, store: CacheStore<ED, FrontCxt>);
private getFullDataFn;
constructor(aspectWrapper: AspectWrapper<ED, Cxt, AD>, contextBuilder: () => FrontCxt, store: CacheStore<ED, FrontCxt>, getFullData: () => any);
getSchema(): import("oak-domain/lib/types").StorageSchema<ED>;
getCurrentUserId(allowUnloggedIn?: boolean): string | undefined;
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<{
@ -51,7 +52,6 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void;
getCachedData(): { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
getFullData(): any;
resetInitialData(): void;
begin(): FrontCxt;
commit(context: FrontCxt): void;
rollback(context: FrontCxt): void;

View File

@ -8,13 +8,14 @@ var Exception_1 = require("oak-domain/lib/types/Exception");
var assert_1 = tslib_1.__importDefault(require("assert"));
var Cache = /** @class */ (function (_super) {
tslib_1.__extends(Cache, _super);
function Cache(aspectWrapper, contextBuilder, store) {
function Cache(aspectWrapper, contextBuilder, store, getFullData) {
var _this = _super.call(this) || this;
_this.refreshing = false;
_this.aspectWrapper = aspectWrapper;
_this.syncEventsCallbacks = [];
_this.contextBuilder = contextBuilder;
_this.cacheStore = store;
_this.getFullDataFn = getFullData;
return _this;
// 在这里把wrapper的返回opRecords截取到并同步到cache中
/* const { exec } = aspectWrapper;
@ -317,10 +318,7 @@ var Cache = /** @class */ (function (_super) {
return this.cacheStore.getCurrentData();
};
Cache.prototype.getFullData = function () {
return this.cacheStore.getFullData();
};
Cache.prototype.resetInitialData = function () {
return this.cacheStore.resetInitialData();
return this.getFullDataFn();
};
Cache.prototype.begin = function () {
var context = this.contextBuilder();

View File

@ -21,7 +21,25 @@ import { ContextMenuFactory } from './contextMenuFactory';
import { Geo } from './geo';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(aspectWrapper: AspectWrapper<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>, storageSchema: StorageSchema<ED>, contextBuilder: () => FrontCxt, store: CacheStore<ED, FrontCxt>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities: (keyof ED)[], createFreeEntities: (keyof ED)[], updateFreeEntities: (keyof ED)[], colorDict: ColorDict<ED>, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string): BasicFeatures<ED, Cxt, FrontCxt, AD>;
export declare function initializeStep2<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(features: Pick<BasicFeatures<ED, Cxt, FrontCxt, AD>, 'localStorage' | 'environment'>, aspectWrapper: AspectWrapper<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>, storageSchema: StorageSchema<ED>, contextBuilder: () => FrontCxt, store: CacheStore<ED, FrontCxt>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities: (keyof ED)[], createFreeEntities: (keyof ED)[], updateFreeEntities: (keyof ED)[], colorDict: ColorDict<ED>, getFullDataFn: () => any, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string): {
cache: Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
relationAuth: RelationAuth<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
runningTree: RunningTree<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
locales: Locales<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
port: Port<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
style: Style<ED>;
geo: Geo<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
contextMenuFactory: ContextMenuFactory<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
};
export declare function initializeStep1(): {
location: Location;
environment: Environment;
eventBus: EventBus;
notification: Notification;
message: Message;
localStorage: LocalStorage;
navigator: Navigator;
};
export declare type BasicFeatures<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>> = {
cache: Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
location: Location;

View File

@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initialize = void 0;
exports.initializeStep1 = exports.initializeStep2 = void 0;
var cache_1 = require("./cache");
var location_1 = require("./location");
var runningTree_1 = require("./runningTree");
@ -16,38 +16,44 @@ var relationAuth_1 = require("./relationAuth");
var style_1 = require("./style");
var contextMenuFactory_1 = require("./contextMenuFactory");
var geo_1 = require("./geo");
function initialize(aspectWrapper, storageSchema, contextBuilder, store, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict, makeBridgeUrlFn) {
var cache = new cache_1.Cache(aspectWrapper, contextBuilder, store);
var location = new location_1.Location();
var environment = new environment_1.Environment();
var relationAuth = new relationAuth_1.RelationAuth(aspectWrapper, contextBuilder, cache, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
function initializeStep2(features, aspectWrapper, storageSchema, contextBuilder, store, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict, getFullDataFn, makeBridgeUrlFn) {
var localStorage = features.localStorage, environment = features.environment;
var cache = new cache_1.Cache(aspectWrapper, contextBuilder, store, getFullDataFn);
var relationAuth = new relationAuth_1.RelationAuth(contextBuilder, cache, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
var runningTree = new runningTree_1.RunningTree(cache, storageSchema, relationAuth);
var geo = new geo_1.Geo(aspectWrapper);
var eventBus = new eventBus_1.EventBus();
var localStorage = new localStorage_1.LocalStorage();
var notification = new notification_1.Notification();
var message = new message_1.Message();
var navigator = new navigator_1.Navigator();
var port = new port_1.Port(aspectWrapper);
var style = new style_1.Style(colorDict);
var locales = new locales_1.Locales(cache, localStorage, environment, 'zh-CN', makeBridgeUrlFn); // 临时性代码,应由上层传入
var contextMenuFactory = new contextMenuFactory_1.ContextMenuFactory(cache, relationAuth, actionCascadePathGraph);
return {
cache: cache,
location: location,
relationAuth: relationAuth,
runningTree: runningTree,
locales: locales,
eventBus: eventBus,
localStorage: localStorage,
notification: notification,
message: message,
navigator: navigator,
port: port,
style: style,
geo: geo,
environment: environment,
contextMenuFactory: contextMenuFactory,
};
}
exports.initialize = initialize;
exports.initializeStep2 = initializeStep2;
function initializeStep1() {
var location = new location_1.Location();
var environment = new environment_1.Environment();
var eventBus = new eventBus_1.EventBus();
var localStorage = new localStorage_1.LocalStorage();
var notification = new notification_1.Notification();
var message = new message_1.Message();
var navigator = new navigator_1.Navigator();
return {
location: location,
environment: environment,
eventBus: eventBus,
notification: notification,
message: message,
localStorage: localStorage,
navigator: navigator,
};
}
exports.initializeStep1 = initializeStep1;

View File

@ -6,7 +6,7 @@ var Feature_1 = require("../types/Feature");
var assert_1 = tslib_1.__importDefault(require("assert"));
var i18n_js_1 = require("i18n-js");
var lodash_1 = require("oak-domain/lib/utils/lodash");
var LS_LNG_KEY = 'ofb-feature-locale-lng';
var constant_1 = require("../constant/constant");
var Locales = /** @class */ (function (_super) {
tslib_1.__extends(Locales, _super);
function Locales(cache, localStorage, environment, defaultLng, makeBridgeUrlFn) {
@ -16,7 +16,7 @@ var Locales = /** @class */ (function (_super) {
_this.localStorage = localStorage;
_this.defaultLng = defaultLng;
_this.environment = environment;
var savedLng = localStorage.load(LS_LNG_KEY);
var savedLng = localStorage.load(constant_1.LOCAL_STORAGE_KEYS.localeLng);
if (savedLng) {
_this.language = savedLng;
}
@ -53,7 +53,7 @@ var Locales = /** @class */ (function (_super) {
env = _a.sent();
language = env.language;
this.language = language;
this.localStorage.save(LS_LNG_KEY, language);
this.localStorage.save(constant_1.LOCAL_STORAGE_KEYS.localeLng, language);
return [2 /*return*/];
}
});

View File

@ -1,4 +1,4 @@
import { EntityDict, AspectWrapper, Aspect, AuthCascadePath, AuthDeduceRelationMap } from 'oak-domain/lib/types';
import { EntityDict, Aspect, AuthCascadePath, AuthDeduceRelationMap } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { Feature } from '../types/Feature';
@ -8,7 +8,6 @@ import { Cache } from './cache';
export declare class RelationAuth<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt> & Record<string, Aspect<ED, Cxt>>> extends Feature {
private cache;
private contextBuilder;
private aspectWrapper;
private actionCascadePathGraph;
private actionCascadePathMap;
private relationCascadePathGraph;
@ -16,7 +15,7 @@ export declare class RelationAuth<ED extends EntityDict & BaseEntityDict, Cxt ex
private authDeduceRelationMap;
static IgnoredActions: string[];
private entityGraph?;
constructor(aspectWrapper: AspectWrapper<ED, Cxt, AD>, contextBuilder: () => FrontCxt, cache: Cache<ED, Cxt, FrontCxt, AD>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities: (keyof ED)[], createFreeEntities: (keyof ED)[], updateFreeEntities: (keyof ED)[]);
constructor(contextBuilder: () => FrontCxt, cache: Cache<ED, Cxt, FrontCxt, AD>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities: (keyof ED)[], createFreeEntities: (keyof ED)[], updateFreeEntities: (keyof ED)[]);
private judgeRelation;
getHasRelationEntities(): string[];
getDeduceRelationAttribute(entity: keyof ED): string | undefined;

View File

@ -9,9 +9,8 @@ var RelationAuth_1 = require("oak-domain/lib/store/RelationAuth");
var relation_1 = require("oak-domain/lib/store/relation");
var RelationAuth = /** @class */ (function (_super) {
tslib_1.__extends(RelationAuth, _super);
function RelationAuth(aspectWrapper, contextBuilder, cache, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities) {
function RelationAuth(contextBuilder, cache, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities) {
var _this = _super.call(this) || this;
_this.aspectWrapper = aspectWrapper;
_this.contextBuilder = contextBuilder;
_this.cache = cache;
_this.actionCascadePathGraph = actionCascadePathGraph;

View File

@ -23,5 +23,22 @@ import { InitializeOptions } from './types/Initialize';
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, backendContextBuilder: (contextStr?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, aspectDict: AD, triggers: Array<Trigger<ED, keyof ED, Cxt>>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, watchers: Array<Watcher<ED, keyof ED, Cxt>>, timers: Array<Timer<ED, Cxt>>, startRoutines: Array<Routine<ED, Cxt>>, initialData: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
}, option: InitializeOptions<ED>): {
features: import("./features").BasicFeatures<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
features: {
cache: import(".").Cache<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
relationAuth: import("./features/relationAuth").RelationAuth<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
runningTree: import("./features/runningTree").RunningTree<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
locales: import("./features/locales").Locales<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
port: import("./features/port").Port<ED, Cxt, CommonAspectDict<ED, Cxt> & AD>;
style: import("./features/style").Style<ED>;
geo: import("./features/geo").Geo<ED, Cxt, CommonAspectDict<ED, Cxt> & AD>;
contextMenuFactory: import("./features/contextMenuFactory").ContextMenuFactory<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
} & {
location: import("./features/location").Location;
environment: import("./features/environment").Environment;
eventBus: import("./features/eventBus").EventBus;
notification: import("./features/notification").Notification;
message: import("./features/message").Message;
localStorage: import(".").LocalStorage;
navigator: import("./features/navigator.web").Navigator;
};
};

View File

@ -34,8 +34,9 @@ function initialize(storageSchema, frontendContextBuilder, backendContextBuilder
var checkers2 = checkers.concat(intCheckers);
var triggers2 = triggers.concat(intTriggers);
var watchers2 = watchers.concat(intWatchers);
var debugStore = (0, debugStore_1.createDebugStore)(storageSchema, backendContextBuilder, triggers2, checkers2, watchers2, timers, startRoutines, initialData, actionDict, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
var cacheStore = new CacheStore_1.CacheStore(storageSchema, function () { return debugStore.getCurrentData(); }, function () { return (0, debugStore_1.clearMaterializedData)(); });
var features1 = (0, features_1.initializeStep1)();
var debugStore = (0, debugStore_1.createDebugStore)(storageSchema, backendContextBuilder, triggers2, checkers2, watchers2, timers, startRoutines, initialData, actionDict, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, function (key, data) { return features1.localStorage.save(key, data); }, function (key) { return features1.localStorage.load(key); });
var cacheStore = new CacheStore_1.CacheStore(storageSchema);
var wrapper = {
exec: function (name, params) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var context, str, contextBackend, result, err_1;
@ -75,9 +76,10 @@ function initialize(storageSchema, frontendContextBuilder, backendContextBuilder
});
}); },
};
var features = (0, features_1.initialize)(wrapper, storageSchema, function () { return frontendContextBuilder()(cacheStore); }, cacheStore, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict);
var features2 = (0, features_1.initializeStep2)(features1, wrapper, storageSchema, function () { return frontendContextBuilder()(cacheStore); }, cacheStore, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict, function () { return debugStore.getCurrentData(); });
checkers2.forEach(function (checker) { return cacheStore.registerChecker(checker); });
(0, oak_common_aspect_2.registerPorts)(importations || [], exportations || []);
var features = Object.assign(features2, features1);
return {
features: features,
};

View File

@ -20,5 +20,22 @@ import { InitializeOptions } from './types/Initialize';
* @returns
*/
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, connector: Connector<ED, Cxt, FrontCxt>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, option: InitializeOptions<ED>): {
features: import("./features").BasicFeatures<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
features: {
location: import("./features/location").Location;
environment: import("./features/environment").Environment;
eventBus: import("./features/eventBus").EventBus;
notification: import("./features/notification").Notification;
message: import("./features/message").Message;
localStorage: import(".").LocalStorage;
navigator: import("./features/navigator.web").Navigator;
} & {
cache: import(".").Cache<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
relationAuth: import("./features/relationAuth").RelationAuth<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
runningTree: import("./features/runningTree").RunningTree<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
locales: import("./features/locales").Locales<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
port: import("./features/port").Port<ED, Cxt, CommonAspectDict<ED, Cxt> & AD>;
style: import("./features/style").Style<ED>;
geo: import("./features/geo").Geo<ED, Cxt, CommonAspectDict<ED, Cxt> & AD>;
contextMenuFactory: import("./features/contextMenuFactory").ContextMenuFactory<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
};
};

View File

@ -23,6 +23,7 @@ function initialize(storageSchema, frontendContextBuilder, connector, checkers,
var actionCascadePathGraph = option.actionCascadePathGraph, relationCascadePathGraph = option.relationCascadePathGraph, authDeduceRelationMap = option.authDeduceRelationMap, actionDict = option.actionDict, selectFreeEntities = option.selectFreeEntities, createFreeEntities = option.createFreeEntities, updateFreeEntities = option.updateFreeEntities, colorDict = option.colorDict;
var intCheckers = (0, actionDef_1.makeIntrinsicCTWs)(storageSchema, actionDict).checkers;
var checkers2 = checkers.concat(intCheckers);
var features1 = (0, features_1.initializeStep1)();
var cacheStore = new CacheStore_1.CacheStore(storageSchema);
var wrapper = {
exec: function (name, params) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
@ -43,8 +44,9 @@ function initialize(storageSchema, frontendContextBuilder, connector, checkers,
});
}); },
};
var features = (0, features_1.initialize)(wrapper, storageSchema, function () { return frontendContextBuilder()(cacheStore); }, cacheStore, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict, function (url, headers) { return connector.makeBridgeUrl(url, headers); });
var features2 = (0, features_1.initializeStep2)(features1, wrapper, storageSchema, function () { return frontendContextBuilder()(cacheStore); }, cacheStore, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict, function () { return '请查看数据库中的数据'; }, function (url, headers) { return connector.makeBridgeUrl(url, headers); });
checkers2.forEach(function (checker) { return cacheStore.registerChecker(checker); });
var features = Object.assign(features1, features2);
return {
features: features,
};

View File

@ -17,18 +17,18 @@ export class CacheStore<
Cxt extends SyncContext<ED>
> extends TreeStore<ED> implements SyncRowStore<ED, SyncContext<ED>>{
private triggerExecutor: SyncTriggerExecutor<ED, Cxt>;
private getFullDataFn?: () => any;
private resetInitialDataFn?: () => void;
private savedEntities: (keyof ED)[];
private keepFreshPeriod: number;
constructor(
storageSchema: StorageSchema<ED>,
getFullDataFn?: () => any,
resetInitialDataFn?: () => void
keepFreshPeriod: number,
savedEntities: (keyof ED)[],
) {
super(storageSchema);
this.triggerExecutor = new SyncTriggerExecutor();
this.getFullDataFn = getFullDataFn;
this.resetInitialDataFn = resetInitialDataFn;
this.keepFreshPeriod = keepFreshPeriod;
this.savedEntities = savedEntities;
}
aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: SyncContext<ED>, option: OP): AggregationResult<ED[T]['Schema']> {
@ -131,21 +131,6 @@ export class CacheStore<
this.triggerExecutor.registerTrigger(trigger);
} */
/**
* debug下用来获取debugStore的数据release下不能使用
* @returns
*/
getFullData() {
return this.getFullDataFn!();
}
/**
* debug下用来初始化debugStore的数据release下不能使用
* @returns
*/
resetInitialData() {
return this.resetInitialDataFn!();
}
count<T extends keyof ED, OP extends SelectOption>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: SyncContext<ED>, option: OP): number {
const autoCommit = !context.getCurrentTxnId();

View File

@ -1,4 +1,5 @@
export const LOCAL_STORAGE_KEYS = {
debugStore: 'debugStore',
debugStoreStat: 'debugStoreStat',
debugStore: 'oak-fronted-base:debugStore',
debugStoreStat: 'oak-fronted-base:debugStoreStat',
localeLng: 'oak-frontend-base:feature-locale-lng',
};

View File

@ -2,7 +2,8 @@ import { scheduleJob } from 'node-schedule';
import { LOCAL_STORAGE_KEYS } from '../constant/constant';
import { DebugStore } from './DebugStore';
import {
Checker, Trigger, StorageSchema, EntityDict, ActionDictOfEntityDict, Watcher, BBWatcher, WBWatcher, Routine, Timer, AuthCascadePath, AuthDeduceRelationMap} from "oak-domain/lib/types";
Checker, Trigger, StorageSchema, EntityDict, ActionDictOfEntityDict, Watcher, BBWatcher, WBWatcher, Routine, Timer, AuthCascadePath, AuthDeduceRelationMap
} from "oak-domain/lib/types";
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { assert } from 'oak-domain/lib/utils/assert';
@ -22,77 +23,35 @@ async function initDataInStore<ED extends EntityDict & BaseEntityDict, Cxt exten
store.resetInitialData(initialData, stat);
}
function getMaterializedData() {
if (process.env.OAK_PLATFORM === 'wechatMp') {
try {
const data = wx.getStorageSync(LOCAL_STORAGE_KEYS.debugStore);
const stat = wx.getStorageSync(LOCAL_STORAGE_KEYS.debugStoreStat);
if (data && stat) {
return {
data,
stat,
};
}
return;
} catch (e) {
return;
}
} else if (process.env.OAK_PLATFORM === 'web') {
try {
const data = JSON.parse(
window.localStorage.getItem(LOCAL_STORAGE_KEYS.debugStore) as string
);
const stat = JSON.parse(
window.localStorage.getItem(LOCAL_STORAGE_KEYS.debugStoreStat) as string
);
if (data && stat) {
return {
data,
stat,
};
}
return;
} catch (e) {
return;
function getMaterializedData(loadFn: (key: string) => any) {
try {
const data = loadFn(LOCAL_STORAGE_KEYS.debugStore);
const stat = loadFn(LOCAL_STORAGE_KEYS.debugStoreStat);
if (data && stat) {
return {
data,
stat,
};
}
return;
} catch (e) {
return;
}
}
let lastMaterializedVersion = 0;
function materializeData(data: any, stat: { create: number, update: number, remove: number, commit: number }) {
if (process.env.OAK_PLATFORM === 'wechatMp') {
try {
wx.setStorageSync(LOCAL_STORAGE_KEYS.debugStore, data);
wx.setStorageSync(LOCAL_STORAGE_KEYS.debugStoreStat, stat);
lastMaterializedVersion = stat.commit;
wx.showToast({
title: '数据已物化',
icon: 'success',
});
console.log('物化数据', data);
} catch (e) {
console.error(e);
wx.showToast({
title: '物化数据失败',
icon: 'error',
});
}
}
else if (process.env.OAK_PLATFORM === 'web') {
try {
window.localStorage.setItem(
LOCAL_STORAGE_KEYS.debugStore,
typeof data === 'string' ? data : JSON.stringify(data)
);
window.localStorage.setItem(LOCAL_STORAGE_KEYS.debugStoreStat, JSON.stringify(stat));
lastMaterializedVersion = stat.commit;
console.log('物化数据', data);
// alert('数据已物化');
} catch (e) {
console.error(e);
// alert('物化数据失败');
}
function materializeData(
data: any,
stat: { create: number, update: number, remove: number, commit: number },
saveFn: (key: string, data: any) => void) {
try {
saveFn(LOCAL_STORAGE_KEYS.debugStore, data);
saveFn(LOCAL_STORAGE_KEYS.debugStoreStat, stat);
lastMaterializedVersion = stat.commit;
console.log('物化数据', data);
} catch (e) {
console.error(e);
}
}
@ -115,7 +74,7 @@ export function clearMaterializedData() {
});
}
}
else if (process.env.OAK_PLATFORM === 'web') {
else if (process.env.OAK_PLATFORM === 'web') {
try {
window.localStorage.removeItem(LOCAL_STORAGE_KEYS.debugStore);
window.localStorage.removeItem(LOCAL_STORAGE_KEYS.debugStoreStat);
@ -135,8 +94,8 @@ export function clearMaterializedData() {
* @param watchers
*/
function initializeWatchers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(
store: DebugStore<ED, Cxt>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, watchers: Array<Watcher<ED, keyof ED, Cxt>>) {
store: DebugStore<ED, Cxt>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, watchers: Array<Watcher<ED, keyof ED, Cxt>>) {
let count = 0;
async function doWatchers() {
count++;
@ -192,7 +151,7 @@ function initializeWatchers<ED extends EntityDict & BaseEntityDict, Cxt extends
}
function initializeTimers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(
store: DebugStore<ED, Cxt>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, timers: Array<Timer<ED, Cxt>>
store: DebugStore<ED, Cxt>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, timers: Array<Timer<ED, Cxt>>
) {
if (process.env.OAK_PLATFORM === 'wechatMp') {
const { platform } = wx.getSystemInfoSync();
@ -213,7 +172,7 @@ function initializeTimers<ED extends EntityDict & BaseEntityDict, Cxt extends As
console.log(`定时器【${name}】执行完成,耗时${Date.now() - start}毫秒,结果是【${result}`);
await context.commit();
}
catch(err) {
catch (err) {
console.warn(`定时器【${name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
await context.rollback();
}
@ -222,11 +181,11 @@ function initializeTimers<ED extends EntityDict & BaseEntityDict, Cxt extends As
}
async function doRoutines<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(
store: DebugStore<ED, Cxt>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, routines: Array<Routine<ED, Cxt>>
store: DebugStore<ED, Cxt>, contextBuilder: (cxtString?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, routines: Array<Routine<ED, Cxt>>
) {
for (const routine of routines) {
const { name, fn } = routine;
const context = await contextBuilder()(store);
const context = await contextBuilder()(store);
const start = Date.now();
await context.begin();
try {
@ -257,9 +216,11 @@ export function createDebugStore<ED extends EntityDict & BaseEntityDict, Cxt ext
relationCascadePathGraph: AuthCascadePath<ED>[],
authDeduceRelationMap: AuthDeduceRelationMap<ED>,
selectFreeEntities: (keyof ED)[],
createFreeEntities: (keyof ED)[],
updateFreeEntities: (keyof ED)[]) {
const store = new DebugStore<ED, Cxt>(storageSchema, contextBuilder, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap,
createFreeEntities: (keyof ED)[],
updateFreeEntities: (keyof ED)[],
saveFn: (key: string, data: any) => void,
loadFn: (key: string) => any) {
const store = new DebugStore<ED, Cxt>(storageSchema, contextBuilder, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap,
selectFreeEntities, createFreeEntities, updateFreeEntities);
triggers.forEach(
@ -273,7 +234,7 @@ export function createDebugStore<ED extends EntityDict & BaseEntityDict, Cxt ext
assert(actionDict);
// 如果没有物化数据则使用initialData初始化debugStore
const data = getMaterializedData();
const data = getMaterializedData(loadFn);
if (!data) {
initDataInStore(store, initialData!);
console.log('使用初始化数据建立debugStore', initialData);
@ -290,15 +251,14 @@ export function createDebugStore<ED extends EntityDict & BaseEntityDict, Cxt ext
}
lastMaterializedVersion = store.getStat().commit;
// 启动定期的物化例程
setInterval(() => {
const stat = store.getStat();
if (stat.commit === lastMaterializedVersion) {
return;
// 当store中有更新事务提交时物化store数据
store.onCommit((result) => {
if (Object.keys(result).length > 0) {
const stat = store.getStat();
const data = store.getCurrentData();
materializeData(data, stat, saveFn);
}
const data = store.getCurrentData();
materializeData(data, stat);
}, 10000);
});
// 启动watcher
initializeWatchers(store, contextBuilder, watchers);

View File

@ -23,11 +23,13 @@ export class Cache<
>;
private contextBuilder?: () => FrontCxt;
private refreshing = false;
private getFullDataFn: () => any;
constructor(
aspectWrapper: AspectWrapper<ED, Cxt, AD>,
contextBuilder: () => FrontCxt,
store: CacheStore<ED, FrontCxt>
store: CacheStore<ED, FrontCxt>,
getFullData: () => any
) {
super();
this.aspectWrapper = aspectWrapper;
@ -35,6 +37,7 @@ export class Cache<
this.contextBuilder = contextBuilder;
this.cacheStore = store;
this.getFullDataFn = getFullData;
// 在这里把wrapper的返回opRecords截取到并同步到cache中
/* const { exec } = aspectWrapper;
@ -316,11 +319,7 @@ export class Cache<
}
getFullData() {
return this.cacheStore!.getFullData();
}
resetInitialData() {
return this.cacheStore!.resetInitialData();
return this.getFullDataFn();
}
begin() {

View File

@ -23,52 +23,61 @@ import { Geo } from './geo';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
export function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>> (
aspectWrapper: AspectWrapper<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>,
storageSchema: StorageSchema<ED>,
contextBuilder: () => FrontCxt,
store: CacheStore<ED, FrontCxt>,
actionCascadePathGraph: AuthCascadePath<ED>[],
relationCascadePathGraph: AuthCascadePath<ED>[],
authDeduceRelationMap: AuthDeduceRelationMap<ED>,
selectFreeEntities: (keyof ED)[],
createFreeEntities: (keyof ED)[],
updateFreeEntities: (keyof ED)[],
colorDict: ColorDict<ED>,
makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string) {
const cache = new Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(aspectWrapper, contextBuilder, store);
const location = new Location();
const environment = new Environment();
const relationAuth = new RelationAuth<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(aspectWrapper, contextBuilder, cache,
export function initializeStep2<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(
features: Pick<BasicFeatures<ED, Cxt, FrontCxt, AD>, 'localStorage' | 'environment'>,
aspectWrapper: AspectWrapper<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>,
storageSchema: StorageSchema<ED>,
contextBuilder: () => FrontCxt,
store: CacheStore<ED, FrontCxt>,
actionCascadePathGraph: AuthCascadePath<ED>[],
relationCascadePathGraph: AuthCascadePath<ED>[],
authDeduceRelationMap: AuthDeduceRelationMap<ED>,
selectFreeEntities: (keyof ED)[],
createFreeEntities: (keyof ED)[],
updateFreeEntities: (keyof ED)[],
colorDict: ColorDict<ED>,
getFullDataFn: () => any,
makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string) {
const { localStorage, environment } = features;
const cache = new Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(aspectWrapper, contextBuilder, store, getFullDataFn);
const relationAuth = new RelationAuth<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(contextBuilder, cache,
actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
const runningTree = new RunningTree<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(cache, storageSchema, relationAuth);
const geo = new Geo(aspectWrapper);
const eventBus = new EventBus();
const localStorage = new LocalStorage();
const notification = new Notification();
const message = new Message();
const navigator = new Navigator();
const port = new Port<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>(aspectWrapper);
const style = new Style<ED>(colorDict);
const locales = new Locales(cache, localStorage, environment, 'zh-CN', makeBridgeUrlFn); // 临时性代码,应由上层传入
const contextMenuFactory = new ContextMenuFactory<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(cache, relationAuth, actionCascadePathGraph);
return {
cache,
location,
relationAuth,
runningTree,
locales,
eventBus,
localStorage,
notification,
message,
navigator,
port,
style,
geo,
environment,
contextMenuFactory,
} as BasicFeatures<ED, Cxt, FrontCxt, AD>;
};
}
export function initializeStep1() {
const location = new Location();
const environment = new Environment();
const eventBus = new EventBus();
const localStorage = new LocalStorage();
const notification = new Notification();
const message = new Message();
const navigator = new Navigator();
return {
location,
environment,
eventBus,
notification,
message,
localStorage,
navigator,
}
}
export type BasicFeatures<

View File

@ -11,7 +11,7 @@ import assert from 'assert';
import { I18n, Scope, TranslateOptions } from 'i18n-js';
import { uniq } from 'oak-domain/lib/utils/lodash';
const LS_LNG_KEY = 'ofb-feature-locale-lng';
import { LOCAL_STORAGE_KEYS } from '../constant/constant';
export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt>> extends Feature {
static MINIMAL_LOADING_GAP = 600 * 10000; // 最小加载间歇
@ -36,7 +36,7 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
this.localStorage = localStorage;
this.defaultLng = defaultLng;
this.environment = environment;
const savedLng = localStorage.load(LS_LNG_KEY);
const savedLng = localStorage.load(LOCAL_STORAGE_KEYS.localeLng);
if (savedLng) {
this.language = savedLng;
}
@ -69,7 +69,7 @@ export class Locales<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncCo
const env = await this.environment.getEnv();
const { language } = env;
this.language = language;
this.localStorage.save(LS_LNG_KEY, language);
this.localStorage.save(LOCAL_STORAGE_KEYS.localeLng, language);
}
private resetDataset() {

View File

@ -18,7 +18,6 @@ export class RelationAuth<
> extends Feature {
private cache: Cache<ED, Cxt, FrontCxt, AD>;
private contextBuilder: () => FrontCxt;
private aspectWrapper: AspectWrapper<ED, Cxt, AD>;
private actionCascadePathGraph: AuthCascadePath<ED>[];
private actionCascadePathMap: Record<string, AuthCascadePath<ED>[]>;
private relationCascadePathGraph: AuthCascadePath<ED>[];
@ -35,7 +34,6 @@ export class RelationAuth<
};
constructor(
aspectWrapper: AspectWrapper<ED, Cxt, AD>,
contextBuilder: () => FrontCxt,
cache: Cache<ED, Cxt, FrontCxt, AD>,
actionCascadePathGraph: AuthCascadePath<ED>[],
@ -46,7 +44,6 @@ export class RelationAuth<
updateFreeEntities: (keyof ED)[]
) {
super();
this.aspectWrapper = aspectWrapper;
this.contextBuilder = contextBuilder;
this.cache = cache;
this.actionCascadePathGraph = actionCascadePathGraph;

View File

@ -14,7 +14,7 @@ import { makeIntrinsicCTWs } from 'oak-domain/lib/store/actionDef';
import { createDebugStore, clearMaterializedData } from './debugStore';
import { initialize as initBasicFeatures } from './features';
import { initializeStep1 as initBasicFeaturesStep1, initializeStep2 as initBasicFeaturesStep2 } from './features';
import { intersection } from 'oak-domain/lib/utils/lodash';
import commonAspectDict from 'oak-common-aspect';
import { CommonAspectDict, registerPorts } from 'oak-common-aspect';
@ -70,6 +70,9 @@ export function initialize<
const checkers2 = checkers.concat(intCheckers);
const triggers2 = triggers.concat(intTriggers);
const watchers2 = watchers.concat(intWatchers);
const features1 = initBasicFeaturesStep1();
const debugStore = createDebugStore(
storageSchema,
backendContextBuilder,
@ -85,13 +88,13 @@ export function initialize<
authDeduceRelationMap,
selectFreeEntities,
createFreeEntities,
updateFreeEntities
updateFreeEntities,
(key, data) => features1.localStorage.save(key, data),
(key) => features1.localStorage.load(key)
);
const cacheStore = new CacheStore<ED, FrontCxt>(
storageSchema,
() => debugStore.getCurrentData(),
() => clearMaterializedData(),
storageSchema
);
const wrapper: AspectWrapper<ED, Cxt, CommonAspectDict<ED, Cxt> & AD> = {
@ -116,7 +119,8 @@ export function initialize<
},
};
const features = initBasicFeatures<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>(
const features2 = initBasicFeaturesStep2<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>(
features1,
wrapper,
storageSchema,
() => frontendContextBuilder()(cacheStore),
@ -127,12 +131,14 @@ export function initialize<
selectFreeEntities,
createFreeEntities,
updateFreeEntities,
colorDict);
colorDict,
() => debugStore.getCurrentData());
checkers2.forEach((checker) => cacheStore.registerChecker(checker));
registerPorts(importations || [], exportations || []);
const features = Object.assign(features2, features1)
return {
features,
};

View File

@ -4,16 +4,14 @@ import {
Checker,
StorageSchema,
Connector,
Trigger,
} from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { EntityDict } from 'oak-domain/lib/types/Entity';
import { initialize as initBasicFeatures } from './features';
import { initializeStep1 as initBasicFeaturesStep1, initializeStep2 as initBasicFeaturesStep2 } from './features';
import { makeIntrinsicCTWs } from 'oak-domain/lib/store/actionDef';
import { CommonAspectDict } from 'oak-common-aspect';
import { CacheStore } from './cacheStore/CacheStore';
import { createDynamicCheckers } from 'oak-domain/lib/checkers';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { InitializeOptions } from './types/Initialize';
@ -50,6 +48,8 @@ export function initialize<
const { checkers: intCheckers } = makeIntrinsicCTWs<ED, Cxt, FrontCxt>(storageSchema, actionDict);
const checkers2 = checkers.concat(intCheckers);
const features1 = initBasicFeaturesStep1();
const cacheStore = new CacheStore<ED, FrontCxt>(
storageSchema,
);
@ -66,7 +66,8 @@ export function initialize<
},
};
const features = initBasicFeatures<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>(
const features2 = initBasicFeaturesStep2<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>(
features1,
wrapper,
storageSchema,
() => frontendContextBuilder()(cacheStore),
@ -78,11 +79,13 @@ export function initialize<
createFreeEntities,
updateFreeEntities,
colorDict,
() => '请查看数据库中的数据',
(url, headers) => connector.makeBridgeUrl(url, headers)
);
checkers2.forEach((checker) => cacheStore.registerChecker(checker));
const features = Object.assign(features1, features2);
return {
features,
};