@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.
@@ -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: boolean;
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;
@@ -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 = true;
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 = false;
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 = false;
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;
@@ -62,13 +62,13 @@ var start_default = /* @__PURE__ */ __name((app) => {
62
62
  } else {
63
63
  await app.install();
64
64
  }
65
- app["_started"] = true;
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"] = true;
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
@@ -14,4 +14,5 @@ export * from './plugin';
14
14
  export * from './plugin-manager';
15
15
  export * from './gateway';
16
16
  export * from './app-supervisor';
17
+ export * from './sync-manager';
17
18
  export declare const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
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.2.14-alpha",
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.2.14-alpha",
14
- "@nocobase/actions": "1.2.14-alpha",
15
- "@nocobase/auth": "1.2.14-alpha",
16
- "@nocobase/cache": "1.2.14-alpha",
17
- "@nocobase/data-source-manager": "1.2.14-alpha",
18
- "@nocobase/database": "1.2.14-alpha",
19
- "@nocobase/evaluators": "1.2.14-alpha",
20
- "@nocobase/logger": "1.2.14-alpha",
21
- "@nocobase/resourcer": "1.2.14-alpha",
22
- "@nocobase/sdk": "1.2.14-alpha",
23
- "@nocobase/telemetry": "1.2.14-alpha",
24
- "@nocobase/utils": "1.2.14-alpha",
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": "717c71eee8cec8d230f1856759d97d6a843f8be6"
57
+ "gitHead": "cb8b234443034da0dfa57dd5d6cca1f3b3db6f08"
58
58
  }