Merge branch 'sub' into dev

This commit is contained in:
Xu Chang 2023-09-04 11:21:49 +08:00
commit ba054ad1f8
34 changed files with 632 additions and 163 deletions

View File

@ -1,4 +1,4 @@
import { EntityDict, OperateOption, SelectOption, OpRecord, AspectWrapper, CheckerType, Aspect, StorageSchema, Checker, SubDataDef } from 'oak-domain/lib/types';
import { EntityDict, OperateOption, SelectOption, OpRecord, AspectWrapper, CheckerType, Aspect, StorageSchema, Checker } 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';
@ -101,7 +101,5 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
commit(): void;
rollback(): void;
buildContext(): FrontCxt;
sub(data: Array<SubDataDef<ED, keyof ED>>, callback: (records: OpRecord<ED>[], ids: string[]) => void): Promise<void>;
unsub(ids: string[]): Promise<void>;
}
export {};

View File

@ -636,16 +636,6 @@ var Cache = /** @class */ (function (_super) {
Cache.prototype.buildContext = function () {
return this.contextBuilder();
};
Cache.prototype.sub = function (data, callback) {
var _this = this;
return this.aspectWrapper.sub(data, function (records, ids) {
_this.sync(records),
callback(records, ids);
});
};
Cache.prototype.unsub = function (ids) {
return this.aspectWrapper.unsub(ids);
};
return Cache;
}(Feature_1.Feature));
exports.Cache = Cache;

View File

@ -17,11 +17,15 @@ import { Navigator } from './navigator';
import { Port } from './port';
import { RelationAuth } from './relationAuth';
import { Style } from './style';
import { SubScriber } from './subscriber';
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 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>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, colorDict: ColorDict<ED>, getFullDataFn: () => any, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string, selectFreeEntities?: (keyof ED)[], createFreeEntities?: (keyof ED)[], updateFreeEntities?: (keyof ED)[], savedEntities?: (keyof ED)[], keepFreshPeriod?: number): {
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>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, actionCascadePathGraph: AuthCascadePath<ED>[], relationCascadePathGraph: AuthCascadePath<ED>[], authDeduceRelationMap: AuthDeduceRelationMap<ED>, colorDict: ColorDict<ED>, getFullDataFn: () => any, getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>, makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string, selectFreeEntities?: (keyof ED)[], createFreeEntities?: (keyof ED)[], updateFreeEntities?: (keyof ED)[], savedEntities?: (keyof ED)[], keepFreshPeriod?: number): {
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>>;
@ -30,6 +34,7 @@ export declare function initializeStep2<ED extends EntityDict & BaseEntityDict,
style: Style<ED>;
geo: Geo<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
contextMenuFactory: ContextMenuFactory<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
subscriber: SubScriber<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
};
export declare function initializeStep1(): {
location: Location;
@ -56,4 +61,5 @@ export declare type BasicFeatures<ED extends EntityDict & BaseEntityDict, Cxt ex
style: Style<ED>;
geo: Geo<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
contextMenuFactory: ContextMenuFactory<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
subscriber: SubScriber<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
};

View File

