重新整理了localStorage相关的key值
This commit is contained in:
parent
90cd65d0a0
commit
b232d0c4c4
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
export declare const LOCAL_STORAGE_KEYS: {
|
||||
debugStore: string;
|
||||
debugStoreStat: string;
|
||||
localeLng: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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*/];
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
};
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue