修正了取missed rows的框架级逻辑
This commit is contained in:
parent
358ffb4114
commit
8301bd8606
|
|
@ -47,6 +47,7 @@ var Cache = /** @class */ (function (_super) {
|
|||
return [4 /*yield*/, this.aspectWrapper.exec(name, params)];
|
||||
case 1:
|
||||
_a = _b.sent(), result = _a.result, opRecords = _a.opRecords, message = _a.message;
|
||||
this.refreshing = false;
|
||||
callback && callback(result, opRecords);
|
||||
if (opRecords) {
|
||||
this.sync(opRecords);
|
||||
|
|
@ -85,7 +86,6 @@ var Cache = /** @class */ (function (_super) {
|
|||
}, callback)];
|
||||
case 1:
|
||||
_a = (_b.sent()).result, ids = _a.ids, count = _a.count;
|
||||
this.refreshing = false;
|
||||
selection2 = Object.assign({}, selection, {
|
||||
filter: {
|
||||
id: {
|
||||
|
|
@ -133,7 +133,6 @@ var Cache = /** @class */ (function (_super) {
|
|||
}, callback)];
|
||||
case 1:
|
||||
result = _a.sent();
|
||||
this.refreshing = false;
|
||||
return [2 /*return*/, result];
|
||||
}
|
||||
});
|
||||
|
|
@ -245,6 +244,7 @@ var Cache = /** @class */ (function (_super) {
|
|||
if (err instanceof Exception_1.OakRowUnexistedException) {
|
||||
if (!this.refreshing && !allowMiss) {
|
||||
var missedRows_1 = err.getRows();
|
||||
this.refreshing = true;
|
||||
this.exec('fetchRows', missedRows_1, function (result, opRecords) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||||
var _a, _b, record, d, missedRows_2, missedRows_2_1, mr;
|
||||
var e_3, _c, e_4, _d;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
|
|||
addNamedSorter(sorter: NamedSorterItem<ED, T>, refresh?: boolean): void;
|
||||
removeNamedSorter(sorter: NamedSorterItem<ED, T>, refresh?: boolean): void;
|
||||
removeNamedSorterByName(name: string, refresh: boolean): void;
|
||||
getFreshValue(context: FrontCxt, allowMiss?: boolean): Array<Partial<ED[T]['Schema']>>;
|
||||
getFreshValue(context: FrontCxt): Array<Partial<ED[T]['Schema']>>;
|
||||
addItem(item: Omit<ED[T]['CreateSingle']['data'], 'id'>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): void;
|
||||
removeItem(id: string, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): void;
|
||||
recoverItem(id: string): void;
|
||||
|
|
@ -149,7 +149,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
|
|||
};
|
||||
addChild(path: string, node: SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD>): void;
|
||||
removeChild(path: string): void;
|
||||
getFreshValue(context?: FrontCxt, allowMiss?: boolean): Partial<ED[T]['Schema']> | undefined;
|
||||
getFreshValue(context?: FrontCxt): Partial<ED[T]['Schema']> | undefined;
|
||||
doBeforeTrigger(): Promise<void>;
|
||||
doAfterTrigger(): Promise<void>;
|
||||
create(data: Partial<Omit<ED[T]['CreateSingle']['data'], 'id'>>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): void;
|
||||
|
|
@ -174,6 +174,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
|
|||
declare class VirtualNode<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt>> extends Feature {
|
||||
private dirty;
|
||||
private executing;
|
||||
private loading;
|
||||
private children;
|
||||
constructor(path?: string, parent?: VirtualNode<ED, Cxt, FrontCxt, AD>);
|
||||
getActiveModies(child: any): undefined;
|
||||
|
|
@ -219,7 +220,6 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
|
|||
private schema;
|
||||
private authDict;
|
||||
private root;
|
||||
private refreshing;
|
||||
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, schema: StorageSchema<ED>, authDict: AuthDefDict<ED>);
|
||||
createNode<T extends keyof ED>(options: CreateNodeOptions<ED, T>): SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD> | VirtualNode<ED, Cxt, FrontCxt, AD>;
|
||||
private findNode;
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ var Node = /** @class */ (function (_super) {
|
|||
return !!this.dirty;
|
||||
};
|
||||
Node.prototype.isLoading = function () {
|
||||
return this.loading;
|
||||
return this.loading || (!!this.parent && this.parent.isLoading());
|
||||
};
|
||||
Node.prototype.setLoading = function (loading) {
|
||||
this.loading = loading;
|
||||
|
|
@ -568,7 +568,7 @@ var ListNode = /** @class */ (function (_super) {
|
|||
this.publish();
|
||||
}
|
||||
};
|
||||
ListNode.prototype.getFreshValue = function (context, allowMiss) {
|
||||
ListNode.prototype.getFreshValue = function (context) {
|
||||
var _this = this;
|
||||
/**
|
||||
* 满足当前结点的数据应当是所有满足当前filter条件且ids在当前ids中的数据
|
||||
|
|
@ -579,7 +579,7 @@ var ListNode = /** @class */ (function (_super) {
|
|||
data: data,
|
||||
filter: filter,
|
||||
sorter: sorter,
|
||||
}, context, allowMiss);
|
||||
}, context, this.isLoading());
|
||||
return result.filter(function (ele) { var _a; return ele.$$createAt$$ === 1 || ((_a = _this.ids) === null || _a === void 0 ? void 0 : _a.includes(ele.id)); });
|
||||
};
|
||||
ListNode.prototype.addItem = function (item, beforeExecute, afterExecute) {
|
||||
|
|
@ -966,12 +966,14 @@ var ListNode = /** @class */ (function (_super) {
|
|||
this.refresh(currentPage, undefined, append);
|
||||
};
|
||||
ListNode.prototype.clean = function () {
|
||||
this.dirty = undefined;
|
||||
this.updates = {};
|
||||
for (var k in this.children) {
|
||||
this.children[k].clean();
|
||||
if (this.dirty) {
|
||||
this.dirty = undefined;
|
||||
this.updates = {};
|
||||
for (var k in this.children) {
|
||||
this.children[k].clean();
|
||||
}
|
||||
this.publish();
|
||||
}
|
||||
this.publish();
|
||||
};
|
||||
ListNode.prototype.getChildOperation = function (child) {
|
||||
var childId = '';
|
||||
|
|
@ -1075,7 +1077,7 @@ var SingleNode = /** @class */ (function (_super) {
|
|||
SingleNode.prototype.removeChild = function (path) {
|
||||
(0, lodash_1.unset)(this.children, path);
|
||||
};
|
||||
SingleNode.prototype.getFreshValue = function (context, allowMiss) {
|
||||
SingleNode.prototype.getFreshValue = function (context) {
|
||||
var projection = this.getProjection(context, false);
|
||||
var id = this.id;
|
||||
if (projection) {
|
||||
|
|
@ -1084,7 +1086,7 @@ var SingleNode = /** @class */ (function (_super) {
|
|||
filter: {
|
||||
id: id,
|
||||
},
|
||||
}, context, allowMiss);
|
||||
}, context, this.isLoading());
|
||||
return result[0];
|
||||
}
|
||||
};
|
||||
|
|
@ -1376,12 +1378,14 @@ var SingleNode = /** @class */ (function (_super) {
|
|||
});
|
||||
};
|
||||
SingleNode.prototype.clean = function () {
|
||||
this.dirty = undefined;
|
||||
this.operation = undefined;
|
||||
for (var child in this.children) {
|
||||
this.children[child].clean();
|
||||
if (this.dirty) {
|
||||
this.dirty = undefined;
|
||||
this.operation = undefined;
|
||||
for (var child in this.children) {
|
||||
this.children[child].clean();
|
||||
}
|
||||
this.publish();
|
||||
}
|
||||
this.publish();
|
||||
};
|
||||
SingleNode.prototype.getFilter = function () {
|
||||
return {
|
||||
|
|
@ -1509,6 +1513,7 @@ var VirtualNode = /** @class */ (function (_super) {
|
|||
tslib_1.__extends(VirtualNode, _super);
|
||||
function VirtualNode(path, parent) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.loading = false;
|
||||
_this.dirty = false;
|
||||
_this.executing = false;
|
||||
_this.children = {};
|
||||
|
|
@ -1562,14 +1567,26 @@ var VirtualNode = /** @class */ (function (_super) {
|
|||
};
|
||||
VirtualNode.prototype.refresh = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var err_3;
|
||||
var _this = this;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, Promise.all(Object.keys(this.children).map(function (ele) { return _this.children[ele].refresh(); }))];
|
||||
case 0:
|
||||
this.loading = true;
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, Promise.all(Object.keys(this.children).map(function (ele) { return _this.children[ele].refresh(); }))];
|
||||
case 2:
|
||||
_a.sent();
|
||||
this.loading = false;
|
||||
this.publish();
|
||||
return [2 /*return*/];
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
err_3 = _a.sent();
|
||||
this.loading = false;
|
||||
throw err_3;
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -1613,12 +1630,7 @@ var VirtualNode = /** @class */ (function (_super) {
|
|||
return this.executing;
|
||||
};
|
||||
VirtualNode.prototype.isLoading = function () {
|
||||
for (var ele in this.children) {
|
||||
if (this.children[ele].isLoading()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return this.loading;
|
||||
};
|
||||
VirtualNode.prototype.doBeforeTrigger = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
|
|
@ -1704,7 +1716,6 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
tslib_1.__extends(RunningTree, _super);
|
||||
function RunningTree(cache, schema, authDict) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.refreshing = false;
|
||||
// this.aspectWrapper = aspectWrapper;
|
||||
_this.cache = cache;
|
||||
_this.schema = schema;
|
||||
|
|
@ -1832,7 +1843,7 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
if (opers) {
|
||||
this.cache.redoOperation(opers, context_1);
|
||||
}
|
||||
var value = node.getFreshValue(context_1, this.refreshing);
|
||||
var value = node.getFreshValue(context_1);
|
||||
context_1.rollback();
|
||||
return value;
|
||||
}
|
||||
|
|
@ -1901,7 +1912,6 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
switch (_a.label) {
|
||||
case 0:
|
||||
node = this.findNode(path);
|
||||
this.refreshing = true;
|
||||
if (!(node instanceof ListNode)) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, node.refresh(1, true)];
|
||||
case 1:
|
||||
|
|
@ -1913,9 +1923,7 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
case 3:
|
||||
_a.sent();
|
||||
_a.label = 4;
|
||||
case 4:
|
||||
this.refreshing = false;
|
||||
return [2 /*return*/];
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -1927,12 +1935,10 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
switch (_a.label) {
|
||||
case 0:
|
||||
node = this.findNode(path);
|
||||
this.refreshing = true;
|
||||
(0, assert_1.assert)(node instanceof ListNode);
|
||||
return [4 /*yield*/, node.loadMore()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
this.refreshing = false;
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
|
|
@ -2061,7 +2067,7 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
};
|
||||
RunningTree.prototype.execute = function (path, action) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var node, operations, entities, result, err_3;
|
||||
var node, operations, entities, result, err_4;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
|
|
@ -2086,7 +2092,6 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
operations = node.composeOperations();
|
||||
entities = (0, lodash_1.uniq)(operations.filter(function (ele) { return !!ele; }).map(function (ele) { return ele.entity; }));
|
||||
(0, assert_1.assert)(entities.length === 1);
|
||||
this.refreshing = true;
|
||||
return [4 /*yield*/, this.cache.operate(entities[0], operations
|
||||
.filter(function (ele) { return !!ele; })
|
||||
.map(function (ele) { return ele.operation; }), undefined, function () {
|
||||
|
|
@ -2096,15 +2101,14 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
})];
|
||||
case 3:
|
||||
result = _a.sent();
|
||||
this.refreshing = false;
|
||||
return [4 /*yield*/, node.doAfterTrigger()];
|
||||
case 4:
|
||||
_a.sent();
|
||||
return [2 /*return*/, result];
|
||||
case 5:
|
||||
err_3 = _a.sent();
|
||||
err_4 = _a.sent();
|
||||
node.setExecuting(false);
|
||||
throw err_3;
|
||||
throw err_4;
|
||||
case 6: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ export class Cache<
|
|||
) {
|
||||
try {
|
||||
const { result, opRecords, message } = await this.aspectWrapper.exec(name, params);
|
||||
this.refreshing = false;
|
||||
callback && callback(result, opRecords);
|
||||
if (opRecords) {
|
||||
this.sync(opRecords);
|
||||
|
|
@ -101,7 +102,6 @@ export class Cache<
|
|||
option,
|
||||
getCount,
|
||||
}, callback);
|
||||
this.refreshing = false;
|
||||
|
||||
const selection2 = Object.assign({}, selection, {
|
||||
filter: {
|
||||
|
|
@ -143,7 +143,6 @@ export class Cache<
|
|||
operation,
|
||||
option,
|
||||
}, callback);
|
||||
this.refreshing = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -255,6 +254,7 @@ export class Cache<
|
|||
if (err instanceof OakRowUnexistedException) {
|
||||
if (!this.refreshing && !allowMiss) {
|
||||
const missedRows = err.getRows();
|
||||
this.refreshing = true;
|
||||
this.exec('fetchRows', missedRows, async (result, opRecords) => {
|
||||
// missedRows理论上一定要取到,不能为空集。否则就是程序员有遗漏
|
||||
for (const record of opRecords!) {
|
||||
|
|
|
|||
|
|
@ -268,8 +268,8 @@ abstract class Node<
|
|||
return !!this.dirty;
|
||||
}
|
||||
|
||||
isLoading() {
|
||||
return this.loading;
|
||||
isLoading(): boolean {
|
||||
return this.loading || (!!this.parent && this.parent.isLoading());
|
||||
}
|
||||
|
||||
protected setLoading(loading: boolean) {
|
||||
|
|
@ -691,7 +691,7 @@ class ListNode<
|
|||
}
|
||||
}
|
||||
|
||||
getFreshValue(context: FrontCxt, allowMiss?: boolean): Array<Partial<ED[T]['Schema']>> {
|
||||
getFreshValue(context: FrontCxt): Array<Partial<ED[T]['Schema']>> {
|
||||
/**
|
||||
* 满足当前结点的数据应当是所有满足当前filter条件且ids在当前ids中的数据
|
||||
* 但如果是当前事务create的行则例外(当前页面上正在create的数据)
|
||||
|
|
@ -702,7 +702,7 @@ class ListNode<
|
|||
data,
|
||||
filter,
|
||||
sorter,
|
||||
}, context, allowMiss);
|
||||
}, context, this.isLoading());
|
||||
return result.filter(
|
||||
ele => ele.$$createAt$$ === 1 || this.ids?.includes(ele.id!)
|
||||
);
|
||||
|
|
@ -1043,13 +1043,15 @@ class ListNode<
|
|||
}
|
||||
|
||||
clean() {
|
||||
this.dirty = undefined;
|
||||
this.updates = {};
|
||||
|
||||
for (const k in this.children) {
|
||||
this.children[k].clean();
|
||||
if (this.dirty) {
|
||||
this.dirty = undefined;
|
||||
this.updates = {};
|
||||
|
||||
for (const k in this.children) {
|
||||
this.children[k].clean();
|
||||
}
|
||||
this.publish();
|
||||
}
|
||||
this.publish();
|
||||
}
|
||||
|
||||
getChildOperation(child: SingleNode<ED, T, Cxt, FrontCxt, AD>) {
|
||||
|
|
@ -1188,7 +1190,7 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
unset(this.children, path);
|
||||
}
|
||||
|
||||
getFreshValue(context?: FrontCxt, allowMiss?: boolean): Partial<ED[T]['Schema']> | undefined {
|
||||
getFreshValue(context?: FrontCxt): Partial<ED[T]['Schema']> | undefined {
|
||||
const projection = this.getProjection(context, false);
|
||||
const { id } = this;
|
||||
if (projection) {
|
||||
|
|
@ -1197,7 +1199,7 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
filter: {
|
||||
id,
|
||||
},
|
||||
}, context, allowMiss);
|
||||
}, context, this.isLoading());
|
||||
return result[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -1444,13 +1446,15 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
}
|
||||
|
||||
clean() {
|
||||
this.dirty = undefined;
|
||||
this.operation = undefined;
|
||||
|
||||
for (const child in this.children) {
|
||||
this.children[child]!.clean();
|
||||
if (this.dirty) {
|
||||
this.dirty = undefined;
|
||||
this.operation = undefined;
|
||||
|
||||
for (const child in this.children) {
|
||||
this.children[child]!.clean();
|
||||
}
|
||||
this.publish();
|
||||
}
|
||||
this.publish();
|
||||
}
|
||||
|
||||
getFilter(): ED[T]['Selection']['filter'] | undefined {
|
||||
|
|
@ -1584,6 +1588,7 @@ class VirtualNode<
|
|||
> extends Feature {
|
||||
private dirty: boolean;
|
||||
private executing: boolean;
|
||||
private loading = false;
|
||||
private children: Record<string, SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD> | VirtualNode<ED, Cxt, FrontCxt, AD>>;
|
||||
constructor(path?: string, parent?: VirtualNode<ED, Cxt, FrontCxt, AD>) {
|
||||
super();
|
||||
|
|
@ -1641,12 +1646,20 @@ class VirtualNode<
|
|||
return this.dirty;
|
||||
}
|
||||
async refresh() {
|
||||
await Promise.all(
|
||||
Object.keys(this.children).map(
|
||||
ele => this.children[ele].refresh()
|
||||
)
|
||||
);
|
||||
this.publish();
|
||||
this.loading = true;
|
||||
try {
|
||||
await Promise.all(
|
||||
Object.keys(this.children).map(
|
||||
ele => this.children[ele].refresh()
|
||||
)
|
||||
);
|
||||
this.loading = false;
|
||||
this.publish();
|
||||
}
|
||||
catch (err) {
|
||||
this.loading = false;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
composeOperations(): Array<{ entity: keyof ED, operation: ED[keyof ED]['Operation'] }> | undefined {
|
||||
/**
|
||||
|
|
@ -1691,12 +1704,7 @@ class VirtualNode<
|
|||
}
|
||||
|
||||
isLoading() {
|
||||
for (const ele in this.children) {
|
||||
if (this.children[ele].isLoading()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return this.loading;
|
||||
}
|
||||
|
||||
async doBeforeTrigger() {
|
||||
|
|
@ -1772,7 +1780,6 @@ export class RunningTree<
|
|||
| ListNode<ED, keyof ED, Cxt, FrontCxt, AD>
|
||||
| VirtualNode<ED, Cxt, FrontCxt, AD>
|
||||
>;
|
||||
private refreshing = false;
|
||||
|
||||
constructor(
|
||||
cache: Cache<ED, Cxt, FrontCxt, AD>,
|
||||
|
|
@ -1945,7 +1952,7 @@ export class RunningTree<
|
|||
if (opers) {
|
||||
this.cache.redoOperation(opers, context);
|
||||
}
|
||||
const value = node.getFreshValue(context, this.refreshing);
|
||||
const value = node.getFreshValue(context);
|
||||
context.rollback();
|
||||
return value;
|
||||
}
|
||||
|
|
@ -2056,21 +2063,17 @@ export class RunningTree<
|
|||
|
||||
async refresh(path: string) {
|
||||
const node = this.findNode(path);
|
||||
this.refreshing = true;
|
||||
if (node instanceof ListNode) {
|
||||
await node.refresh(1, true);
|
||||
} else if (node) {
|
||||
await node.refresh();
|
||||
}
|
||||
this.refreshing = false;
|
||||
}
|
||||
|
||||
async loadMore(path: string) {
|
||||
const node = this.findNode(path);
|
||||
this.refreshing = true;
|
||||
assert(node instanceof ListNode);
|
||||
await node.loadMore();
|
||||
this.refreshing = false;
|
||||
}
|
||||
|
||||
getPagination(path: string) {
|
||||
|
|
@ -2262,7 +2265,6 @@ export class RunningTree<
|
|||
);
|
||||
assert(entities.length === 1);
|
||||
|
||||
this.refreshing = true;
|
||||
const result = await this.cache.operate(
|
||||
entities[0],
|
||||
operations
|
||||
|
|
@ -2275,7 +2277,6 @@ export class RunningTree<
|
|||
node.setExecuting(false);
|
||||
}
|
||||
);
|
||||
this.refreshing = false;
|
||||
|
||||
await node.doAfterTrigger();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue