feat(plugin-workflow): use toggle instead of mount and unmount
This commit is contained in:
parent
e592d03f18
commit
f9182c4004
@ -10,28 +10,22 @@ describe('execution', () => {
|
|||||||
let db: Database;
|
let db: Database;
|
||||||
let PostModel;
|
let PostModel;
|
||||||
let WorkflowModel;
|
let WorkflowModel;
|
||||||
let WorkflowRepository;
|
|
||||||
let workflow;
|
let workflow;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
app = await getApp();
|
app = await getApp();
|
||||||
|
|
||||||
db = app.db;
|
db = app.db;
|
||||||
WorkflowRepository = db.getCollection('workflows').repository;
|
|
||||||
WorkflowModel = db.getCollection('workflows').model;
|
WorkflowModel = db.getCollection('workflows').model;
|
||||||
PostModel = db.getCollection('posts').model;
|
PostModel = db.getCollection('posts').model;
|
||||||
|
|
||||||
// TODO(question): why the hooks of creating workflow won't run by using `WorkflowModel.create()`?
|
workflow = await WorkflowModel.create({
|
||||||
// maybe the model is not the original defined one which hooks have been added.
|
title: 'test workflow',
|
||||||
// @see database/../collections.ts@L99: `this.model = class extends M {};`
|
enabled: true,
|
||||||
workflow = await WorkflowRepository.create({
|
type: 'model',
|
||||||
values: {
|
config: {
|
||||||
title: 'condition workflow',
|
mode: 1,
|
||||||
enabled: true,
|
collection: 'posts'
|
||||||
type: 'afterCreate',
|
|
||||||
config: {
|
|
||||||
collection: 'posts'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -10,25 +10,21 @@ describe('workflow > instructions > condition', () => {
|
|||||||
let db: Database;
|
let db: Database;
|
||||||
let PostModel;
|
let PostModel;
|
||||||
let WorkflowModel;
|
let WorkflowModel;
|
||||||
let WorkflowRepository;
|
|
||||||
let workflow;
|
let workflow;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
app = await getApp();
|
app = await getApp();
|
||||||
|
|
||||||
db = app.db;
|
db = app.db;
|
||||||
WorkflowRepository = db.getCollection('workflows').repository;
|
|
||||||
WorkflowModel = db.getCollection('workflows').model;
|
WorkflowModel = db.getCollection('workflows').model;
|
||||||
PostModel = db.getCollection('posts').model;
|
PostModel = db.getCollection('posts').model;
|
||||||
|
|
||||||
workflow = await WorkflowRepository.create({
|
workflow = await WorkflowModel.create({
|
||||||
values: {
|
title: 'test workflow',
|
||||||
title: 'condition workflow',
|
enabled: true,
|
||||||
enabled: true,
|
type: 'afterCreate',
|
||||||
type: 'afterCreate',
|
config: {
|
||||||
config: {
|
collection: 'posts'
|
||||||
collection: 'posts'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -34,28 +34,27 @@ export default class WorkflowModel extends Model {
|
|||||||
filter: { enabled: true }
|
filter: { enabled: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
workflows.forEach(workflow => {
|
workflows.forEach((workflow: WorkflowModel) => {
|
||||||
// @ts-ignore
|
workflow.toggle();
|
||||||
workflow.mount();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addHook('afterCreate', (model: WorkflowModel) => model.mount());
|
this.addHook('afterCreate', (model: WorkflowModel) => model.toggle());
|
||||||
// TODO: afterUpdate, afterDestroy
|
this.addHook('afterUpdate', (model: WorkflowModel) => model.toggle());
|
||||||
|
this.addHook('afterDestroy', (model: WorkflowModel) => model.toggle(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
async mount() {
|
getHookId() {
|
||||||
if (!this.get('enabled')) {
|
return `workflow-${this.get('id')}`;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
async toggle(enable?: boolean) {
|
||||||
const type = this.get('type');
|
const type = this.get('type');
|
||||||
const config = this.get('config');
|
const { on, off } = getTrigger(type);
|
||||||
const trigger = getTrigger(type);
|
if (typeof enable !== 'undefined' ? enable : this.get('enabled')) {
|
||||||
trigger.call(this, config, this.start.bind(this));
|
on.call(this, this.start.bind(this));
|
||||||
}
|
} else {
|
||||||
|
off.call(this);
|
||||||
// TODO
|
}
|
||||||
async unmount() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(context: Object, options) {
|
async start(context: Object, options) {
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import WorkflowModel from "../models/Workflow";
|
|
||||||
|
|
||||||
export interface IDataChangeTriggerConfig {
|
|
||||||
collection: string;
|
|
||||||
// TODO: ICondition
|
|
||||||
filter: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function afterCreate(this: WorkflowModel, config: IDataChangeTriggerConfig, callback: Function) {
|
|
||||||
// @ts-ignore
|
|
||||||
const { database } = this.constructor;
|
|
||||||
const { model } = database.getCollection(config.collection);
|
|
||||||
model.addHook('afterCreate', `workflow-${this.get('id')}`, (data: any, options) => callback({ data }, options));
|
|
||||||
}
|
|
@ -1,22 +1,20 @@
|
|||||||
import WorkflowModel from '../models/Workflow';
|
import WorkflowModel from '../models/Workflow';
|
||||||
import * as dataChangeTriggers from './data-change';
|
import modelTrigger from './model';
|
||||||
|
|
||||||
export interface ITrigger {
|
export interface Trigger {
|
||||||
(this: WorkflowModel, config: any): void
|
name: string;
|
||||||
|
on(this: WorkflowModel, callback: Function): void;
|
||||||
|
off(this: WorkflowModel): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const triggers = new Map<string, ITrigger>();
|
const triggers = new Map<string, Trigger>();
|
||||||
|
|
||||||
export function register(type: string, trigger: ITrigger): void {
|
export function register(type: string, trigger: Trigger): void {
|
||||||
triggers.set(type, trigger);
|
triggers.set(type, trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get(type: string): ITrigger | undefined {
|
export function get(type: string): Trigger | undefined {
|
||||||
return triggers.get(type);
|
return triggers.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key in dataChangeTriggers) {
|
register(modelTrigger.name, modelTrigger);
|
||||||
if (dataChangeTriggers.hasOwnProperty(key)) {
|
|
||||||
register(key, dataChangeTriggers[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
44
packages/plugin-workflow/src/triggers/model.ts
Normal file
44
packages/plugin-workflow/src/triggers/model.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import WorkflowModel from "../models/Workflow";
|
||||||
|
|
||||||
|
export interface ModelChangeTriggerConfig {
|
||||||
|
collection: string;
|
||||||
|
// TODO: ICondition
|
||||||
|
filter: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MODE_BITMAP = {
|
||||||
|
CREATE: 1,
|
||||||
|
UPDATE: 2,
|
||||||
|
DESTROY: 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const MODE_BITMAP_EVENTS = new Map();
|
||||||
|
MODE_BITMAP_EVENTS.set(MODE_BITMAP.CREATE, 'afterCreate');
|
||||||
|
MODE_BITMAP_EVENTS.set(MODE_BITMAP.UPDATE, 'afterUpdate');
|
||||||
|
MODE_BITMAP_EVENTS.set(MODE_BITMAP.DESTROY, 'afterDestroy');
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'model',
|
||||||
|
on(this: WorkflowModel, callback: Function) {
|
||||||
|
const { database } = <typeof WorkflowModel>this.constructor;
|
||||||
|
const { collection, mode } = this.config;
|
||||||
|
const { model } = database.getCollection(collection);
|
||||||
|
const handler = (data: any, options) => callback({ data }, options);
|
||||||
|
// TODO: duplication when mode change should be considered
|
||||||
|
for (let [key, event] of MODE_BITMAP_EVENTS.entries()) {
|
||||||
|
if (mode & key) {
|
||||||
|
model.addHook(event, this.getHookId(), handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
off(this: WorkflowModel) {
|
||||||
|
const { database } = <typeof WorkflowModel>this.constructor;
|
||||||
|
const { collection, mode } = this.config;
|
||||||
|
const { model } = database.getCollection(collection);
|
||||||
|
for (let [key, event] of MODE_BITMAP_EVENTS.entries()) {
|
||||||
|
if (mode & key) {
|
||||||
|
model.removeHook(event, this.getHookId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user