import { SelectOption, CheckerType } from "."; import { GenericAction } from "../actions/action"; import { AsyncContext } from "../store/AsyncRowStore"; import { SyncContext } from "../store/SyncRowStore"; import { EntityDict, OperateOption } from "../types/Entity"; import { EntityShape } from "../types/Entity"; export type ModiTurn = 'create' | 'apply' | 'both'; /** * 优先级越小,越早执行。定义在1~99之间 */ export declare const TRIGGER_MIN_PRIORITY = 1; export declare const TRIGGER_DEFAULT_PRIORITY = 25; export declare const TRIGGER_MAX_PRIORITY = 50; export declare const CHECKER_MAX_PRIORITY = 99; /** * logical可能会更改row和data的值,应当最先执行,data和row不能修改相关的值 * 允许logicalData去改data中的值 */ export declare const CHECKER_PRIORITY_MAP: Record; interface TriggerBase { checkerType?: CheckerType; entity: T; name: string; asRoot?: true; priority?: number; } export interface CreateTriggerBase | SyncContext> extends TriggerBase { action: 'create'; mt?: ModiTurn; check?: (operation: ED[T]['Create']) => boolean; } export interface CreateTriggerInTxn | SyncContext> extends CreateTriggerBase { when: 'before' | 'after'; fn: (event: { operation: ED[T]['Create']; }, context: Cxt, option: OperateOption) => Promise | number; } interface TriggerCrossTxn | SyncContext> { when: 'commit'; strict?: 'takeEasy' | 'makeSure'; cs?: true; singleton?: true; grouped?: true; fn: (event: { ids: string[]; }, context: Cxt, option: OperateOption) => Promise<((context: Cxt, option: OperateOption) => Promise) | void>; } export interface CreateTriggerCrossTxn | SyncContext> extends CreateTriggerBase, TriggerCrossTxn { } export type CreateTrigger | SyncContext> = CreateTriggerInTxn | CreateTriggerCrossTxn; /** * update trigger如果带有filter,说明只对存在限定条件的行起作用。此时系统在进行相应动作时, * 会判定当前动作的filter条件和trigger所定义的filter是否有交集(即有同时满足两个条件的行) * 只要有,就会触发trigger。要注意的是这个条件是exists而不是all */ export interface UpdateTriggerBase | SyncContext> extends TriggerBase { action: Exclude | 'update' | Array | 'update'>; attributes?: keyof ED[T]['OpSchema'] | Array; mt?: ModiTurn; check?: (operation: ED[T]['Update']) => boolean; filter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Update'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise); } export interface UpdateTriggerInTxn | SyncContext> extends UpdateTriggerBase { when: 'before' | 'after'; fn: (event: { operation: ED[T]['Update']; }, context: Cxt, option: OperateOption) => Promise | number; } export interface UpdateTriggerCrossTxn | SyncContext> extends UpdateTriggerBase, TriggerCrossTxn { } export type UpdateTrigger | SyncContext> = UpdateTriggerInTxn | UpdateTriggerCrossTxn; /** * 同update trigger一样,remove trigger如果带有filter,说明只对存在限定条件的行起作用。此时系统在进行相应动作时, * 会判定当前动作的filter条件和trigger所定义的filter是否有交集(即有同时满足两个条件的行) * 只要有,就会触发trigger。要注意的是这个条件是exists而不是all */ export interface RemoveTriggerBase | SyncContext> extends TriggerBase { action: 'remove'; mt?: ModiTurn; check?: (operation: ED[T]['Remove']) => boolean; filter?: ED[T]['Remove']['filter'] | ((operation: ED[T]['Remove'], context: Cxt, option: OperateOption) => ED[T]['Remove']['filter'] | Promise); } export interface RemoveTriggerInTxn | SyncContext> extends RemoveTriggerBase { when: 'before' | 'after'; fn: (event: { operation: ED[T]['Remove']; }, context: Cxt, option: OperateOption) => Promise | number; } export interface RemoveTriggerCrossTxn | SyncContext> extends RemoveTriggerBase, TriggerCrossTxn { } export type RemoveTrigger | SyncContext> = RemoveTriggerInTxn | RemoveTriggerCrossTxn; export interface SelectTriggerBase extends TriggerBase { action: 'select'; } /** * selection似乎不需要支持跨事务?没想清楚 * todo by Xc */ export interface SelectTriggerBefore | SyncContext> extends SelectTriggerBase { when: 'before'; fn: (event: { operation: ED[T]['Selection']; }, context: Cxt, params?: SelectOption) => Promise | number; } export interface SelectTriggerAfter | SyncContext> extends SelectTriggerBase { when: 'after'; fn: (event: { operation: ED[T]['Selection']; result: Partial[]; }, context: Cxt, params?: SelectOption) => Promise | number; } export type SelectTrigger | SyncContext> = SelectTriggerBefore | SelectTriggerAfter; export type Trigger | SyncContext> = CreateTrigger | UpdateTrigger | RemoveTrigger | SelectTrigger; export interface TriggerEntityShape extends EntityShape { $$triggerData$$?: { name: string; operation: object; }; $$triggerTimestamp$$?: number; } export type VolatileTrigger | SyncContext> = CreateTriggerCrossTxn | UpdateTriggerCrossTxn | RemoveTriggerCrossTxn; export {};