oak-backend-base 4.0.2 → 4.0.3
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/lib/AppLoader.js +16 -12
- package/package.json +5 -5
- package/lib/DataSubscriber.d.ts +0 -18
- package/lib/DataSubscriber.js +0 -158
package/lib/AppLoader.js
CHANGED
|
@@ -73,25 +73,29 @@ class AppLoader extends types_1.AppLoader {
|
|
|
73
73
|
this.dataSubscriber = new DataSubscriber_1.default(ns, nsServer);
|
|
74
74
|
}
|
|
75
75
|
const { BackendRuntimeContext } = require(`${path}/lib/context/BackendRuntimeContext`);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
const loaderThis = this;
|
|
77
|
+
// 需要重载context上的构造和commit方法,否则程序中执行context.restartToExecute这样的方法中,new一个context出来是无法正确执行的
|
|
78
|
+
class BackendRuntimeContextWrapper extends BackendRuntimeContext {
|
|
79
|
+
constructor(store) {
|
|
80
|
+
super(store);
|
|
81
|
+
this.clusterInfo = (0, env_1.getClusterInfo)();
|
|
82
|
+
}
|
|
83
|
+
async commit() {
|
|
84
|
+
const { eventOperationMap, opRecords } = this;
|
|
85
|
+
await super.commit();
|
|
83
86
|
// 注入在提交后向dataSubscribe发送订阅的事件
|
|
84
|
-
if (
|
|
87
|
+
if (loaderThis.dataSubscriber) {
|
|
85
88
|
Object.keys(eventOperationMap).forEach((event) => {
|
|
86
89
|
const ids = eventOperationMap[event];
|
|
87
90
|
const opRecordsToPublish = opRecords.filter((ele) => !!ele.id && ids.includes(ele.id));
|
|
88
91
|
(0, assert_1.default)(opRecordsToPublish.length === ids.length, '要推送的事件的operation数量不足,请检查确保');
|
|
89
|
-
|
|
92
|
+
loaderThis.dataSubscriber.publishEvent(event, opRecordsToPublish, this.getSubscriberId());
|
|
90
93
|
});
|
|
91
94
|
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
;
|
|
98
|
+
this.contextBuilder = (store) => new BackendRuntimeContextWrapper(store);
|
|
95
99
|
}
|
|
96
100
|
registerTrigger(trigger) {
|
|
97
101
|
this.dbStore.registerTrigger(trigger);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-backend-base",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"description": "oak-backend-base",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"author": {
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"mysql": "^2.18.1",
|
|
21
21
|
"mysql2": "^2.3.3",
|
|
22
22
|
"node-schedule": "^2.1.0",
|
|
23
|
-
"oak-common-aspect": "
|
|
24
|
-
"oak-db": "
|
|
25
|
-
"oak-domain": "
|
|
26
|
-
"oak-frontend-base": "
|
|
23
|
+
"oak-common-aspect": "~3.0.0",
|
|
24
|
+
"oak-db": "~3.3.0",
|
|
25
|
+
"oak-domain": "~5.0.5",
|
|
26
|
+
"oak-frontend-base": "~5.0.5",
|
|
27
27
|
"socket.io": "^4.7.2",
|
|
28
28
|
"socket.io-client": "^4.7.2",
|
|
29
29
|
"uuid": "^8.3.2"
|
package/lib/DataSubscriber.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { EntityDict } from 'oak-domain/lib/types';
|
|
2
|
-
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
|
3
|
-
import { BackendRuntimeContext } from 'oak-frontend-base';
|
|
4
|
-
import { Namespace } from 'socket.io';
|
|
5
|
-
export default class DataSubscriber<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
|
|
6
|
-
private ns;
|
|
7
|
-
private contextBuilder;
|
|
8
|
-
private filterMap;
|
|
9
|
-
private idEntityMap;
|
|
10
|
-
constructor(ns: Namespace, contextBuilder: (scene?: string) => Promise<Context>);
|
|
11
|
-
private formCreateRoomRoutine;
|
|
12
|
-
/**
|
|
13
|
-
* 来自外部的socket连接,监听数据变化
|
|
14
|
-
*/
|
|
15
|
-
private startup;
|
|
16
|
-
private sendRecord;
|
|
17
|
-
onDataCommited(context: Context): void;
|
|
18
|
-
}
|
package/lib/DataSubscriber.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const lodash_1 = require("oak-domain/lib/utils/lodash");
|
|
4
|
-
const oak_domain_1 = require("oak-domain");
|
|
5
|
-
class DataSubscriber {
|
|
6
|
-
ns;
|
|
7
|
-
contextBuilder;
|
|
8
|
-
filterMap;
|
|
9
|
-
idEntityMap;
|
|
10
|
-
constructor(ns, contextBuilder) {
|
|
11
|
-
this.ns = ns;
|
|
12
|
-
this.contextBuilder = contextBuilder;
|
|
13
|
-
this.startup();
|
|
14
|
-
this.filterMap = {};
|
|
15
|
-
this.idEntityMap = {};
|
|
16
|
-
}
|
|
17
|
-
formCreateRoomRoutine(def) {
|
|
18
|
-
const { id, entity, filter } = def;
|
|
19
|
-
return (room) => {
|
|
20
|
-
if (room === id) {
|
|
21
|
-
console.log('instance:', process.env.NODE_APP_INSTANCE, 'add filter', room);
|
|
22
|
-
// 本房间不存在,说明这个filter是新出现的
|
|
23
|
-
if (this.filterMap[entity]) {
|
|
24
|
-
// id的唯一性由前台保证,重复则无视
|
|
25
|
-
Object.assign(this.filterMap[entity], {
|
|
26
|
-
[id]: filter,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
Object.assign(this.filterMap, {
|
|
31
|
-
[entity]: {
|
|
32
|
-
[id]: filter,
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
this.idEntityMap[id] = entity;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* 来自外部的socket连接,监听数据变化
|
|
42
|
-
*/
|
|
43
|
-
startup() {
|
|
44
|
-
this.ns.on('connection', async (socket) => {
|
|
45
|
-
try {
|
|
46
|
-
const { 'oak-cxt': cxtStr } = socket.handshake.headers;
|
|
47
|
-
const context = await this.contextBuilder(cxtStr);
|
|
48
|
-
socket.userId = context.getCurrentUserId();
|
|
49
|
-
socket.context = context;
|
|
50
|
-
socket.idMap = {};
|
|
51
|
-
socket.on('sub', async (data) => {
|
|
52
|
-
try {
|
|
53
|
-
console.log('instance:', process.env.NODE_APP_INSTANCE, 'on sub', JSON.stringify(data));
|
|
54
|
-
await Promise.all(data.map(async (ele) => {
|
|
55
|
-
const { id, entity, filter } = ele;
|
|
56
|
-
// 尝试select此filter,如果失败说明权限越界
|
|
57
|
-
await context.select(entity, {
|
|
58
|
-
data: {
|
|
59
|
-
id: 1,
|
|
60
|
-
},
|
|
61
|
-
filter,
|
|
62
|
-
}, {});
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
socket.emit('error', err.toString());
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
data.forEach((ele) => {
|
|
70
|
-
const createRoomRoutine = this.formCreateRoomRoutine(ele);
|
|
71
|
-
this.ns.adapter.on('create-room', createRoomRoutine);
|
|
72
|
-
socket.join(ele.id);
|
|
73
|
-
this.ns.adapter.off('create-room', createRoomRoutine);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
socket.on('unsub', (ids) => {
|
|
77
|
-
// console.log('instance:', process.env.NODE_APP_INSTANCE, 'on unsub', JSON.stringify(ids));
|
|
78
|
-
ids.forEach((id) => {
|
|
79
|
-
socket.leave(id);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
catch (err) {
|
|
84
|
-
socket.emit('error', err.toString());
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
this.ns.adapter.on('delete-room', (room) => {
|
|
88
|
-
const entity = this.idEntityMap[room];
|
|
89
|
-
if (entity) {
|
|
90
|
-
// console.log('instance:', process.env.NODE_APP_INSTANCE, 'remove filter', room);
|
|
91
|
-
(0, lodash_1.unset)(this.filterMap[entity], room);
|
|
92
|
-
(0, lodash_1.unset)(this.idEntityMap, room);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
this.ns.on('sendRecord', (entity, filter, record, isCreate) => {
|
|
96
|
-
console.log('instance:', process.env.NODE_APP_INSTANCE, 'get record from another', JSON.stringify(entity));
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
sendRecord(entity, filter, record, sid, isCreate) {
|
|
100
|
-
if (entity === 'spContractApplyment') {
|
|
101
|
-
console.log('instance:', process.env.NODE_APP_INSTANCE, 'sendRecord', JSON.stringify(entity));
|
|
102
|
-
}
|
|
103
|
-
this.ns.serverSideEmit('sendRecord', entity, filter, record, isCreate);
|
|
104
|
-
if (this.filterMap[entity]) {
|
|
105
|
-
Object.keys(this.filterMap[entity]).forEach(async (room) => {
|
|
106
|
-
const context = await this.contextBuilder();
|
|
107
|
-
const filter2 = this.filterMap[entity][room];
|
|
108
|
-
let needSend = false;
|
|
109
|
-
if (isCreate) {
|
|
110
|
-
// 如果是插入数据肯定是单行,使用相容性检测
|
|
111
|
-
const contained = await (0, oak_domain_1.checkFilterContains)(entity, context, filter2, filter, true);
|
|
112
|
-
needSend = contained;
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
const repeled = await (0, oak_domain_1.checkFilterRepel)(entity, context, filter, filter2, true);
|
|
116
|
-
needSend = !repeled;
|
|
117
|
-
}
|
|
118
|
-
if (needSend) {
|
|
119
|
-
// console.log('instance:', process.env.NODE_APP_INSTANCE, 'needSend', JSON.stringify(room));
|
|
120
|
-
if (sid) {
|
|
121
|
-
this.ns.to(room).except(sid).emit('data', [record], [room]);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
this.ns.to(room).emit('data', [record], [room]);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
onDataCommited(context) {
|
|
131
|
-
const sid = context.getSubscriberId();
|
|
132
|
-
const { opRecords } = context;
|
|
133
|
-
opRecords.forEach((record) => {
|
|
134
|
-
const { a } = record;
|
|
135
|
-
switch (a) {
|
|
136
|
-
case 'c': {
|
|
137
|
-
const { e, d } = record;
|
|
138
|
-
this.sendRecord(e, d, record, sid, true);
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
case 'u': {
|
|
142
|
-
const { e, d, f } = record;
|
|
143
|
-
this.sendRecord(e, f, record, sid);
|
|
144
|
-
break;
|
|
145
|
-
}
|
|
146
|
-
case 'r': {
|
|
147
|
-
const { e, f } = record;
|
|
148
|
-
this.sendRecord(e, f, record, sid);
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
default: {
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
exports.default = DataSubscriber;
|