@ -14,9 +14,10 @@ var navigator_1 = require("./navigator");
var port_1 = require("./port");
var relationAuth_1 = require("./relationAuth");
var style_1 = require("./style");
var subscriber_1 = require("./subscriber");
var contextMenuFactory_1 = require("./contextMenuFactory");
var geo_1 = require("./geo");
function initializeStep2(features, aspectWrapper, storageSchema, frontendContextBuilder, checkers, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, colorDict, getFullDataFn, makeBridgeUrlFn, selectFreeEntities, createFreeEntities, updateFreeEntities, savedEntities, keepFreshPeriod) {
function initializeStep2(features, aspectWrapper, storageSchema, frontendContextBuilder, checkers, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, colorDict, getFullDataFn, getSubscribePointFn, makeBridgeUrlFn, selectFreeEntities, createFreeEntities, updateFreeEntities, savedEntities, keepFreshPeriod) {
var localStorage = features.localStorage, environment = features.environment;
var cache = new cache_1.Cache(storageSchema, aspectWrapper, frontendContextBuilder, checkers, getFullDataFn, localStorage, savedEntities, keepFreshPeriod);
var relationAuth = new relationAuth_1.RelationAuth(cache, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
@ -26,6 +27,7 @@ function initializeStep2(features, aspectWrapper, storageSchema, frontendContext
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);
var subscriber = new subscriber_1.SubScriber(cache, getSubscribePointFn);
return {
cache: cache,
relationAuth: relationAuth,
@ -35,6 +37,7 @@ function initializeStep2(features, aspectWrapper, storageSchema, frontendContext
style: style,
geo: geo,
contextMenuFactory: contextMenuFactory,
subscriber: subscriber,
};
}
exports.initializeStep2 = initializeStep2;

29
lib/features/subscriber.d.ts vendored Normal file
View File

@ -0,0 +1,29 @@
import { EntityDict, Aspect, OpRecord, SubDataDef } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { Cache } from './cache';
import { SyncContext } from "oak-domain/lib/store/SyncRowStore";
import { Feature } from "../types/Feature";
declare type SubscribeEvent = 'connect' | 'disconnect';
export declare class SubScriber<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 getSubscribePointFn;
private callbackMap;
private socket?;
private socketState;
private eventCallbackMap;
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>);
on(event: SubscribeEvent, callback: () => void): void;
off(event: SubscribeEvent, callback: () => void): void;
private emit;
private initSocketOption;
private login;
private connect;
sub(data: SubDataDef<ED, keyof ED>[], callback?: (records: OpRecord<ED>[], ids: string[]) => void): Promise<void>;
unsub(ids: string[]): Promise<void>;
}
export {};

20
lib/features/subscriber.dev.d.ts vendored Normal file
View File

@ -0,0 +1,20 @@
import { EntityDict, Aspect, OpRecord, SubDataDef } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { Cache } from './cache';
import { SyncContext } from "oak-domain/lib/store/SyncRowStore";
import { Feature } from "../types/Feature";
declare type SubscribeEvent = 'connect' | 'disconnect';
export declare class SubScriber<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 eventCallbackMap;
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>);
on(event: SubscribeEvent, callback: () => void): void;
off(event: SubscribeEvent, callback: () => void): void;
sub(data: SubDataDef<ED, keyof ED>[], callback: (records: OpRecord<ED>[], ids: string[]) => void): Promise<void>;
unsub(ids: string[]): Promise<void>;
}
export {};

View File

@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubScriber = void 0;
var tslib_1 = require("tslib");
var lodash_1 = require("oak-domain/lib/utils/lodash");
var Feature_1 = require("../types/Feature");
var SubScriber = /** @class */ (function (_super) {
tslib_1.__extends(SubScriber, _super);
function SubScriber(cache, getSubscribePointFn) {
var _this = _super.call(this) || this;
_this.eventCallbackMap = {
connect: [],
disconnect: [],
};
return _this;
}
SubScriber.prototype.on = function (event, callback) {
this.eventCallbackMap[event].push(callback);
};
SubScriber.prototype.off = function (event, callback) {
(0, lodash_1.pull)(this.eventCallbackMap[event], callback);
};
SubScriber.prototype.sub = function (data, callback) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
console.log('data subscribe 在dev模式下不起作用');
return [2 /*return*/];
});
});
};
SubScriber.prototype.unsub = function (ids) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/];
});
});
};
return SubScriber;
}(Feature_1.Feature));
exports.SubScriber = SubScriber;

173
lib/features/subscriber.js Normal file
View File

@ -0,0 +1,173 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubScriber = void 0;
var tslib_1 = require("tslib");
var assert_1 = tslib_1.__importDefault(require("assert"));
var lodash_1 = require("oak-domain/lib/utils/lodash");
var socket_io_1 = tslib_1.__importDefault(require("../utils/socket.io/socket.io"));
var Feature_1 = require("../types/Feature");
var SubScriber = /** @class */ (function (_super) {
tslib_1.__extends(SubScriber, _super);
function SubScriber(cache, getSubscribePointFn) {
var _this = _super.call(this) || this;
_this.callbackMap = {};
_this.socketState = 'unconnected';
_this.eventCallbackMap = {
connect: [],
disconnect: [],
};
_this.cache = cache;
_this.getSubscribePointFn = getSubscribePointFn;
return _this;
}
SubScriber.prototype.on = function (event, callback) {
this.eventCallbackMap[event].push(callback);
};
SubScriber.prototype.off = function (event, callback) {
(0, lodash_1.pull)(this.eventCallbackMap[event], callback);
};
SubScriber.prototype.emit = function (event) {
this.eventCallbackMap[event].forEach(function (ele) { return ele(); });
};
SubScriber.prototype.initSocketOption = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, url, path, socket;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.getSubscribePointFn()];
case 1:
_a = _b.sent(), url = _a.url, path = _a.path;
socket = (0, socket_io_1.default)(url, {
path: path,
});
this.socket = socket;
return [2 /*return*/];
}
});
});
};
SubScriber.prototype.login = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/];
});
});
};
SubScriber.prototype.connect = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var optionInited, socket;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
optionInited = false;
if (!!this.socket) return [3 /*break*/, 2];
return [4 /*yield*/, this.initSocketOption()];
case 1:
_a.sent();
optionInited = true;
_a.label = 2;
case 2:
socket = this.socket;
return [2 /*return*/, new Promise(function (resolve, reject) {
/**
* https://socket.io/zh-CN/docs/v4/client-socket-instance/
*/
socket.on('connect', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
// 验证身份
this.socketState = 'connected';
this.emit('connect');
socket.off('connect');
socket.on('disconnect', function () {
_this.socketState = 'unconnected';
_this.emit('disconnect');
socket.removeAllListeners();
if (Object.keys(_this.callbackMap).length > 0) {
_this.connect();
}
});
return [4 /*yield*/, this.login()];
case 1:
_a.sent();
resolve(undefined);
return [2 /*return*/];
}
});
}); });
if (!optionInited) {
var count_1 = 0;
socket.on('connect_error', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
count_1++;
if (!(count_1 > 10)) return [3 /*break*/, 2];
// 可能socket地址改变了刷新重连
socket.removeAllListeners();
socket.disconnect();
this.socket = undefined;
return [4 /*yield*/, this.connect()];
case 1:
_a.sent();
resolve(undefined);
_a.label = 2;
case 2: return [2 /*return*/];
}
});
}); });
}
socket.connect();
})];
}
});
});
};
SubScriber.prototype.sub = function (data, callback) {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var ids;
var _this = this;
return tslib_1.__generator(this, function (_b) {
ids = data.map(function (ele) { return ele.id; });
if (callback) {
ids.forEach(function (id) {
(0, assert_1.default)(!_this.callbackMap[id], "[subscriber]\u6CE8\u518C\u56DE\u8C03\u7684id".concat(id, "\u53D1\u751F\u91CD\u590D"));
_this.callbackMap[id] = callback;
});
}
if (this.socketState === 'unconnected') {
this.connect();
}
else if (this.socketState === 'connected') {
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.emit('sub', data);
}
return [2 /*return*/];
});
});
};
SubScriber.prototype.unsub = function (ids) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
return tslib_1.__generator(this, function (_a) {
ids.forEach(function (id) { return (0, lodash_1.omit)(_this.callbackMap, id); });
if (this.socketState === 'connected') {
this.socket.emit('unsub', ids);
}
if (this.socketState !== 'unconnected') {
if (Object.keys(this.callbackMap).length === 0) {
this.socket.disconnect();
this.socket.removeAllListeners();
this.socketState = 'unconnected';
}
}
return [2 /*return*/];
});
});
};
return SubScriber;
}(Feature_1.Feature));
exports.SubScriber = SubScriber;

View File

@ -32,6 +32,7 @@ export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt e
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>;
subscriber: import("./features/subscriber").SubScriber<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
} & {
location: import("./features/location").Location;
environment: import("./features/environment").Environment;

View File

@ -73,19 +73,10 @@ function initialize(storageSchema, frontendContextBuilder, backendContextBuilder
}
});
}); },
/**
* dev模式下订阅数据没有意义单用户模式
* @param data
* @returns
*/
sub: function (data, callback) {
return Promise.resolve();
},
unsub: function (ids) {
return Promise.resolve();
},
};
var features2 = (0, features_1.initializeStep2)(features1, wrapper, storageSchema, frontendContextBuilder, checkers2, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, colorDict, function () { return debugStore.getCurrentData(); }, undefined, selectFreeEntities, createFreeEntities, updateFreeEntities, cacheSavedEntities, cacheKeepFreshPeriod);
var features2 = (0, features_1.initializeStep2)(features1, wrapper, storageSchema, frontendContextBuilder, checkers2, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, colorDict, function () { return debugStore.getCurrentData(); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, ({ url: '', path: '' })];
}); }); }, undefined, selectFreeEntities, createFreeEntities, updateFreeEntities, cacheSavedEntities, cacheKeepFreshPeriod);
(0, oak_common_aspect_2.registerPorts)(importations || [], exportations || []);
var features = Object.assign(features2, features1);
return {

View File

@ -19,7 +19,7 @@ import { InitializeOptions } from './types/Initialize';
* @param actionDict
* @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>): {
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, FrontCxt>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, option: InitializeOptions<ED>): {
features: {
location: import("./features/location").Location;
environment: import("./features/environment").Environment;
@ -37,5 +37,6 @@ export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt e
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>;
subscriber: import("./features/subscriber").SubScriber<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
};
};

View File

