cache开启和关闭事务机制的再整理

This commit is contained in:
Xu Chang 2024-03-28 14:58:04 +08:00
parent e7ba378388
commit 7715cccca6
22 changed files with 426 additions and 320 deletions

View File

@ -119,7 +119,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void; unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void;
getCachedData(): { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; }; getCachedData(): { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
getFullData(): any; getFullData(): any;
begin(): FrontCxt; begin(allowExists?: boolean): FrontCxt | undefined;
commit(): void; commit(): void;
rollback(): void; rollback(): void;
getContext(): FrontCxt; getContext(): FrontCxt;

View File

@ -486,8 +486,13 @@ export class Cache extends Feature {
getFullData() { getFullData() {
return this.getFullDataFn(); return this.getFullDataFn();
} }
begin() { begin(allowExists) {
assert(!this.context); if (this.context) {
if (allowExists) {
return;
}
assert(false);
}
this.context = this.contextBuilder(); this.context = this.contextBuilder();
this.context.begin(); this.context.begin();
return this.context; return this.context;

View File

@ -74,7 +74,8 @@ export class ContextMenuFactory extends Feature {
} }
getMenusByContext(entity, entityId) { getMenusByContext(entity, entityId) {
assert(this.menus, '应当先调用setMenus才能动态判定菜单'); assert(this.menus, '应当先调用setMenus才能动态判定菜单');
this.cache.begin(); const needRollback = !!this.cache.begin(true);
try {
const menus = this.menus const menus = this.menus
.filter((menu) => { .filter((menu) => {
const { entity: destEntity, paths, action } = menu; const { entity: destEntity, paths, action } = menu;
@ -135,7 +136,12 @@ export class ContextMenuFactory extends Feature {
return false; return false;
}) })
.map((wrapper) => omit(wrapper, ['filtersMaker'])); .map((wrapper) => omit(wrapper, ['filtersMaker']));
this.cache.rollback(); needRollback && this.cache.rollback();
return menus; return menus;
} }
catch (err) {
needRollback && this.cache.rollback();
throw err;
}
}
} }

View File

@ -249,8 +249,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
checkIsModiNode(path: string): boolean; checkIsModiNode(path: string): boolean;
private findNode; private findNode;
destroyNode(path: string): void; destroyNode(path: string): void;
redoBranchOperations(path: string): void; redoBranchOperations(path: string): () => void;
rollbackRedoBranchOperations(): void;
getFreshValue(path: string): Partial<ED[keyof ED]["Schema"]> | Partial<ED[keyof ED]["Schema"]>[] | undefined; getFreshValue(path: string): Partial<ED[keyof ED]["Schema"]> | Partial<ED[keyof ED]["Schema"]>[] | undefined;
isDirty(path: string): boolean; isDirty(path: string): boolean;
addItem<T extends keyof ED>(path: string, data: Omit<ED[T]['CreateSingle']['data'], 'id'> & { addItem<T extends keyof ED>(path: string, data: Omit<ED[T]['CreateSingle']['data'], 'id'> & {

View File

@ -1656,7 +1656,8 @@ export class RunningTree extends Feature {
const paths = path.split('.'); const paths = path.split('.');
const root = this.root[paths[0]]; const root = this.root[paths[0]];
const opers = root.composeOperations(); const opers = root.composeOperations();
this.cache.begin(); const cxt = this.cache.begin();
if (cxt) {
if (opers) { if (opers) {
this.cache.redoOperation(opers); this.cache.redoOperation(opers);
} }
@ -1665,9 +1666,9 @@ export class RunningTree extends Feature {
const modiOperations = (root instanceof SingleNode || root instanceof VirtualNode) && root.getModiOperations(); const modiOperations = (root instanceof SingleNode || root instanceof VirtualNode) && root.getModiOperations();
modiOperations && this.cache.redoOperation(modiOperations); modiOperations && this.cache.redoOperation(modiOperations);
} }
return () => this.cache.rollback();
} }
rollbackRedoBranchOperations() { return () => undefined;
this.cache.rollback();
} }
getFreshValue(path) { getFreshValue(path) {
const node = this.findNode(path); const node = this.findNode(path);

View File

@ -405,7 +405,7 @@ export function reRender(option, extra) {
const localeState = features.locales.getState(); const localeState = features.locales.getState();
if (this.state.oakEntity && this.state.oakFullpath) { if (this.state.oakEntity && this.state.oakFullpath) {
// 现在取数据需要把runningTree上的更新应用了再取判定actions也一样 // 现在取数据需要把runningTree上的更新应用了再取判定actions也一样
this.features.runningTree.redoBranchOperations(this.state.oakFullpath); const cleanFn = this.features.runningTree.redoBranchOperations(this.state.oakFullpath);
try { try {
const rows = this.features.runningTree.getFreshValue(this.state.oakFullpath); const rows = this.features.runningTree.getFreshValue(this.state.oakFullpath);
const oakLegalActions = rows && checkActionsAndCascadeEntities.call(this, rows, option); const oakLegalActions = rows && checkActionsAndCascadeEntities.call(this, rows, option);
@ -459,10 +459,10 @@ export function reRender(option, extra) {
Object.assign(data, extra); Object.assign(data, extra);
} }
this.setState(data); this.setState(data);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
} }
catch (err) { catch (err) {
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
throw err; throw err;
} }
} }

View File

@ -188,10 +188,16 @@ const oakBehavior = Behavior({
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
return value; return value;
}
catch (err) {
cleanFn();
throw err;
}
}, },
checkOperation(entity, { action, data, filter }, checkerTypes) { checkOperation(entity, { action, data, filter }, checkerTypes) {
if (checkerTypes?.includes('relation')) { if (checkerTypes?.includes('relation')) {
@ -459,11 +465,17 @@ const oakBehavior = Behavior({
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations();
assert(!(value instanceof Array)); assert(!(value instanceof Array));
cleanFn();
return value?.$$createAt$$ === 1; return value?.$$createAt$$ === 1;
}
catch (err) {
cleanFn();
throw err;
}
}, },
async aggregate(aggregation) { async aggregate(aggregation) {
return await this.features.cache.aggregate(this.state.oakEntity, aggregation); return await this.features.cache.aggregate(this.state.oakEntity, aggregation);

View File

@ -151,12 +151,18 @@ class OakComponentBase extends React.PureComponent {
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations();
assert(!(value instanceof Array)); assert(!(value instanceof Array));
cleanFn();
return value?.$$createAt$$ === 1; return value?.$$createAt$$ === 1;
} }
catch (err) {
cleanFn();
throw err;
}
}
clean(path) { clean(path) {
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
@ -176,11 +182,17 @@ class OakComponentBase extends React.PureComponent {
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
return value; return value;
} }
catch (err) {
cleanFn();
throw err;
}
}
checkOperation(entity, operation, checkerTypes) { checkOperation(entity, operation, checkerTypes) {
if (checkerTypes?.includes('relation')) { if (checkerTypes?.includes('relation')) {
return this.features.relationAuth.checkRelation(entity, operation) && this.features.cache.checkOperation(entity, operation, checkerTypes); return this.features.relationAuth.checkRelation(entity, operation) && this.features.cache.checkOperation(entity, operation, checkerTypes);

View File

@ -119,7 +119,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void; unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void;
getCachedData(): { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; }; getCachedData(): { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
getFullData(): any; getFullData(): any;
begin(): FrontCxt; begin(allowExists?: boolean): FrontCxt | undefined;
commit(): void; commit(): void;
rollback(): void; rollback(): void;
getContext(): FrontCxt; getContext(): FrontCxt;

View File

@ -489,8 +489,13 @@ class Cache extends Feature_1.Feature {
getFullData() { getFullData() {
return this.getFullDataFn(); return this.getFullDataFn();
} }
begin() { begin(allowExists) {
(0, assert_1.assert)(!this.context); if (this.context) {
if (allowExists) {
return;
}
(0, assert_1.assert)(false);
}
this.context = this.contextBuilder(); this.context = this.contextBuilder();
this.context.begin(); this.context.begin();
return this.context; return this.context;

View File

@ -77,7 +77,8 @@ class ContextMenuFactory extends Feature_1.Feature {
} }
getMenusByContext(entity, entityId) { getMenusByContext(entity, entityId) {
(0, assert_1.assert)(this.menus, '应当先调用setMenus才能动态判定菜单'); (0, assert_1.assert)(this.menus, '应当先调用setMenus才能动态判定菜单');
this.cache.begin(); const needRollback = !!this.cache.begin(true);
try {
const menus = this.menus const menus = this.menus
.filter((menu) => { .filter((menu) => {
const { entity: destEntity, paths, action } = menu; const { entity: destEntity, paths, action } = menu;
@ -138,8 +139,13 @@ class ContextMenuFactory extends Feature_1.Feature {
return false; return false;
}) })
.map((wrapper) => (0, lodash_1.omit)(wrapper, ['filtersMaker'])); .map((wrapper) => (0, lodash_1.omit)(wrapper, ['filtersMaker']));
this.cache.rollback(); needRollback && this.cache.rollback();
return menus; return menus;
} }
catch (err) {
needRollback && this.cache.rollback();
throw err;
}
}
} }
exports.ContextMenuFactory = ContextMenuFactory; exports.ContextMenuFactory = ContextMenuFactory;

View File

@ -249,8 +249,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
checkIsModiNode(path: string): boolean; checkIsModiNode(path: string): boolean;
private findNode; private findNode;
destroyNode(path: string): void; destroyNode(path: string): void;
redoBranchOperations(path: string): void; redoBranchOperations(path: string): () => void;
rollbackRedoBranchOperations(): void;
getFreshValue(path: string): Partial<ED[keyof ED]["Schema"]> | Partial<ED[keyof ED]["Schema"]>[] | undefined; getFreshValue(path: string): Partial<ED[keyof ED]["Schema"]> | Partial<ED[keyof ED]["Schema"]>[] | undefined;
isDirty(path: string): boolean; isDirty(path: string): boolean;
addItem<T extends keyof ED>(path: string, data: Omit<ED[T]['CreateSingle']['data'], 'id'> & { addItem<T extends keyof ED>(path: string, data: Omit<ED[T]['CreateSingle']['data'], 'id'> & {

View File

@ -1659,7 +1659,8 @@ class RunningTree extends Feature_1.Feature {
const paths = path.split('.'); const paths = path.split('.');
const root = this.root[paths[0]]; const root = this.root[paths[0]];
const opers = root.composeOperations(); const opers = root.composeOperations();
this.cache.begin(); const cxt = this.cache.begin();
if (cxt) {
if (opers) { if (opers) {
this.cache.redoOperation(opers); this.cache.redoOperation(opers);
} }
@ -1668,9 +1669,9 @@ class RunningTree extends Feature_1.Feature {
const modiOperations = (root instanceof SingleNode || root instanceof VirtualNode) && root.getModiOperations(); const modiOperations = (root instanceof SingleNode || root instanceof VirtualNode) && root.getModiOperations();
modiOperations && this.cache.redoOperation(modiOperations); modiOperations && this.cache.redoOperation(modiOperations);
} }
return () => this.cache.rollback();
} }
rollbackRedoBranchOperations() { return () => undefined;
this.cache.rollback();
} }
getFreshValue(path) { getFreshValue(path) {
const node = this.findNode(path); const node = this.findNode(path);

View File

@ -409,7 +409,7 @@ function reRender(option, extra) {
const localeState = features.locales.getState(); const localeState = features.locales.getState();
if (this.state.oakEntity && this.state.oakFullpath) { if (this.state.oakEntity && this.state.oakFullpath) {
// 现在取数据需要把runningTree上的更新应用了再取判定actions也一样 // 现在取数据需要把runningTree上的更新应用了再取判定actions也一样
this.features.runningTree.redoBranchOperations(this.state.oakFullpath); const cleanFn = this.features.runningTree.redoBranchOperations(this.state.oakFullpath);
try { try {
const rows = this.features.runningTree.getFreshValue(this.state.oakFullpath); const rows = this.features.runningTree.getFreshValue(this.state.oakFullpath);
const oakLegalActions = rows && checkActionsAndCascadeEntities.call(this, rows, option); const oakLegalActions = rows && checkActionsAndCascadeEntities.call(this, rows, option);
@ -463,10 +463,10 @@ function reRender(option, extra) {
Object.assign(data, extra); Object.assign(data, extra);
} }
this.setState(data); this.setState(data);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
} }
catch (err) { catch (err) {
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
throw err; throw err;
} }
} }

View File

@ -191,10 +191,16 @@ const oakBehavior = Behavior({
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
return value; return value;
}
catch (err) {
cleanFn();
throw err;
}
}, },
checkOperation(entity, { action, data, filter }, checkerTypes) { checkOperation(entity, { action, data, filter }, checkerTypes) {
if (checkerTypes?.includes('relation')) { if (checkerTypes?.includes('relation')) {
@ -462,11 +468,17 @@ const oakBehavior = Behavior({
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations();
(0, assert_1.assert)(!(value instanceof Array)); (0, assert_1.assert)(!(value instanceof Array));
cleanFn();
return value?.$$createAt$$ === 1; return value?.$$createAt$$ === 1;
}
catch (err) {
cleanFn();
throw err;
}
}, },
async aggregate(aggregation) { async aggregate(aggregation) {
return await this.features.cache.aggregate(this.state.oakEntity, aggregation); return await this.features.cache.aggregate(this.state.oakEntity, aggregation);

View File

@ -156,12 +156,18 @@ class OakComponentBase extends react_1.default.PureComponent {
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations();
(0, assert_1.assert)(!(value instanceof Array)); (0, assert_1.assert)(!(value instanceof Array));
cleanFn();
return value?.$$createAt$$ === 1; return value?.$$createAt$$ === 1;
} }
catch (err) {
cleanFn();
throw err;
}
}
clean(path) { clean(path) {
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
@ -181,11 +187,17 @@ class OakComponentBase extends react_1.default.PureComponent {
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
return value; return value;
} }
catch (err) {
cleanFn();
throw err;
}
}
checkOperation(entity, operation, checkerTypes) { checkOperation(entity, operation, checkerTypes) {
if (checkerTypes?.includes('relation')) { if (checkerTypes?.includes('relation')) {
return this.features.relationAuth.checkRelation(entity, operation) && this.features.cache.checkOperation(entity, operation, checkerTypes); return this.features.relationAuth.checkRelation(entity, operation) && this.features.cache.checkOperation(entity, operation, checkerTypes);

View File

@ -655,8 +655,13 @@ export class Cache<
return this.getFullDataFn(); return this.getFullDataFn();
} }
begin() { begin(allowExists?: boolean) {
assert(!this.context); if (this.context) {
if (allowExists) {
return;
}
assert(false);
}
this.context = this.contextBuilder!(); this.context = this.contextBuilder!();
this.context.begin(); this.context.begin();
return this.context; return this.context;

View File

@ -122,7 +122,8 @@ export class ContextMenuFactory<
entityId: string entityId: string
) { ) {
assert(this.menus, '应当先调用setMenus才能动态判定菜单'); assert(this.menus, '应当先调用setMenus才能动态判定菜单');
this.cache.begin(); const needRollback = !!this.cache.begin(true);
try {
const menus = this.menus const menus = this.menus
.filter((menu) => { .filter((menu) => {
const { entity: destEntity, paths, action } = menu; const { entity: destEntity, paths, action } = menu;
@ -207,8 +208,13 @@ export class ContextMenuFactory<
return false; return false;
}) })
.map((wrapper) => omit(wrapper, ['filtersMaker'])) as OMenu[]; .map((wrapper) => omit(wrapper, ['filtersMaker'])) as OMenu[];
this.cache.rollback(); needRollback && this.cache.rollback();
return menus; return menus;
} }
catch (err) {
needRollback && this.cache.rollback();
throw err;
}
}
} }

View File

@ -229,7 +229,7 @@ class ListNode<
case 'c': { case 'c': {
const { e, d } = record as CreateOpResult<ED, T>; const { e, d } = record as CreateOpResult<ED, T>;
if (e === this.entity) { if (e === this.entity) {
const context = this.cache.begin(); const context = this.cache.begin()!;
const { filter } = this.constructSelection(); const { filter } = this.constructSelection();
if (d instanceof Array) { if (d instanceof Array) {
d.forEach( d.forEach(
@ -276,7 +276,7 @@ class ListNode<
} }
} }
else { else {
const context = this.cache.begin(); const context = this.cache.begin()!;
for (const id in this.sr) { for (const id in this.sr) {
if (!f || checkFilterContains<ED, T, FrontCxt>(e, context, f, { id }, true)) { if (!f || checkFilterContains<ED, T, FrontCxt>(e, context, f, { id }, true)) {
unset(this.sr, id); unset(this.sr, id);
@ -2023,7 +2023,8 @@ export class RunningTree<
const root = this.root[paths[0]]; const root = this.root[paths[0]];
const opers = root.composeOperations(); const opers = root.composeOperations();
this.cache.begin(); const cxt = this.cache.begin();
if (cxt) {
if (opers) { if (opers) {
this.cache.redoOperation(opers); this.cache.redoOperation(opers);
} }
@ -2033,10 +2034,10 @@ export class RunningTree<
const modiOperations = (root instanceof SingleNode || root instanceof VirtualNode) && root.getModiOperations(); const modiOperations = (root instanceof SingleNode || root instanceof VirtualNode) && root.getModiOperations();
modiOperations && this.cache.redoOperation(modiOperations); modiOperations && this.cache.redoOperation(modiOperations);
} }
return () => this.cache.rollback();
} }
rollbackRedoBranchOperations() { return () => undefined;
this.cache.rollback();
} }
getFreshValue(path: string) { getFreshValue(path: string) {

View File

@ -505,7 +505,7 @@ export function reRender<
const localeState = features.locales.getState(); const localeState = features.locales.getState();
if (this.state.oakEntity && this.state.oakFullpath) { if (this.state.oakEntity && this.state.oakFullpath) {
// 现在取数据需要把runningTree上的更新应用了再取判定actions也一样 // 现在取数据需要把runningTree上的更新应用了再取判定actions也一样
this.features.runningTree.redoBranchOperations(this.state.oakFullpath); const cleanFn = this.features.runningTree.redoBranchOperations(this.state.oakFullpath);
try { try {
const rows = this.features.runningTree.getFreshValue(this.state.oakFullpath); const rows = this.features.runningTree.getFreshValue(this.state.oakFullpath);
const oakLegalActions = rows && checkActionsAndCascadeEntities.call( const oakLegalActions = rows && checkActionsAndCascadeEntities.call(
@ -570,10 +570,10 @@ export function reRender<
} }
this.setState(data); this.setState(data);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
} }
catch (err) { catch (err) {
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
throw err; throw err;
} }
} else { } else {

View File

@ -322,10 +322,16 @@ const oakBehavior = Behavior<
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
return value; return value;
}
catch (err) {
cleanFn();
throw err;
}
}, },
checkOperation(entity, { action, data, filter }, checkerTypes) { checkOperation(entity, { action, data, filter }, checkerTypes) {
@ -675,11 +681,17 @@ const oakBehavior = Behavior<
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations();
assert(!(value instanceof Array)); assert(!(value instanceof Array));
cleanFn();
return value?.$$createAt$$ === 1; return value?.$$createAt$$ === 1;
}
catch (err) {
cleanFn();
throw err;
}
}, },
async aggregate(aggregation) { async aggregate(aggregation) {

View File

@ -304,12 +304,18 @@ abstract class OakComponentBase<
const path2 = path const path2 = path
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations();
assert(!(value instanceof Array)); assert(!(value instanceof Array));
cleanFn();
return value?.$$createAt$$ === 1; return value?.$$createAt$$ === 1;
} }
catch (err) {
cleanFn();
throw err;
}
}
clean(path?: string) { clean(path?: string) {
const path2 = path const path2 = path
@ -338,11 +344,17 @@ abstract class OakComponentBase<
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
this.features.runningTree.redoBranchOperations(path2); const cleanFn = this.features.runningTree.redoBranchOperations(path2);
try {
const value = this.features.runningTree.getFreshValue(path2); const value = this.features.runningTree.getFreshValue(path2);
this.features.runningTree.rollbackRedoBranchOperations(); cleanFn();
return value; return value;
} }
catch (err) {
cleanFn();
throw err;
}
}
checkOperation<T2 extends keyof ED>( checkOperation<T2 extends keyof ED>(
entity: T2, entity: T2,