@mldong/jeeflow 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/model.js ADDED
@@ -0,0 +1,170 @@
1
+ // ─── LogicFlow JSON Types ─────────────────────────────────────────────────────
2
+ // ─── Node Type Constants ──────────────────────────────────────────────────────
3
+ export const TypeStart = 'snaker:start';
4
+ export const TypeEnd = 'snaker:end';
5
+ export const TypeTask = 'snaker:task';
6
+ export const TypeDecision = 'snaker:decision';
7
+ export const TypeFork = 'snaker:fork';
8
+ export const TypeJoin = 'snaker:join';
9
+ export const TypeCustom = 'snaker:custom';
10
+ export var InstanceState;
11
+ (function (InstanceState) {
12
+ InstanceState[InstanceState["Doing"] = 10] = "Doing";
13
+ InstanceState[InstanceState["Done"] = 20] = "Done";
14
+ InstanceState[InstanceState["Reject"] = 45] = "Reject";
15
+ })(InstanceState || (InstanceState = {}));
16
+ export var TaskState;
17
+ (function (TaskState) {
18
+ TaskState[TaskState["Doing"] = 10] = "Doing";
19
+ TaskState[TaskState["Done"] = 20] = "Done";
20
+ TaskState[TaskState["Abandoned"] = 99] = "Abandoned";
21
+ })(TaskState || (TaskState = {}));
22
+ export const BusinessNoKey = 'BUSINESS_NO';
23
+ // ─── 聚合根:ProcessInstance ───────────────────────────────────────────────────
24
+ export class ProcessInstance {
25
+ id;
26
+ parentId;
27
+ defineId;
28
+ state;
29
+ parentNodeName;
30
+ businessNo;
31
+ operator;
32
+ expireTime;
33
+ variables;
34
+ tasks;
35
+ createTime;
36
+ createUser;
37
+ updateTime;
38
+ updateUser;
39
+ constructor(data) {
40
+ Object.assign(this, data);
41
+ }
42
+ /** 工厂——创建流程实例 */
43
+ static create(id, defineId, operator, vars, now) {
44
+ return new ProcessInstance({
45
+ id, defineId, state: InstanceState.Doing,
46
+ operator, variables: vars,
47
+ parentNodeName: '', businessNo: vars[BusinessNoKey] ?? '',
48
+ createTime: now, updateTime: now, createUser: operator, updateUser: operator,
49
+ tasks: [],
50
+ });
51
+ }
52
+ /** 完成任务(子实体状态转换 + 实例变量合并) */
53
+ completeTask(task, operator, vars, now) {
54
+ task.finish(operator, vars, now);
55
+ this.variables = vars;
56
+ this.updateTime = now;
57
+ this.updateUser = operator;
58
+ }
59
+ /** 废弃单个任务 */
60
+ abandonTask(task, now) {
61
+ task.abandon(now);
62
+ this.updateTime = now;
63
+ }
64
+ /** 废弃所有进行中任务,返回被废弃列表(供调用方持久化) */
65
+ abandonAllDoing(now) {
66
+ const abandoned = [];
67
+ for (const t of this.tasks) {
68
+ if (t.isDoing()) {
69
+ t.abandon(now);
70
+ abandoned.push(t);
71
+ }
72
+ }
73
+ this.updateTime = now;
74
+ return abandoned;
75
+ }
76
+ /** 流程完成 */
77
+ finish(now) {
78
+ this.state = InstanceState.Done;
79
+ this.updateTime = now;
80
+ }
81
+ /** 驳回流程 */
82
+ reject(now) {
83
+ this.state = InstanceState.Reject;
84
+ this.updateTime = now;
85
+ }
86
+ /** 追加变量 */
87
+ addVariable(vars) {
88
+ Object.assign(this.variables, vars);
89
+ }
90
+ /** 获取进行中任务 */
91
+ getDoingTasks() {
92
+ return this.tasks.filter(t => t.isDoing());
93
+ }
94
+ /** 获取已完成任务 */
95
+ getDoneTasks() {
96
+ return this.tasks.filter(t => t.isFinished());
97
+ }
98
+ /** 所有任务是否都已完成(join 合并判断) */
99
+ isAllTasksFinished() {
100
+ return !this.tasks.some(t => t.isDoing());
101
+ }
102
+ /** 创建任务(子实体工厂) */
103
+ createTask(id, taskName, displayName, actor, operator, formKey, now) {
104
+ const task = new ProcessTask({
105
+ id, processInstanceId: this.id,
106
+ taskName, displayName, taskState: TaskState.Doing,
107
+ actorId: '', actorIds: [actor],
108
+ taskType: 0, performType: 0, formKey,
109
+ variables: {},
110
+ createTime: now, updateTime: now, createUser: operator, updateUser: operator,
111
+ });
112
+ this.tasks.push(task);
113
+ return task;
114
+ }
115
+ }
116
+ // ─── 子实体:ProcessTask ────────────────────────────────────────────────────────
117
+ export class ProcessTask {
118
+ id;
119
+ processInstanceId;
120
+ taskName;
121
+ displayName;
122
+ taskType;
123
+ performType;
124
+ taskState;
125
+ actorId;
126
+ actorIds;
127
+ finishTime;
128
+ expireTime;
129
+ formKey;
130
+ parentTaskId;
131
+ variables;
132
+ createTime;
133
+ createUser;
134
+ updateTime;
135
+ updateUser;
136
+ constructor(data) {
137
+ Object.assign(this, data);
138
+ }
139
+ /** 完成任务 */
140
+ finish(operator, vars, now) {
141
+ this.taskState = TaskState.Done;
142
+ this.actorId = operator;
143
+ this.finishTime = now;
144
+ this.updateTime = now;
145
+ this.updateUser = operator;
146
+ this.variables = vars;
147
+ }
148
+ /** 废弃任务 */
149
+ abandon(now) {
150
+ this.taskState = TaskState.Abandoned;
151
+ this.updateTime = now;
152
+ }
153
+ /** 是否进行中 */
154
+ isDoing() { return this.taskState === TaskState.Doing; }
155
+ /** 是否已完成 */
156
+ isFinished() { return this.taskState === TaskState.Done; }
157
+ /** 操作人是否有权限处理 */
158
+ isAllowed(operator) {
159
+ return this.actorIds.includes(operator);
160
+ }
161
+ }
162
+ // ─── Clone Helpers(保留 class 原型)────────────────────────────────────────────
163
+ export function cloneInstance(inst) {
164
+ return Object.assign(Object.create(ProcessInstance.prototype), inst, {
165
+ tasks: inst.tasks.map(cloneTask),
166
+ });
167
+ }
168
+ export function cloneTask(task) {
169
+ return Object.assign(Object.create(ProcessTask.prototype), task);
170
+ }
@@ -0,0 +1,18 @@
1
+ import type { FlowNode, ProcessInstance } from './model.js';
2
+ /** 参与者指派处理器接口——对标 Java AssignmentHandler */
3
+ export interface IAssignmentHandler {
4
+ assign(node: FlowNode, inst: ProcessInstance): string[] | Promise<string[]>;
5
+ }
6
+ /** 决策处理器接口——对标 Java DecisionHandler */
7
+ export interface IDecisionHandler {
8
+ decide(node: FlowNode, inst: ProcessInstance, vars: Record<string, any>): string | Promise<string>;
9
+ }
10
+ /** 处理器注册表——按名称注册/解析(对标 Spring IoC) */
11
+ export declare class HandlerRegistry {
12
+ private assignments;
13
+ private decisions;
14
+ registerAssignment(name: string, handler: IAssignmentHandler): void;
15
+ registerDecision(name: string, handler: IDecisionHandler): void;
16
+ resolveAssignment(name: string): IAssignmentHandler | undefined;
17
+ resolveDecision(name: string): IDecisionHandler | undefined;
18
+ }
@@ -0,0 +1,17 @@
1
+ /** 处理器注册表——按名称注册/解析(对标 Spring IoC) */
2
+ export class HandlerRegistry {
3
+ assignments = new Map();
4
+ decisions = new Map();
5
+ registerAssignment(name, handler) {
6
+ this.assignments.set(name, handler);
7
+ }
8
+ registerDecision(name, handler) {
9
+ this.decisions.set(name, handler);
10
+ }
11
+ resolveAssignment(name) {
12
+ return this.assignments.get(name);
13
+ }
14
+ resolveDecision(name) {
15
+ return this.decisions.get(name);
16
+ }
17
+ }
package/dist/spi.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import type { ProcessDefine, ProcessInstance, ProcessTask, UserInfo } from './model.js';
2
+ export interface ProcessRepository {
3
+ findDefineById(id: number): Promise<ProcessDefine | null>;
4
+ findInstanceById(id: number): Promise<ProcessInstance | null>;
5
+ saveInstance(inst: ProcessInstance): Promise<void>;
6
+ updateInstance(inst: ProcessInstance): Promise<void>;
7
+ findTaskById(taskId: number): Promise<ProcessTask | null>;
8
+ saveTask(task: ProcessTask): Promise<void>;
9
+ updateTask(task: ProcessTask): Promise<void>;
10
+ findDoingTasks(instanceId: number, taskNames?: string[]): Promise<ProcessTask[]>;
11
+ findDoneTasks(instanceId: number, taskNames?: string[]): Promise<ProcessTask[]>;
12
+ findHistoryTasks(instanceId: number): Promise<ProcessTask[]>;
13
+ findTaskActors(taskId: number): Promise<string[]>;
14
+ addTaskActor(taskId: number, actors: string[]): Promise<void>;
15
+ removeTaskActor(taskId: number, actors: string[]): Promise<void>;
16
+ createCcInstance(instanceId: number, creator: string, ...actorIds: string[]): Promise<void>;
17
+ updateCcStatus(instanceId: number, actorId: string): Promise<void>;
18
+ }
19
+ export interface UserProvider {
20
+ getUser(userId: string): Promise<UserInfo | null>;
21
+ }
22
+ export interface IDGenerator {
23
+ nextId(): number;
24
+ }
25
+ export interface ExpressionEvaluator {
26
+ eval(expr: string, vars: Record<string, any>): Promise<any>;
27
+ }
package/dist/spi.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@mldong/jeeflow",
3
+ "version": "1.0.0",
4
+ "description": "jeeflow workflow engine — Node.js / TypeScript implementation",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./engine": "./dist/engine.js",
11
+ "./model": "./dist/model.js",
12
+ "./spi": "./dist/spi.js",
13
+ "./memory": "./dist/memory.js",
14
+ "./jdbc": "./dist/jdbc/index.js",
15
+ "./mysql": "./dist/jdbc/mysql.js",
16
+ "./postgres": "./dist/jdbc/postgres.js"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "test": "node --import tsx __tests__/spec.test.ts",
21
+ "demo": "node --import tsx demo/main.ts",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "workflow",
26
+ "engine",
27
+ "jeeflow",
28
+ "typescript"
29
+ ],
30
+ "license": "Apache-2.0",
31
+ "devDependencies": {
32
+ "@types/pg": "^8.20.3",
33
+ "tsx": "^4.19.0",
34
+ "typescript": "^5.5.0"
35
+ },
36
+ "optionalDependencies": {
37
+ "mysql2": "^3.11.0",
38
+ "pg": "^8.13.0"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "LICENSE",
43
+ "README.md"
44
+ ]
45
+ }