@ -4,7 +4,6 @@ exports.initialize = void 0;
var tslib_1 = require("tslib");
var features_1 = require("./features");
var actionDef_1 = require("oak-domain/lib/store/actionDef");
var subscriber_1 = tslib_1.__importDefault(require("./utils/subscriber"));
/**
* @param storageSchema
* @param createFeatures
@ -24,7 +23,6 @@ function initialize(storageSchema, frontendContextBuilder, connector, checkers,
var intCheckers = (0, actionDef_1.makeIntrinsicCTWs)(storageSchema, actionDict).checkers;
var checkers2 = checkers.concat(intCheckers);
var features1 = (0, features_1.initializeStep1)();
var subscriber = new subscriber_1.default(connector.getSubscribeRouter());
var wrapper = {
exec: function (name, params) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var context, _a, result, opRecords, message;
@ -43,14 +41,8 @@ function initialize(storageSchema, frontendContextBuilder, connector, checkers,
}
});
}); },
sub: function (data, callback) {
return subscriber.sub(data, callback);
},
unsub: function (ids) {
return subscriber.unsub(ids);
},
};
var features2 = (0, features_1.initializeStep2)(features1, wrapper, storageSchema, frontendContextBuilder, checkers2, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, colorDict, function () { return '请查看数据库中的数据'; }, function (url, headers) { return connector.makeBridgeUrl(url, headers); }, selectFreeEntities, createFreeEntities, updateFreeEntities, cacheSavedEntities, cacheKeepFreshPeriod);
var features2 = (0, features_1.initializeStep2)(features1, wrapper, storageSchema, frontendContextBuilder, checkers2, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, colorDict, function () { return '请查看数据库中的数据'; }, function () { return connector.getSubscribePoint(); }, function (url, headers) { return connector.makeBridgeUrl(url, headers); }, selectFreeEntities, createFreeEntities, updateFreeEntities, cacheSavedEntities, cacheKeepFreshPeriod);
var features = Object.assign(features1, features2);
return {
features: features,

View File

@ -144,16 +144,16 @@ var oakBehavior = Behavior({
});
});
},
sub: function (type, callback) {
subEvent: function (type, callback) {
this.features.eventBus.sub(type, callback);
},
unsub: function (type, callback) {
unsubEvent: function (type, callback) {
this.features.eventBus.unsub(type, callback);
},
pub: function (type, option) {
pubEvent: function (type, option) {
this.features.eventBus.pub(type, option);
},
unsubAll: function (type) {
unsubAllEvents: function (type) {
this.features.eventBus.unsubAll(type);
},
save: function (key, item) {
@ -448,6 +448,12 @@ var oakBehavior = Behavior({
},
loadMissedLocales: function (key) {
this.features.locales.loadMissedLocale(key);
},
subData: function (data, callback) {
return this.features.subscriber.sub(data, callback);
},
unSubData: function (ids) {
return this.features.subscriber.unsub(ids);
}
},
observers: {

View File

@ -23,16 +23,16 @@ var OakComponentBase = /** @class */ (function (_super) {
return page_common_1.onPathSet.call(this, this.oakOption);
};
OakComponentBase.prototype.triggerEvent = function (name, detail, options) { };
OakComponentBase.prototype.sub = function (type, callback) {
OakComponentBase.prototype.subEvent = function (type, callback) {
this.features.eventBus.sub(type, callback);
};
OakComponentBase.prototype.unsub = function (type, callback) {
OakComponentBase.prototype.unsubEvent = function (type, callback) {
this.features.eventBus.unsub(type, callback);
};
OakComponentBase.prototype.pub = function (type, options) {
OakComponentBase.prototype.pubEvent = function (type, options) {
this.features.eventBus.pub(type, options);
};
OakComponentBase.prototype.unsubAll = function (type) {
OakComponentBase.prototype.unsubAllEvents = function (type) {
this.features.eventBus.unsubAll(type);
};
OakComponentBase.prototype.save = function (key, item) {
@ -389,6 +389,12 @@ var OakComponentBase = /** @class */ (function (_super) {
this.features.runningTree.setCurrentPage(path2, currentPage);
}
};
OakComponentBase.prototype.subData = function (data, callback) {
return this.features.subscriber.sub(data, callback);
};
OakComponentBase.prototype.unSubData = function (ids) {
return this.features.subscriber.unsub(ids);
};
return OakComponentBase;
}(react_1.default.PureComponent));
function translateListeners(listeners) {

View File

@ -3,3 +3,6 @@ export declare class OakEnvInitializedFailure extends OakException<any> {
error: Error;
constructor(err: Error);
}
export declare class OakSubscriberConnectError extends OakException<any> {
constructor(url: string, path?: string);
}

View File

@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OakEnvInitializedFailure = void 0;
exports.OakSubscriberConnectError = exports.OakEnvInitializedFailure = void 0;
var tslib_1 = require("tslib");
var types_1 = require("oak-domain/lib/types");
var OakEnvInitializedFailure = /** @class */ (function (_super) {
@ -13,3 +13,12 @@ var OakEnvInitializedFailure = /** @class */ (function (_super) {
return OakEnvInitializedFailure;
}(types_1.OakException));
exports.OakEnvInitializedFailure = OakEnvInitializedFailure;
;
var OakSubscriberConnectError = /** @class */ (function (_super) {
tslib_1.__extends(OakSubscriberConnectError, _super);
function OakSubscriberConnectError(url, path) {
return _super.call(this, "Subscriber\u65E0\u6CD5\u8FDE\u63A5\u4E0Asocket\uFF0C\u8BF7\u8054\u7CFB\u6280\u672F\u4EBA\u5458\u3002url\u300C".concat(url, "\u300D\uFF0Cpath\u300C").concat(path, "\u300D")) || this;
}
return OakSubscriberConnectError;
}(types_1.OakException));
exports.OakSubscriberConnectError = OakSubscriberConnectError;

12
lib/types/Page.d.ts vendored
View File

@ -1,5 +1,5 @@
/// <reference types="wechat-miniprogram" />
import { Aspect, EntityDict, CheckerType, AggregationResult } from "oak-domain/lib/types";
import { Aspect, EntityDict, CheckerType, AggregationResult, SubDataDef, OpRecord } 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 './Feature';
@ -137,10 +137,10 @@ export declare type OakNavigateToParameters<ED extends EntityDict & BaseEntityDi
};
export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
setDisablePulldownRefresh: (able: boolean) => void;
sub: (type: string, callback: Function) => void;
unsub: (type: string, callback: Function) => void;
pub: (type: string, options?: any) => void;
unsubAll: (type: string) => void;
subEvent: (type: string, callback: Function) => void;
unsubEvent: (type: string, callback: Function) => void;
pubEvent: (type: string, options?: any) => void;
unsubAllEvents: (type: string) => void;
save: (key: string, item: any) => void;
load: (key: string) => any;
clear: () => void;
@ -174,6 +174,8 @@ export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntity
}[] | undefined;
refresh: () => Promise<void>;
aggregate: (aggregation: ED[T]['Aggregation']) => Promise<AggregationResult<ED[T]['Schema']>>;
subData: (data: SubDataDef<ED, keyof ED>[], callback?: (records: OpRecord<ED>[], ids: string[]) => void) => Promise<void>;
unSubData: (ids: string[]) => Promise<void>;
};
export declare type OakSingleComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
setId: (id: string) => void;

View File

@ -1,2 +1,3 @@
import { io } from "socket.io-client";
import { io, Socket } from "socket.io-client";
export default io;
export { Socket, };

View File

@ -1,4 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Socket = void 0;
var socket_io_client_1 = require("socket.io-client");
Object.defineProperty(exports, "Socket", { enumerable: true, get: function () { return socket_io_client_1.Socket; } });
exports.default = socket_io_client_1.io;

View File

@ -1,2 +1,3 @@
import { io } from "socket.io-client";
import { io, Socket } from "socket.io-client";
export default io;
export { Socket, };

View File

@ -1,4 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Socket = void 0;
var socket_io_client_1 = require("socket.io-client");
Object.defineProperty(exports, "Socket", { enumerable: true, get: function () { return socket_io_client_1.Socket; } });
exports.default = socket_io_client_1.io;

View File

@ -682,15 +682,4 @@ export class Cache<
buildContext() {
return this.contextBuilder!();
}
sub(data: Array<SubDataDef<ED, keyof ED>>, callback: (records: OpRecord<ED>[], ids: string[]) => void) {
return this.aspectWrapper.sub(data, (records, ids) => {
this.sync(records),
callback(records, ids);
});
}
unsub(ids: string[]) {
return this.aspectWrapper.unsub(ids);
}
}

View File

@ -18,30 +18,38 @@ import { Navigator } from './navigator';
import { Port } from './port';
import { RelationAuth } from './relationAuth';
import { Style } from './style';
import { SubScriber } from './subscriber';
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 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>,
frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt,
checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>,
actionCascadePathGraph: AuthCascadePath<ED>[],
relationCascadePathGraph: AuthCascadePath<ED>[],
authDeduceRelationMap: AuthDeduceRelationMap<ED>,
colorDict: ColorDict<ED>,
getFullDataFn: () => any,
makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string,
selectFreeEntities?: (keyof ED)[],
createFreeEntities?: (keyof ED)[],
updateFreeEntities?: (keyof ED)[],
savedEntities?: (keyof ED)[],
keepFreshPeriod?: number) {
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>,
frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt,
checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>,
actionCascadePathGraph: AuthCascadePath<ED>[],
relationCascadePathGraph: AuthCascadePath<ED>[],
authDeduceRelationMap: AuthDeduceRelationMap<ED>,
colorDict: ColorDict<ED>,
getFullDataFn: () => any,
getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>,
makeBridgeUrlFn?: (url: string, headers?: Record<string, string>) => string,
selectFreeEntities?: (keyof ED)[],
createFreeEntities?: (keyof ED)[],
updateFreeEntities?: (keyof ED)[],
savedEntities?: (keyof ED)[],
keepFreshPeriod?: number) {
const { localStorage, environment } = features;
const cache = new Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(storageSchema, aspectWrapper,
const cache = new Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(storageSchema, aspectWrapper,
frontendContextBuilder, checkers, getFullDataFn, localStorage, savedEntities, keepFreshPeriod);
const relationAuth = new RelationAuth<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>(cache,
actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities);
@ -51,6 +59,7 @@ export function initializeStep2<ED extends EntityDict & BaseEntityDict, Cxt exte
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);
const subscriber = new SubScriber(cache, getSubscribePointFn);
return {
cache,
relationAuth,
@ -60,6 +69,7 @@ export function initializeStep2<ED extends EntityDict & BaseEntityDict, Cxt exte
style,
geo,
contextMenuFactory,
subscriber,
};
}
@ -88,20 +98,21 @@ export type BasicFeatures<
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;
runningTree: RunningTree<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
locales: Locales<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
eventBus: EventBus;
localStorage: LocalStorage;
notification: Notification;
message: Message;
navigator: Navigator;
port: Port<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
relationAuth: RelationAuth<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
environment: Environment;
style: Style<ED>;
geo: Geo<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
contextMenuFactory: ContextMenuFactory<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
};
> = {
cache: Cache<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
location: Location;
runningTree: RunningTree<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
locales: Locales<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
eventBus: EventBus;
localStorage: LocalStorage;
notification: Notification;
message: Message;
navigator: Navigator;
port: Port<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
relationAuth: RelationAuth<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
environment: Environment;
style: Style<ED>;
geo: Geo<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
contextMenuFactory: ContextMenuFactory<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
subscriber: SubScriber<ED, Cxt, FrontCxt, AD & CommonAspectDict<ED, Cxt>>;
};

View File

@ -0,0 +1,47 @@
import assert from "assert";
import { EntityDict, Aspect, OpRecord, SubDataDef } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { pull, omit } from 'oak-domain/lib/utils/lodash';
import { Cache } from './cache';
import { SyncContext } from "oak-domain/lib/store/SyncRowStore";
import io, { Socket } from '../utils/socket.io/socket.io';
import { Feature } from "../types/Feature";
type SubscribeEvent = 'connect' | 'disconnect';
export class SubScriber<
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 eventCallbackMap: Record<SubscribeEvent, Array<() => void>> = {
connect: [],
disconnect: [],
};
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>) {
super();
}
on(event: SubscribeEvent, callback: () => void) {
this.eventCallbackMap[event].push(callback);
}
off(event: SubscribeEvent, callback: () => void) {
pull(this.eventCallbackMap[event], callback);
}
async sub(data: SubDataDef<ED, keyof ED>[], callback: (records: OpRecord<ED>[], ids: string[]) => void) {
console.log('data subscribe 在dev模式下不起作用');
}
async unsub(ids: string[]) {
}
}

