oak-backend-base 4.0.1 → 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 CHANGED
@@ -65,7 +65,7 @@ class AppLoader extends types_1.AppLoader {
65
65
  const { dbConfig } = this.getConfiguration();
66
66
  const { storageSchema } = require(`${path}/lib/oak-app-domain/Storage`);
67
67
  const depGraph = (0, dependencyBuilder_1.analyzeDepedency)(process.cwd());
68
- this.externalDependencies = Object.keys(depGraph.nodeDict);
68
+ this.externalDependencies = depGraph.ascOrder;
69
69
  const { authDeduceRelationMap, selectFreeEntities, updateFreeDict } = this.requireSth('lib/configuration/relation');
70
70
  this.aspectDict = Object.assign({}, index_1.default, this.requireSth('lib/aspects/index'));
71
71
  this.dbStore = new DbStore_1.DbStore(storageSchema, () => this.contextBuilder(this.dbStore), dbConfig, authDeduceRelationMap, selectFreeEntities, updateFreeDict);
@@ -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
- this.contextBuilder = (store) => {
77
- const context = new BackendRuntimeContext(store);
78
- context.clusterInfo = (0, env_1.getClusterInfo)();
79
- const originCommit = context.commit;
80
- context.commit = async () => {
81
- const { eventOperationMap, opRecords } = context;
82
- await originCommit.call(context);
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 (this.dataSubscriber) {
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
- this.dataSubscriber.publishEvent(event, opRecordsToPublish, context.getSubscriberId());
92
+ loaderThis.dataSubscriber.publishEvent(event, opRecordsToPublish, this.getSubscriberId());
90
93
  });
91
94
  }
92
- };
93
- return context;
94
- };
95
+ }
96
+ }
97
+ ;
98
+ this.contextBuilder = (store) => new BackendRuntimeContextWrapper(store);
95
99
  }
96
100
  registerTrigger(trigger) {
97
101
  this.dbStore.registerTrigger(trigger);
@@ -220,13 +224,15 @@ class AppLoader extends types_1.AppLoader {
220
224
  }
221
225
  }]);
222
226
  };
223
- for (const router in endpoints) {
224
- const item = endpoints[router];
225
- if (item instanceof Array) {
226
- item.forEach(ele => transformEndpointItem(router, ele));
227
- }
228
- else {
229
- transformEndpointItem(router, item);
227
+ if (endpoints) {
228
+ for (const router in endpoints) {
229
+ const item = endpoints[router];
230
+ if (item instanceof Array) {
231
+ item.forEach(ele => transformEndpointItem(router, ele));
232
+ }
233
+ else {
234
+ transformEndpointItem(router, item);
235
+ }
230
236
  }
231
237
  }
232
238
  if (this.synchronizer) {
@@ -285,7 +291,7 @@ class AppLoader extends types_1.AppLoader {
285
291
  const watchers = this.requireSth('lib/watchers/index');
286
292
  const { ActionDefDict } = require(`${this.path}/lib/oak-app-domain/ActionDefDict`);
287
293
  const { watchers: adWatchers } = (0, IntrinsicLogics_1.makeIntrinsicLogics)(this.dbStore.getSchema(), ActionDefDict);
288
- const totalWatchers = watchers.concat(adWatchers);
294
+ const totalWatchers = (watchers || []).concat(adWatchers);
289
295
  let count = 0;
290
296
  const execOne = async (watcher, start) => {
291
297
  try {
@@ -317,38 +323,40 @@ class AppLoader extends types_1.AppLoader {
317
323
  }
318
324
  startTimers() {
319
325
  const timers = this.requireSth('lib/timers/index');
320
- for (const timer of timers) {
321
- const { cron, name } = timer;
322
- (0, node_schedule_1.scheduleJob)(name, cron, async (date) => {
323
- const start = Date.now();
324
- console.log(`定时器【${name}】开始执行,时间是【${date.toLocaleTimeString()}】`);
325
- if (timer.hasOwnProperty('entity')) {
326
- try {
327
- const result = await this.execWatcher(timer);
328
- console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒】,结果是`, result);
326
+ if (timers) {
327
+ for (const timer of timers) {
328
+ const { cron, name } = timer;
329
+ (0, node_schedule_1.scheduleJob)(name, cron, async (date) => {
330
+ const start = Date.now();
331
+ console.log(`定时器【${name}】开始执行,时间是【${date.toLocaleTimeString()}】`);
332
+ if (timer.hasOwnProperty('entity')) {
333
+ try {
334
+ const result = await this.execWatcher(timer);
335
+ console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒】,结果是`, result);
336
+ }
337
+ catch (err) {
338
+ console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒】,错误是`, err);
339
+ }
329
340
  }
330
- catch (err) {
331
- console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒】,错误是`, err);
332
- }
333
- }
334
- else {
335
- const context = await this.makeContext();
336
- try {
337
- const { timer: timerFn } = timer;
338
- const result = await timerFn(context);
339
- console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒,结果是【${result}】`);
340
- await context.commit();
341
+ else {
342
+ const context = await this.makeContext();
343
+ try {
344
+ const { timer: timerFn } = timer;
345
+ const result = await timerFn(context);
346
+ console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒,结果是【${result}】`);
347
+ await context.commit();
348
+ }
349
+ catch (err) {
350
+ console.warn(`定时器【${name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
351
+ await context.rollback();
352
+ }
341
353
  }
342
- catch (err) {
343
- console.warn(`定时器【${name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
344
- await context.rollback();
345
- }
346
- }
347
- });
354
+ });
355
+ }
348
356
  }
349
357
  }
350
358
  async execStartRoutines() {
351
- const routines = this.requireSth('lib/routines/start');
359
+ const routines = this.requireSth('lib/routines/start') || [];
352
360
  if (this.synchronizer) {
353
361
  const routine = this.synchronizer.getSyncRoutine();
354
362
  routines.push(routine);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oak-backend-base",
3
- "version": "4.0.1",
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": "^3.0.0",
24
- "oak-db": "^3.3.0",
25
- "oak-domain": "^5.0.0",
26
- "oak-frontend-base": "^5.0.0",
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"
@@ -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
- }
@@ -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;