@nocobase/server 1.2.14-alpha → 1.3.0-alpha.20240710141659
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/application.d.ts +7 -1
- package/lib/application.js +14 -5
- package/lib/commands/start.js +2 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/sync-manager.d.ts +44 -0
- package/lib/sync-manager.js +129 -0
- package/package.json +14 -14
package/lib/application.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ import { Locale } from './locale';
|
|
|
28
28
|
import { Plugin } from './plugin';
|
|
29
29
|
import { InstallOptions, PluginManager } from './plugin-manager';
|
|
30
30
|
import { DataSourceManager, SequelizeDataSource } from '@nocobase/data-source-manager';
|
|
31
|
+
import { SyncManager } from './sync-manager';
|
|
31
32
|
export type PluginType = string | typeof Plugin;
|
|
32
33
|
export type PluginConfiguration = PluginType | [PluginType, any];
|
|
33
34
|
export interface ResourceManagerOptions {
|
|
@@ -149,7 +150,7 @@ export declare class Application<StateT = DefaultState, ContextT = DefaultContex
|
|
|
149
150
|
perfHistograms: Map<string, RecordableHistogram>;
|
|
150
151
|
protected plugins: Map<string, Plugin<any>>;
|
|
151
152
|
protected _appSupervisor: AppSupervisor;
|
|
152
|
-
protected _started:
|
|
153
|
+
protected _started: Date | null;
|
|
153
154
|
private _authenticated;
|
|
154
155
|
private _maintaining;
|
|
155
156
|
private _maintainingCommandStatus;
|
|
@@ -158,10 +159,15 @@ export declare class Application<StateT = DefaultState, ContextT = DefaultContex
|
|
|
158
159
|
/**
|
|
159
160
|
* @internal
|
|
160
161
|
*/
|
|
162
|
+
syncManager: SyncManager;
|
|
161
163
|
requestLogger: Logger;
|
|
162
164
|
private sqlLogger;
|
|
163
165
|
protected _logger: SystemLogger;
|
|
164
166
|
constructor(options: ApplicationOptions);
|
|
167
|
+
/**
|
|
168
|
+
* @experimental
|
|
169
|
+
*/
|
|
170
|
+
get started(): Date;
|
|
165
171
|
get logger(): SystemLogger;
|
|
166
172
|
get log(): SystemLogger;
|
|
167
173
|
protected _loaded: boolean;
|
package/lib/application.js
CHANGED
|
@@ -72,6 +72,7 @@ var import_validate_filter_params = __toESM(require("./middlewares/validate-filt
|
|
|
72
72
|
var import_path2 = __toESM(require("path"));
|
|
73
73
|
var import_middlewares = require("./middlewares");
|
|
74
74
|
var import_data_template = require("./middlewares/data-template");
|
|
75
|
+
var import_sync_manager = require("./sync-manager");
|
|
75
76
|
const _Application = class _Application extends import_koa.default {
|
|
76
77
|
constructor(options) {
|
|
77
78
|
super();
|
|
@@ -107,7 +108,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
107
108
|
perfHistograms = /* @__PURE__ */ new Map();
|
|
108
109
|
plugins = /* @__PURE__ */ new Map();
|
|
109
110
|
_appSupervisor = import_app_supervisor.AppSupervisor.getInstance();
|
|
110
|
-
_started;
|
|
111
|
+
_started = null;
|
|
111
112
|
_authenticated = false;
|
|
112
113
|
_maintaining = false;
|
|
113
114
|
_maintainingCommandStatus;
|
|
@@ -116,9 +117,16 @@ const _Application = class _Application extends import_koa.default {
|
|
|
116
117
|
/**
|
|
117
118
|
* @internal
|
|
118
119
|
*/
|
|
120
|
+
syncManager;
|
|
119
121
|
requestLogger;
|
|
120
122
|
sqlLogger;
|
|
121
123
|
_logger;
|
|
124
|
+
/**
|
|
125
|
+
* @experimental
|
|
126
|
+
*/
|
|
127
|
+
get started() {
|
|
128
|
+
return this._started;
|
|
129
|
+
}
|
|
122
130
|
get logger() {
|
|
123
131
|
return this._logger;
|
|
124
132
|
}
|
|
@@ -536,7 +544,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
536
544
|
if (this._started) {
|
|
537
545
|
return;
|
|
538
546
|
}
|
|
539
|
-
this._started =
|
|
547
|
+
this._started = /* @__PURE__ */ new Date();
|
|
540
548
|
if (options.checkInstall && !await this.isInstalled()) {
|
|
541
549
|
throw new import_application_not_install.ApplicationNotInstall(
|
|
542
550
|
`Application ${this.name} is not installed, Please run 'yarn nocobase install' command first`
|
|
@@ -564,7 +572,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
564
572
|
});
|
|
565
573
|
}
|
|
566
574
|
async isStarted() {
|
|
567
|
-
return this._started;
|
|
575
|
+
return Boolean(this._started);
|
|
568
576
|
}
|
|
569
577
|
/**
|
|
570
578
|
* @internal
|
|
@@ -581,7 +589,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
581
589
|
return;
|
|
582
590
|
}
|
|
583
591
|
this.log.info("restarting...");
|
|
584
|
-
this._started =
|
|
592
|
+
this._started = null;
|
|
585
593
|
await this.emitAsync("beforeStop");
|
|
586
594
|
await this.reload(options);
|
|
587
595
|
await this.start(options);
|
|
@@ -622,7 +630,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
622
630
|
await this.emitAsync("afterStop", this, options);
|
|
623
631
|
this.stopped = true;
|
|
624
632
|
log.info(`app has stopped`, { method: "stop" });
|
|
625
|
-
this._started =
|
|
633
|
+
this._started = null;
|
|
626
634
|
}
|
|
627
635
|
async destroy(options = {}) {
|
|
628
636
|
this.log.debug("start destroy app", { method: "destory" });
|
|
@@ -791,6 +799,7 @@ const _Application = class _Application extends import_koa.default {
|
|
|
791
799
|
this._cronJobManager = new import_cron_job_manager.CronJobManager(this);
|
|
792
800
|
this._cli = this.createCLI();
|
|
793
801
|
this._i18n = (0, import_helper.createI18n)(options);
|
|
802
|
+
this.syncManager = new import_sync_manager.SyncManager(this);
|
|
794
803
|
this.context.db = this.db;
|
|
795
804
|
this.context.resourcer = this.resourceManager;
|
|
796
805
|
this.context.resourceManager = this.resourceManager;
|
package/lib/commands/start.js
CHANGED
|
@@ -62,13 +62,13 @@ var start_default = /* @__PURE__ */ __name((app) => {
|
|
|
62
62
|
} else {
|
|
63
63
|
await app.install();
|
|
64
64
|
}
|
|
65
|
-
app["_started"] =
|
|
65
|
+
app["_started"] = /* @__PURE__ */ new Date();
|
|
66
66
|
await app.restart();
|
|
67
67
|
app.log.info("app has been started");
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
if (!await app.isInstalled()) {
|
|
71
|
-
app["_started"] =
|
|
71
|
+
app["_started"] = /* @__PURE__ */ new Date();
|
|
72
72
|
throw new import_application_not_install.ApplicationNotInstall(
|
|
73
73
|
`Application ${app.name} is not installed, Please run 'yarn nocobase install' command first`
|
|
74
74
|
);
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -50,6 +50,7 @@ __reExport(src_exports, require("./plugin"), module.exports);
|
|
|
50
50
|
__reExport(src_exports, require("./plugin-manager"), module.exports);
|
|
51
51
|
__reExport(src_exports, require("./gateway"), module.exports);
|
|
52
52
|
__reExport(src_exports, require("./app-supervisor"), module.exports);
|
|
53
|
+
__reExport(src_exports, require("./sync-manager"), module.exports);
|
|
53
54
|
const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
|
|
54
55
|
// Annotate the CommonJS export names for ESM import in node:
|
|
55
56
|
0 && (module.exports = {
|
|
@@ -60,5 +61,6 @@ const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
|
|
|
60
61
|
...require("./plugin"),
|
|
61
62
|
...require("./plugin-manager"),
|
|
62
63
|
...require("./gateway"),
|
|
63
|
-
...require("./app-supervisor")
|
|
64
|
+
...require("./app-supervisor"),
|
|
65
|
+
...require("./sync-manager")
|
|
64
66
|
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
/// <reference types="node" />
|
|
10
|
+
import EventEmitter from 'node:events';
|
|
11
|
+
import Application from './application';
|
|
12
|
+
export declare abstract class SyncAdapter extends EventEmitter {
|
|
13
|
+
abstract get ready(): boolean;
|
|
14
|
+
abstract publish(data: SyncMessage): void | Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export type SyncMessageData = Record<string, string>;
|
|
17
|
+
export type SyncEventCallback = (message: SyncMessageData) => void;
|
|
18
|
+
export type SyncMessage = {
|
|
19
|
+
namespace: string;
|
|
20
|
+
nodeId: string;
|
|
21
|
+
appName: string;
|
|
22
|
+
} & SyncMessageData;
|
|
23
|
+
/**
|
|
24
|
+
* @experimental
|
|
25
|
+
*/
|
|
26
|
+
export declare class SyncManager {
|
|
27
|
+
private nodeId;
|
|
28
|
+
private app;
|
|
29
|
+
private eventEmitter;
|
|
30
|
+
private adapter;
|
|
31
|
+
private incomingBuffer;
|
|
32
|
+
private outgoingBuffer;
|
|
33
|
+
private flushTimer;
|
|
34
|
+
private onSync;
|
|
35
|
+
private onReady;
|
|
36
|
+
constructor(app: Application);
|
|
37
|
+
init(adapter: SyncAdapter): void;
|
|
38
|
+
subscribe(namespace: string, callback: SyncEventCallback): void;
|
|
39
|
+
unsubscribe(namespace: string, callback: SyncEventCallback): void;
|
|
40
|
+
/**
|
|
41
|
+
* Publish a message to the sync manager
|
|
42
|
+
*/
|
|
43
|
+
publish(namespace: string, data: SyncMessageData): any;
|
|
44
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
17
|
+
var __export = (target, all) => {
|
|
18
|
+
for (var name in all)
|
|
19
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
20
|
+
};
|
|
21
|
+
var __copyProps = (to, from, except, desc) => {
|
|
22
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
23
|
+
for (let key of __getOwnPropNames(from))
|
|
24
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
25
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
26
|
+
}
|
|
27
|
+
return to;
|
|
28
|
+
};
|
|
29
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
32
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
33
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
34
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
35
|
+
mod
|
|
36
|
+
));
|
|
37
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
|
+
var sync_manager_exports = {};
|
|
39
|
+
__export(sync_manager_exports, {
|
|
40
|
+
SyncAdapter: () => SyncAdapter,
|
|
41
|
+
SyncManager: () => SyncManager
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(sync_manager_exports);
|
|
44
|
+
var import_node_crypto = require("node:crypto");
|
|
45
|
+
var import_node_events = __toESM(require("node:events"));
|
|
46
|
+
var import_lodash = require("lodash");
|
|
47
|
+
const _SyncAdapter = class _SyncAdapter extends import_node_events.default {
|
|
48
|
+
};
|
|
49
|
+
__name(_SyncAdapter, "SyncAdapter");
|
|
50
|
+
let SyncAdapter = _SyncAdapter;
|
|
51
|
+
const _SyncManager = class _SyncManager {
|
|
52
|
+
nodeId;
|
|
53
|
+
app;
|
|
54
|
+
eventEmitter = new import_node_events.default();
|
|
55
|
+
adapter = null;
|
|
56
|
+
incomingBuffer = [];
|
|
57
|
+
outgoingBuffer = [];
|
|
58
|
+
flushTimer = null;
|
|
59
|
+
onSync = (messages) => {
|
|
60
|
+
this.app.logger.info("sync messages received into buffer:", messages);
|
|
61
|
+
if (this.flushTimer) {
|
|
62
|
+
clearTimeout(this.flushTimer);
|
|
63
|
+
this.flushTimer = null;
|
|
64
|
+
}
|
|
65
|
+
this.incomingBuffer = (0, import_lodash.uniqWith)(
|
|
66
|
+
this.incomingBuffer.concat(
|
|
67
|
+
messages.filter((item) => item.nodeId !== this.nodeId && item.appName === this.app.name).map(({ nodeId, appName, ...message }) => message)
|
|
68
|
+
),
|
|
69
|
+
import_lodash.isEqual
|
|
70
|
+
);
|
|
71
|
+
this.flushTimer = setTimeout(() => {
|
|
72
|
+
this.incomingBuffer.forEach(({ namespace, ...message }) => {
|
|
73
|
+
this.app.logger.info(`emit sync event in namespace ${namespace}`);
|
|
74
|
+
this.eventEmitter.emit(namespace, message);
|
|
75
|
+
});
|
|
76
|
+
}, 1e3);
|
|
77
|
+
};
|
|
78
|
+
onReady = () => {
|
|
79
|
+
while (this.outgoingBuffer.length) {
|
|
80
|
+
const [namespace, data] = this.outgoingBuffer.shift();
|
|
81
|
+
this.publish(namespace, data);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
constructor(app) {
|
|
85
|
+
this.app = app;
|
|
86
|
+
this.nodeId = `${process.env.NODE_ID || (0, import_node_crypto.randomUUID)()}-${process.pid}`;
|
|
87
|
+
}
|
|
88
|
+
init(adapter) {
|
|
89
|
+
if (this.adapter) {
|
|
90
|
+
throw new Error("sync adapter is already exists");
|
|
91
|
+
}
|
|
92
|
+
if (!adapter) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.adapter = adapter;
|
|
96
|
+
this.adapter.on("message", this.onSync);
|
|
97
|
+
this.adapter.on("ready", this.onReady);
|
|
98
|
+
}
|
|
99
|
+
subscribe(namespace, callback) {
|
|
100
|
+
this.eventEmitter.on(namespace, callback);
|
|
101
|
+
}
|
|
102
|
+
unsubscribe(namespace, callback) {
|
|
103
|
+
this.eventEmitter.off(namespace, callback);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Publish a message to the sync manager
|
|
107
|
+
*/
|
|
108
|
+
publish(namespace, data) {
|
|
109
|
+
if (!this.adapter) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!this.adapter.ready) {
|
|
113
|
+
this.outgoingBuffer.push([namespace, data]);
|
|
114
|
+
this.app.logger.warn(`sync adapter is not ready for now, message will be send when it is ready`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.app.logger.info(`publishing sync message from #${this.nodeId} (${this.app.name}) in namespace ${namespace}:`, {
|
|
118
|
+
data
|
|
119
|
+
});
|
|
120
|
+
return this.adapter.publish({ ...data, nodeId: this.nodeId, appName: this.app.name, namespace });
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
__name(_SyncManager, "SyncManager");
|
|
124
|
+
let SyncManager = _SyncManager;
|
|
125
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
126
|
+
0 && (module.exports = {
|
|
127
|
+
SyncAdapter,
|
|
128
|
+
SyncManager
|
|
129
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-alpha.20240710141659",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "./lib/index.d.ts",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
"@koa/cors": "^3.1.0",
|
|
11
11
|
"@koa/multer": "^3.0.2",
|
|
12
12
|
"@koa/router": "^9.4.0",
|
|
13
|
-
"@nocobase/acl": "1.
|
|
14
|
-
"@nocobase/actions": "1.
|
|
15
|
-
"@nocobase/auth": "1.
|
|
16
|
-
"@nocobase/cache": "1.
|
|
17
|
-
"@nocobase/data-source-manager": "1.
|
|
18
|
-
"@nocobase/database": "1.
|
|
19
|
-
"@nocobase/evaluators": "1.
|
|
20
|
-
"@nocobase/logger": "1.
|
|
21
|
-
"@nocobase/resourcer": "1.
|
|
22
|
-
"@nocobase/sdk": "1.
|
|
23
|
-
"@nocobase/telemetry": "1.
|
|
24
|
-
"@nocobase/utils": "1.
|
|
13
|
+
"@nocobase/acl": "1.3.0-alpha.20240710141659",
|
|
14
|
+
"@nocobase/actions": "1.3.0-alpha.20240710141659",
|
|
15
|
+
"@nocobase/auth": "1.3.0-alpha.20240710141659",
|
|
16
|
+
"@nocobase/cache": "1.3.0-alpha.20240710141659",
|
|
17
|
+
"@nocobase/data-source-manager": "1.3.0-alpha.20240710141659",
|
|
18
|
+
"@nocobase/database": "1.3.0-alpha.20240710141659",
|
|
19
|
+
"@nocobase/evaluators": "1.3.0-alpha.20240710141659",
|
|
20
|
+
"@nocobase/logger": "1.3.0-alpha.20240710141659",
|
|
21
|
+
"@nocobase/resourcer": "1.3.0-alpha.20240710141659",
|
|
22
|
+
"@nocobase/sdk": "1.3.0-alpha.20240710141659",
|
|
23
|
+
"@nocobase/telemetry": "1.3.0-alpha.20240710141659",
|
|
24
|
+
"@nocobase/utils": "1.3.0-alpha.20240710141659",
|
|
25
25
|
"@types/decompress": "4.2.4",
|
|
26
26
|
"@types/ini": "^1.3.31",
|
|
27
27
|
"@types/koa-send": "^4.1.3",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"@types/serve-handler": "^6.1.1",
|
|
55
55
|
"@types/ws": "^8.5.5"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "cb8b234443034da0dfa57dd5d6cca1f3b3db6f08"
|
|
58
58
|
}
|