158
src/features/subscriber.ts Normal file
View File

@ -0,0 +1,158 @@
import assert from "assert";
import { EntityDict, Aspect, OpRecord, SubDataDef } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { pull, omit } from 'oak-domain/lib/utils/lodash';
import { Cache } from './cache';
import { SyncContext } from "oak-domain/lib/store/SyncRowStore";
import io, { Socket } from '../utils/socket.io/socket.io';
import { Feature } from "../types/Feature";
type SubscribeEvent = 'connect' | 'disconnect';
export class SubScriber<
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: Cache<ED, Cxt, FrontCxt, AD>;
private getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>;
private callbackMap: Record<string, (records: OpRecord<ED>[], ids: string[]) => void> = {};
private socket?: Socket;
private socketState: 'connecting' | 'connected' | 'unconnected' = 'unconnected';
private eventCallbackMap: Record<SubscribeEvent, Array<() => void>> = {
connect: [],
disconnect: [],
};
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, getSubscribePointFn: () => Promise<{
url: string;
path: string;
}>) {
super();
this.cache = cache;
this.getSubscribePointFn = getSubscribePointFn;
}
on(event: SubscribeEvent, callback: () => void) {
this.eventCallbackMap[event].push(callback);
}
off(event: SubscribeEvent, callback: () => void) {
pull(this.eventCallbackMap[event], callback);
}
private emit(event: SubscribeEvent) {
this.eventCallbackMap[event].forEach(
ele => ele()
);
}
private async initSocketOption() {
const { url, path } = await this.getSubscribePointFn();
const socket = io(url, {
path,
});
this.socket = socket;
}
private async login() {
}
private async connect() {
let optionInited = false;
if (!this.socket) {
await this.initSocketOption();
optionInited = true;
}
const socket = this.socket!;
return new Promise(
(resolve, reject) => {
/**
* https://socket.io/zh-CN/docs/v4/client-socket-instance/
*/
socket.on('connect', async () => {
// 验证身份
this.socketState = 'connected';
this.emit('connect');
socket.off('connect');
socket.on('disconnect', () => {
this.socketState = 'unconnected';
this.emit('disconnect');
socket.removeAllListeners();
if (Object.keys(this.callbackMap).length > 0) {
this.connect();
}
});
await this.login();
resolve(undefined);
});
if (!optionInited) {
let count = 0;
socket.on('connect_error', async () => {
count ++;
if (count > 10) {
// 可能socket地址改变了刷新重连
socket.removeAllListeners();
socket.disconnect();
this.socket = undefined;
await this.connect();
resolve(undefined);
}
});
}
socket.connect();
}
);
}
async sub(data: SubDataDef<ED, keyof ED>[], callback?: (records: OpRecord<ED>[], ids: string[]) => void) {
const ids = data.map(ele => ele.id);
if (callback) {
ids.forEach(
(id) => {
assert(!this.callbackMap[id], `[subscriber]注册回调的id${id}发生重复`);
this.callbackMap[id] = callback;
}
);
}
if (this.socketState === 'unconnected') {
this.connect();
}
else if (this.socketState === 'connected') {
this.socket?.emit('sub', data);
}
}
async unsub(ids: string[]) {
ids.forEach(
(id) => omit(this.callbackMap, id)
);
if (this.socketState === 'connected') {
this.socket!.emit('unsub', ids);
}
if (this.socketState !== 'unconnected') {
if (Object.keys(this.callbackMap).length === 0) {
this.socket!.disconnect();
this.socket!.removeAllListeners();
this.socketState = 'unconnected';
}
}
}
}

