修正了reinforceSelection中的部分无用代码,增加了几个未来用于subscribe的结构定义

This commit is contained in:
Xu Chang 2023-08-29 13:45:19 +08:00
parent a506f2acc2
commit 060c208804
6 changed files with 246 additions and 242 deletions

View File

@ -24,13 +24,12 @@ var CascadeStore = /** @class */ (function (_super) {
} }
CascadeStore.prototype.reinforceSelectionAsync = function (entity, selection, context, option) { CascadeStore.prototype.reinforceSelectionAsync = function (entity, selection, context, option) {
return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__awaiter(this, void 0, void 0, function () {
var noRelationDestEntities, rewriterPromises; var rewriterPromises;
var _this = this; var _this = this;
return tslib_1.__generator(this, function (_a) { return tslib_1.__generator(this, function (_a) {
switch (_a.label) { switch (_a.label) {
case 0: case 0:
noRelationDestEntities = []; this.reinforceSelectionInner(entity, selection, context);
this.reinforceSelectionInner(entity, selection, context, noRelationDestEntities);
rewriterPromises = this.selectionRewriters.map(function (ele) { return ele(_this.getSchema(), entity, selection, context); }); rewriterPromises = this.selectionRewriters.map(function (ele) { return ele(_this.getSchema(), entity, selection, context); });
if (!(rewriterPromises.length > 0)) return [3 /*break*/, 2]; if (!(rewriterPromises.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(rewriterPromises)]; return [4 /*yield*/, Promise.all(rewriterPromises)];
@ -44,13 +43,16 @@ var CascadeStore = /** @class */ (function (_super) {
}; };
CascadeStore.prototype.reinforceSelectionSync = function (entity, selection, context, option) { CascadeStore.prototype.reinforceSelectionSync = function (entity, selection, context, option) {
var _this = this; var _this = this;
this.reinforceSelectionInner(entity, selection, context, []); this.reinforceSelectionInner(entity, selection, context);
var rewriterPromises = this.selectionRewriters.map(function (ele) { return ele(_this.getSchema(), entity, selection, context); }); this.selectionRewriters.forEach(function (ele) {
var result = ele(_this.getSchema(), entity, selection, context);
(0, assert_1.default)(!(result instanceof Promise));
});
}; };
CascadeStore.prototype.reinforceSelectionInner = function (entity, selection, context, noRelationDestEntities) { CascadeStore.prototype.reinforceSelectionInner = function (entity, selection, context) {
var _this = this; var _this = this;
var filter = selection.filter, data = selection.data, sorter = selection.sorter; var filter = selection.filter, data = selection.data, sorter = selection.sorter;
var checkNode = function (projectionNode, attrs) { var assignNecessaryProjectionAttrs = function (projectionNode, attrs) {
attrs.forEach(function (attr) { attrs.forEach(function (attr) {
var _a; var _a;
if (!projectionNode.hasOwnProperty(attr)) { if (!projectionNode.hasOwnProperty(attr)) {
@ -60,29 +62,24 @@ var CascadeStore = /** @class */ (function (_super) {
} }
}); });
}; };
var relevantIds = []; var checkFilterNode = function (entity2, filterNode, projectionNode, toBeAssignNode, filterNodeDict) {
if (filter) {
var toBeAssignNode_1 = {}; // 用来记录在表达式中涉及到的结点
// filter当中所关联到的属性必须在projection中
var filterNodeDict_1 = {};
var checkFilterNode_1 = function (entity2, filterNode, projectionNode) {
var _a, e_1, _b, _c, _d, _e, _f; var _a, e_1, _b, _c, _d, _e, _f;
var necessaryAttrs = ['id']; var necessaryAttrs = ['id'];
for (var attr in filterNode) { for (var attr in filterNode) {
if (attr === '#id') { if (attr === '#id') {
(0, assert_1.default)(!filterNodeDict_1[filterNode[attr]], "projection\u4E2D\u7ED3\u70B9\u7684id\u6709\u91CD\u590D, ".concat(filterNode[attr])); (0, assert_1.default)(!filterNodeDict[filterNode[attr]], "projection\u4E2D\u7ED3\u70B9\u7684id\u6709\u91CD\u590D, ".concat(filterNode[attr]));
Object.assign(filterNodeDict_1, (_a = {}, Object.assign(filterNodeDict, (_a = {},
_a[filterNode[attr]] = projectionNode, _a[filterNode[attr]] = projectionNode,
_a)); _a));
if (toBeAssignNode_1[filterNode[attr]]) { if (toBeAssignNode[filterNode[attr]]) {
checkNode(projectionNode, toBeAssignNode_1[filterNode[attr]]); assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode[filterNode[attr]]);
} }
} }
else if (['$and', '$or'].includes(attr)) { else if (['$and', '$or'].includes(attr)) {
try { try {
for (var _g = (e_1 = void 0, tslib_1.__values(filterNode[attr])), _h = _g.next(); !_h.done; _h = _g.next()) { for (var _g = (e_1 = void 0, tslib_1.__values(filterNode[attr])), _h = _g.next(); !_h.done; _h = _g.next()) {
var node = _h.value; var node = _h.value;
checkFilterNode_1(entity2, node, projectionNode); checkFilterNode(entity2, node, projectionNode, toBeAssignNode, filterNodeDict);
} }
} }
catch (e_1_1) { e_1 = { error: e_1_1 }; } catch (e_1_1) { e_1 = { error: e_1_1 }; }
@ -94,7 +91,7 @@ var CascadeStore = /** @class */ (function (_super) {
} }
} }
else if (attr === '$not') { else if (attr === '$not') {
checkFilterNode_1(entity2, filterNode[attr], projectionNode); checkFilterNode(entity2, filterNode[attr], projectionNode, toBeAssignNode, filterNodeDict);
} }
else if (attr === '$text') { else if (attr === '$text') {
// 全文检索首先要有fulltext索引其次要把fulltext的相关属性加到projection里 // 全文检索首先要有fulltext索引其次要把fulltext的相关属性加到projection里
@ -108,17 +105,17 @@ var CascadeStore = /** @class */ (function (_super) {
var exprResult = (0, types_1.getAttrRefInExpression)(filterNode[attr]); var exprResult = (0, types_1.getAttrRefInExpression)(filterNode[attr]);
for (var nodeName in exprResult) { for (var nodeName in exprResult) {
if (nodeName === '#current') { if (nodeName === '#current') {
checkNode(projectionNode, exprResult[nodeName]); assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
} }
else if (filterNodeDict_1[nodeName]) { else if (filterNodeDict[nodeName]) {
checkNode(filterNodeDict_1[nodeName], exprResult[nodeName]); assignNecessaryProjectionAttrs(filterNodeDict[nodeName], exprResult[nodeName]);
} }
else { else {
if (toBeAssignNode_1[nodeName]) { if (toBeAssignNode[nodeName]) {
(_c = toBeAssignNode_1[nodeName]).push.apply(_c, tslib_1.__spreadArray([], tslib_1.__read(exprResult[nodeName]), false)); (_c = toBeAssignNode[nodeName]).push.apply(_c, tslib_1.__spreadArray([], tslib_1.__read(exprResult[nodeName]), false));
} }
else { else {
Object.assign(toBeAssignNode_1, (_d = {}, Object.assign(toBeAssignNode, (_d = {},
_d[nodeName] = exprResult[nodeName], _d[nodeName] = exprResult[nodeName],
_d)); _d));
} }
@ -140,7 +137,7 @@ var CascadeStore = /** @class */ (function (_super) {
}, },
_e)); _e));
} }
checkFilterNode_1(attr, filterNode[attr], projectionNode[attr]); checkFilterNode(attr, filterNode[attr], projectionNode[attr], toBeAssignNode, filterNodeDict);
} }
else if (typeof rel === 'string') { else if (typeof rel === 'string') {
necessaryAttrs.push("".concat(attr, "Id")); necessaryAttrs.push("".concat(attr, "Id"));
@ -151,17 +148,22 @@ var CascadeStore = /** @class */ (function (_super) {
}, },
_f)); _f));
} }
checkFilterNode_1(rel, filterNode[attr], projectionNode[attr]); checkFilterNode(rel, filterNode[attr], projectionNode[attr], toBeAssignNode, filterNodeDict);
} }
else if (rel instanceof Array) { else if (rel instanceof Array) {
// 现在filter中还不支持一对多的语义先放着吧 // 子查询,暂时不处理
} }
} }
} }
checkNode(projectionNode, necessaryAttrs); assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
} }
}; };
checkFilterNode_1(entity, filter, data); var relevantIds = [];
if (filter) {
var toBeAssignNode = {}; // 用来记录在表达式中涉及到的结点
// filter当中所关联到的属性必须在projection中
var filterNodeDict = {};
checkFilterNode(entity, filter, data, toBeAssignNode, filterNodeDict);
relevantIds = (0, filter_2.getRelevantIds)(filter); relevantIds = (0, filter_2.getRelevantIds)(filter);
} }
// sorter感觉现在取不取影响不大前端的list直接获取返回的ids了先不管之 // sorter感觉现在取不取影响不大前端的list直接获取返回的ids了先不管之
@ -179,7 +181,7 @@ var CascadeStore = /** @class */ (function (_super) {
_a[projectionNode[attr]] = projectionNode, _a[projectionNode[attr]] = projectionNode,
_a)); _a));
if (toBeAssignNode2[projectionNode[attr]]) { if (toBeAssignNode2[projectionNode[attr]]) {
checkNode(projectionNode, toBeAssignNode2[projectionNode[attr]]); assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode2[projectionNode[attr]]);
} }
} }
else { else {
@ -187,10 +189,10 @@ var CascadeStore = /** @class */ (function (_super) {
var exprResult = (0, types_1.getAttrRefInExpression)(projectionNode[attr]); var exprResult = (0, types_1.getAttrRefInExpression)(projectionNode[attr]);
for (var nodeName in exprResult) { for (var nodeName in exprResult) {
if (nodeName === '#current') { if (nodeName === '#current') {
checkNode(projectionNode, exprResult[nodeName]); assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
} }
else if (projectionNodeDict[nodeName]) { else if (projectionNodeDict[nodeName]) {
checkNode(projectionNodeDict[nodeName], exprResult[nodeName]); assignNecessaryProjectionAttrs(projectionNodeDict[nodeName], exprResult[nodeName]);
} }
else { else {
if (toBeAssignNode2[nodeName]) { if (toBeAssignNode2[nodeName]) {
@ -219,18 +221,18 @@ var CascadeStore = /** @class */ (function (_super) {
checkProjectionNode(rel, projectionNode[attr]); checkProjectionNode(rel, projectionNode[attr]);
} }
else if (rel instanceof Array && !attr.endsWith('$$aggr')) { else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
var data_1 = projectionNode[attr].data; var _d = projectionNode[attr], data_1 = _d.data, filter_3 = _d.filter;
if (rel[1]) { if (rel[1]) {
checkNode(data_1, [rel[1]]); assignNecessaryProjectionAttrs(data_1, [rel[1]]);
} }
else { else {
checkNode(data_1, ['entity', 'entityId']); assignNecessaryProjectionAttrs(data_1, ['entity', 'entityId']);
} }
_this.reinforceSelectionInner(rel[0], projectionNode[attr], context, noRelationDestEntities); _this.reinforceSelectionInner(rel[0], projectionNode[attr], context);
} }
} }
} }
checkNode(projectionNode, necessaryAttrs); assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
} }
// 如果对象中指向一对多的Modi此时加上指向Modi的projection // 如果对象中指向一对多的Modi此时加上指向Modi的projection
if (_this.getSchema()[entity2].toModi) { if (_this.getSchema()[entity2].toModi) {
@ -281,7 +283,6 @@ var CascadeStore = /** @class */ (function (_super) {
}, },
}); });
} }
noRelationDestEntities.push(entity2);
} }
} }
}; };

View File

@ -190,4 +190,9 @@ export declare type AuthDeduceRelationMap<ED extends EntityDict> = {
}; };
export declare type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[]; export declare type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[];
export declare type OtmKey<K extends string> = K | `${K}$${number}`; export declare type OtmKey<K extends string> = K | `${K}$${number}`;
export interface SubDataDef<ED extends EntityDict, T extends keyof ED> {
id: string;
entity: T;
filter: ED[T]['Selection']['filter'];
}
export {}; export {};

View File

@ -12,3 +12,4 @@ exports.initinctiveAttributes = [exports.PrimaryKeyAttribute, exports.TriggerDat
; ;
; ;
; ;
;

View File

@ -30,59 +30,38 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
private operationRewriters: OperationRewriter<ED, AsyncContext<ED> | SyncContext<ED>>[] = []; private operationRewriters: OperationRewriter<ED, AsyncContext<ED> | SyncContext<ED>>[] = [];
private async reinforceSelectionAsync<Cxt extends AsyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) { private async reinforceSelectionAsync<Cxt extends AsyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) {
const noRelationDestEntities: string[] = [];
this.reinforceSelectionInner(entity, selection, context, noRelationDestEntities);
this.reinforceSelectionInner(entity, selection, context);
const rewriterPromises = this.selectionRewriters.map( const rewriterPromises = this.selectionRewriters.map(
ele => ele(this.getSchema(), entity, selection, context) ele => ele(this.getSchema(), entity, selection, context)
); );
// 这个设计每次都要取actionAuth的数据感觉不是很优雅。by Xc 20230722
// 这个设计废除了前台页面自己来取需要的actionAUth通过cache的缓存和KeepFresh机制来减少对后台数据的访问
/* if (noRelationDestEntities.length > 0 && !option.dontCollect) {
rewriterPromises.push(
context.select('actionAuth', {
data: {
id: 1,
deActions: 1,
destEntity: 1,
paths: 1,
relationId: 1,
},
filter: {
relationId: {
$exists: false,
},
destEntity: {
$in: noRelationDestEntities,
},
},
}, {}) as any
);
} */
if (rewriterPromises.length > 0) { if (rewriterPromises.length > 0) {
await Promise.all(rewriterPromises); await Promise.all(rewriterPromises);
} }
} }
private reinforceSelectionSync<Cxt extends SyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) { private reinforceSelectionSync<Cxt extends SyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) {
this.reinforceSelectionInner(entity, selection, context, []); this.reinforceSelectionInner(entity, selection, context);
const rewriterPromises = this.selectionRewriters.map( this.selectionRewriters.forEach(
ele => ele(this.getSchema(), entity, selection, context) ele => {
const result = ele(this.getSchema(), entity, selection, context);
assert(!(result instanceof Promise));
}
); );
} }
private reinforceSelectionInner<Cxt extends AsyncContext<ED> | SyncContext<ED>, OP extends SelectOption>( private reinforceSelectionInner<Cxt extends AsyncContext<ED> | SyncContext<ED>, OP extends SelectOption>(
entity: keyof ED, entity: keyof ED,
selection: ED[keyof ED]['Selection'], selection: ED[keyof ED]['Selection'],
context: Cxt, context: Cxt
noRelationDestEntities: string[]) { ) {
const { filter, data, sorter } = selection; const { filter, data, sorter } = selection;
const checkNode = (projectionNode: ED[keyof ED]['Selection']['data'], attrs: string[]) => { const assignNecessaryProjectionAttrs = (projectionNode: ED[keyof ED]['Selection']['data'], attrs: string[]) => {
attrs.forEach( attrs.forEach(
(attr) => { (attr) => {
if (!projectionNode.hasOwnProperty(attr)) { if (!projectionNode.hasOwnProperty(attr)) {
@ -94,12 +73,13 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
); );
}; };
let relevantIds: string[] = [];
if (filter) { const checkFilterNode = (
const toBeAssignNode: Record<string, string[]> = {}; // 用来记录在表达式中涉及到的结点 entity2: keyof ED,
// filter当中所关联到的属性必须在projection中 filterNode: ED[keyof ED]['Selection']['filter'],
const filterNodeDict: Record<string, ED[keyof ED]['Selection']['data']> = {}; projectionNode: ED[keyof ED]['Selection']['data'],
const checkFilterNode = (entity2: keyof ED, filterNode: ED[keyof ED]['Selection']['filter'], projectionNode: ED[keyof ED]['Selection']['data']) => { toBeAssignNode: Record<string, string[]>,
filterNodeDict: Record<string, ED[keyof ED]['Selection']['data']>) => {
const necessaryAttrs: string[] = ['id']; const necessaryAttrs: string[] = ['id'];
for (const attr in filterNode) { for (const attr in filterNode) {
if (attr === '#id') { if (attr === '#id') {
@ -108,16 +88,16 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
[filterNode[attr]!]: projectionNode, [filterNode[attr]!]: projectionNode,
}); });
if (toBeAssignNode[filterNode[attr]!]) { if (toBeAssignNode[filterNode[attr]!]) {
checkNode(projectionNode, toBeAssignNode[filterNode[attr]!]); assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode[filterNode[attr]!]);
} }
} }
else if (['$and', '$or'].includes(attr)) { else if (['$and', '$or'].includes(attr)) {
for (const node of filterNode[attr]!) { for (const node of filterNode[attr]!) {
checkFilterNode(entity2, node, projectionNode); checkFilterNode(entity2, node, projectionNode, toBeAssignNode, filterNodeDict);
} }
} }
else if (attr === '$not') { else if (attr === '$not') {
checkFilterNode(entity2, filterNode[attr]!, projectionNode); checkFilterNode(entity2, filterNode[attr]!, projectionNode, toBeAssignNode, filterNodeDict);
} }
else if (attr === '$text') { else if (attr === '$text') {
// 全文检索首先要有fulltext索引其次要把fulltext的相关属性加到projection里 // 全文检索首先要有fulltext索引其次要把fulltext的相关属性加到projection里
@ -135,10 +115,10 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
const exprResult = getAttrRefInExpression(filterNode[attr]!); const exprResult = getAttrRefInExpression(filterNode[attr]!);
for (const nodeName in exprResult) { for (const nodeName in exprResult) {
if (nodeName === '#current') { if (nodeName === '#current') {
checkNode(projectionNode, exprResult[nodeName]); assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
} }
else if (filterNodeDict[nodeName]) { else if (filterNodeDict[nodeName]) {
checkNode(filterNodeDict[nodeName], exprResult[nodeName]); assignNecessaryProjectionAttrs(filterNodeDict[nodeName], exprResult[nodeName]);
} }
else { else {
if (toBeAssignNode[nodeName]) { if (toBeAssignNode[nodeName]) {
@ -167,7 +147,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
}); });
} }
checkFilterNode(attr, filterNode[attr]!, projectionNode[attr]); checkFilterNode(attr, filterNode[attr]!, projectionNode[attr], toBeAssignNode, filterNodeDict);
} }
else if (typeof rel === 'string') { else if (typeof rel === 'string') {
necessaryAttrs.push(`${attr}Id`); necessaryAttrs.push(`${attr}Id`);
@ -178,18 +158,24 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
}); });
} }
checkFilterNode(rel, filterNode[attr]!, projectionNode[attr]); checkFilterNode(rel, filterNode[attr]!, projectionNode[attr], toBeAssignNode, filterNodeDict);
} }
else if (rel instanceof Array) { else if (rel instanceof Array) {
// 现在filter中还不支持一对多的语义先放着吧 // 子查询,暂时不处理
} }
} }
} }
checkNode(projectionNode, necessaryAttrs); assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
} }
}; };
checkFilterNode(entity, filter, data); let relevantIds: string[] = [];
if (filter) {
const toBeAssignNode: Record<string, string[]> = {}; // 用来记录在表达式中涉及到的结点
// filter当中所关联到的属性必须在projection中
const filterNodeDict: Record<string, ED[keyof ED]['Selection']['data']> = {};
checkFilterNode(entity, filter, data, toBeAssignNode, filterNodeDict);
relevantIds = getRelevantIds(filter); relevantIds = getRelevantIds(filter);
} }
@ -208,7 +194,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
[projectionNode[attr]!]: projectionNode, [projectionNode[attr]!]: projectionNode,
}); });
if (toBeAssignNode2[projectionNode[attr]!]) { if (toBeAssignNode2[projectionNode[attr]!]) {
checkNode(projectionNode, toBeAssignNode2[projectionNode[attr]!]); assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode2[projectionNode[attr]!]);
} }
} }
else { else {
@ -216,10 +202,10 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
const exprResult = getAttrRefInExpression(projectionNode[attr]!); const exprResult = getAttrRefInExpression(projectionNode[attr]!);
for (const nodeName in exprResult) { for (const nodeName in exprResult) {
if (nodeName === '#current') { if (nodeName === '#current') {
checkNode(projectionNode, exprResult[nodeName]); assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
} }
else if (projectionNodeDict[nodeName]) { else if (projectionNodeDict[nodeName]) {
checkNode(projectionNodeDict[nodeName], exprResult[nodeName]); assignNecessaryProjectionAttrs(projectionNodeDict[nodeName], exprResult[nodeName]);
} }
else { else {
if (toBeAssignNode2[nodeName]) { if (toBeAssignNode2[nodeName]) {
@ -248,18 +234,18 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
checkProjectionNode(rel, projectionNode[attr]); checkProjectionNode(rel, projectionNode[attr]);
} }
else if (rel instanceof Array && !attr.endsWith('$$aggr')) { else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
const { data } = projectionNode[attr]; const { data, filter } = projectionNode[attr];
if (rel[1]) { if (rel[1]) {
checkNode(data, [rel[1]]); assignNecessaryProjectionAttrs(data, [rel[1]]);
} }
else { else {
checkNode(data, ['entity', 'entityId']); assignNecessaryProjectionAttrs(data, ['entity', 'entityId']);
} }
this.reinforceSelectionInner(rel[0], projectionNode[attr], context, noRelationDestEntities); this.reinforceSelectionInner(rel[0], projectionNode[attr], context);
} }
} }
} }
checkNode(projectionNode, necessaryAttrs); assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
} }
// 如果对象中指向一对多的Modi此时加上指向Modi的projection // 如果对象中指向一对多的Modi此时加上指向Modi的projection
@ -312,7 +298,6 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} as ED['userRelation']['Selection'], } as ED['userRelation']['Selection'],
}); });
} }
noRelationDestEntities.push(entity2 as string);
} }
} }
}; };

View File

@ -1,4 +1,4 @@
import { EntityDict } from "./Entity"; import { EntityDict, SubDataDef } from "./Entity";
import { OpRecord } from "./Entity"; import { OpRecord } from "./Entity";
import { AsyncContext } from "../store/AsyncRowStore"; import { AsyncContext } from "../store/AsyncRowStore";
@ -12,4 +12,10 @@ export interface AspectWrapper<ED extends EntityDict, Cxt extends AsyncContext<E
opRecords?: OpRecord<ED>[]; opRecords?: OpRecord<ED>[];
message?: string | null; message?: string | null;
}>; }>;
/* sub: (data: Array<SubDataDef<ED, keyof ED>>) => Promise<void>;
unsub: (ids: string[]) => Promise<void>;
registerSubCallback: (callback: (records: OpRecord<ED>[]) => void) => Promise<void>; */
}; };

View File

@ -268,3 +268,9 @@ export type AuthDeduceRelationMap<ED extends EntityDict> = {
export type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[]; export type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[];
// 一对多的键值的扩展 // 一对多的键值的扩展
export type OtmKey<K extends string> = K | `${K}$${number}`; export type OtmKey<K extends string> = K | `${K}$${number}`;
export interface SubDataDef<ED extends EntityDict, T extends keyof ED> {
id: string;
entity: T,
filter: ED[T]['Selection']['filter'],
};