View File

@ -114,18 +114,6 @@ export function initialize<
message: contextBackend.getMessage(),
};
},
/**
* dev模式下订阅数据没有意义
* @param data
* @returns
*/
sub: function (data: SubDataDef<ED, keyof ED>[], callback: (records: OpRecord<ED>[], ids: string[]) => void): Promise<void> {
return Promise.resolve();
},
unsub: function (ids: string[]): Promise<void> {
return Promise.resolve();
},
};
const features2 = initBasicFeaturesStep2<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>(
@ -139,6 +127,7 @@ export function initialize<
authDeduceRelationMap,
colorDict,
() => debugStore.getCurrentData(),
async () => ({ url: '', path: '' }),
undefined,
selectFreeEntities,
createFreeEntities,

View File

@ -16,7 +16,6 @@ import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { InitializeOptions } from './types/Initialize';
import SubScriber from './utils/subscriber';
/**
* @param storageSchema
* @param createFeatures
@ -38,7 +37,7 @@ export function initialize<
>(
storageSchema: StorageSchema<ED>,
frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt,
connector: Connector<ED, Cxt, FrontCxt>,
connector: Connector<ED, FrontCxt>,
checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>,
option: InitializeOptions<ED>
) {
@ -51,7 +50,6 @@ export function initialize<
const features1 = initBasicFeaturesStep1();
const subscriber = new SubScriber<ED>(connector.getSubscribeRouter());
const wrapper: AspectWrapper<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> = {
exec: async (name, params) => {
const context = features2.cache.buildContext();
@ -62,12 +60,6 @@ export function initialize<
message,
};
},
sub: function (data: SubDataDef<ED, keyof ED>[], callback: (records: OpRecord<ED>[], ids: string[]) => void): Promise<void> {
return subscriber.sub(data, callback);
},
unsub: function (ids: string[]): Promise<void> {
return subscriber.unsub(ids);
},
};
const features2 = initBasicFeaturesStep2<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>(
@ -81,6 +73,7 @@ export function initialize<
authDeduceRelationMap,
colorDict,
() => '请查看数据库中的数据',
() => connector.getSubscribePoint(),
(url, headers) => connector.makeBridgeUrl(url, headers),
selectFreeEntities,
createFreeEntities,

View File

@ -227,19 +227,19 @@ const oakBehavior = Behavior<
}
},
sub(type: string, callback: Function) {
subEvent(type: string, callback: Function) {
this.features.eventBus.sub(type, callback);
},
unsub(type: string, callback: Function) {
unsubEvent(type: string, callback: Function) {
this.features.eventBus.unsub(type, callback);
},
pub(type: string, option?: any) {
pubEvent(type: string, option?: any) {
this.features.eventBus.pub(type, option);
},
unsubAll(type: string) {
unsubAllEvents(type: string) {
this.features.eventBus.unsubAll(type);
},
@ -652,6 +652,14 @@ const oakBehavior = Behavior<
loadMissedLocales(key: string) {
this.features.locales.loadMissedLocale(key);
},
subData(data, callback) {
return this.features.subscriber.sub(data, callback);
},
unSubData(ids) {
return this.features.subscriber.unsub(ids);
}
},
observers: {

View File

@ -4,7 +4,7 @@ import React from 'react';
import { withRouter, PullToRefresh } from './platforms/web';
import { get } from 'oak-domain/lib/utils/lodash';
import { CommonAspectDict } from 'oak-common-aspect';
import { Action, Aspect, CheckerType, EntityDict } from 'oak-domain/lib/types';
import { Action, Aspect, CheckerType, EntityDict, OpRecord, SubDataDef } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { BasicFeatures } from './features';
import { NamedFilterItem, NamedSorterItem } from './types/NamedCondition';
@ -79,19 +79,19 @@ abstract class OakComponentBase<
options?: WechatMiniprogram.Component.TriggerEventOption
) { }
sub(type: string, callback: Function) {
subEvent(type: string, callback: Function) {
this.features.eventBus.sub(type, callback);
}
unsub(type: string, callback: Function) {
unsubEvent(type: string, callback: Function) {
this.features.eventBus.unsub(type, callback);
}
pub(type: string, options?: any) {
pubEvent(type: string, options?: any) {
this.features.eventBus.pub(type, options);
}
unsubAll(type: string) {
unsubAllEvents(type: string) {
this.features.eventBus.unsubAll(type);
}
@ -636,6 +636,14 @@ abstract class OakComponentBase<
this.features.runningTree.setCurrentPage(path2, currentPage);
}
}
subData(data: SubDataDef<ED, keyof ED>[], callback?: (records: OpRecord<ED>[], ids: string[]) => void) {
return this.features.subscriber.sub(data, callback);
}
unSubData(ids: string[]) {
return this.features.subscriber.unsub(ids);
}
}
function translateListeners(listeners?: Record<string, (prev: Record<string, any>, next: Record<string, any>) => void>): { fn: React.Component['componentDidUpdate'] } & ThisType<React.Component> {

View File

@ -6,4 +6,10 @@ export class OakEnvInitializedFailure extends OakException<any> {
super('环境初始化失败,请检查授权情况');
this.error = err;
}
};
export class OakSubscriberConnectError extends OakException<any> {
constructor(url: string, path?: string) {
super(`Subscriber无法连接上socket请联系技术人员。url「${url}path「${path}`);
}
}

View File

@ -1,4 +1,4 @@
import { Aspect, EntityDict, CheckerType, AggregationResult } from "oak-domain/lib/types";
import { Aspect, EntityDict, CheckerType, AggregationResult, SubDataDef, OpRecord } 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 './Feature';
@ -327,10 +327,11 @@ export type OakCommonComponentMethods<
T extends keyof ED
> = {
setDisablePulldownRefresh: (able: boolean) => void;
sub: (type: string, callback: Function) => void;
unsub: (type: string, callback: Function) => void;
pub: (type: string, options?: any) => void;
unsubAll: (type: string) => void;
subEvent: (type: string, callback: Function) => void;
unsubEvent: (type: string, callback: Function) => void;
pubEvent: (type: string, options?: any) => void;
unsubAllEvents: (type: string) => void;
save: (key: string, item: any) => void;
load: (key: string) => any;
clear: () => void;
@ -394,6 +395,8 @@ export type OakCommonComponentMethods<
aggregate: (
aggregation: ED[T]['Aggregation']
) => Promise<AggregationResult<ED[T]['Schema']>>;
subData: (data: SubDataDef<ED, keyof ED>[], callback?: (records: OpRecord<ED>[], ids: string[]) => void) => Promise<void>;
unSubData: (ids: string[]) => Promise<void>;
};
export type OakSingleComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {

View File

@ -1,2 +1,5 @@
import { io } from "socket.io-client";
export default io;
import { io, Socket } from "socket.io-client";
export default io;
export {
Socket,
};

View File

@ -1,2 +1,5 @@
import { io } from "socket.io-client";
export default io;
import { io, Socket } from "socket.io-client";
export default io;
export {
Socket,
};

View File

@ -1,25 +0,0 @@
import {
Aspect,
AspectWrapper,
Checker,
StorageSchema,
Connector,
EntityDict,
SubDataDef,
OpRecord,
} from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
export default class SubScriber<ED extends BaseEntityDict & EntityDict>{
private getSubscribePointUrl: string;
constructor(getSubscribePointUrl: string) {
this.getSubscribePointUrl = getSubscribePointUrl;
}
async sub(data: SubDataDef<ED, keyof ED>[], callback: (records: OpRecord<ED>[], ids: string[]) => void) {
}
async unsub(ids: string[]) {
}
}