@nocobase/server 1.9.0-beta.4 → 1.9.0-beta.5

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.
@@ -15,7 +15,7 @@ export type QueueCallbackOptions = {
15
15
  retried?: number;
16
16
  signal?: AbortSignal;
17
17
  };
18
- export type QueueCallback = (message: any, options: QueueCallbackOptions) => Promise<void> | void;
18
+ export type QueueCallback = (message: any, options: QueueCallbackOptions) => Promise<void>;
19
19
  export type QueueEventOptions = {
20
20
  /**
21
21
  * @experimental
@@ -53,9 +53,9 @@ export declare class MemoryEventQueueAdapter implements IEventQueueAdapter {
53
53
  content: any;
54
54
  options?: QueueMessageOptions;
55
55
  }[]>;
56
- get processing(): Promise<void[]>;
56
+ get processing(): Promise<Promise<void>[][]>;
57
57
  private get storagePath();
58
- listen: (channel: string) => Promise<void>;
58
+ listen: (channel: string) => void;
59
59
  constructor(options: {
60
60
  appName: string;
61
61
  });
@@ -69,7 +69,7 @@ export declare class MemoryEventQueueAdapter implements IEventQueueAdapter {
69
69
  unsubscribe(channel: string): void;
70
70
  publish(channel: string, content: any, options?: QueueMessageOptions): void;
71
71
  consume(channel: string, once?: boolean): Promise<void>;
72
- read(channel: string): Promise<void>;
72
+ read(channel: string, n: number): Promise<void>[];
73
73
  process(channel: string, { id, message }: {
74
74
  id: any;
75
75
  message: any;
@@ -73,26 +73,37 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
73
73
  get storagePath() {
74
74
  return import_path.default.resolve(process.cwd(), "storage", "apps", this.options.appName, "event-queue.json");
75
75
  }
76
- listen = /* @__PURE__ */ __name(async (channel) => {
76
+ listen = /* @__PURE__ */ __name((channel) => {
77
77
  if (!this.connected) {
78
78
  return;
79
79
  }
80
- if (this.reading.has(channel)) {
81
- console.debug(`memory queue (${channel}) is already reading, waiting last reading to end...`);
82
- await this.reading.get(channel);
83
- }
84
80
  const event = this.events.get(channel);
85
81
  if (!event) {
86
82
  console.warn(`memory queue (${channel}) not found, skipping...`);
87
83
  return;
88
84
  }
89
85
  if (!event.idle()) {
90
- console.debug(`memory queue (${channel}) is not idle, skipping...`);
91
86
  return;
92
87
  }
93
- const reading = this.read(channel);
88
+ const reading = this.reading.get(channel) || [];
89
+ const count = (event.concurrency || QUEUE_DEFAULT_CONCURRENCY) - reading.length;
90
+ if (count <= 0) {
91
+ console.debug(
92
+ `memory queue (${channel}) is already reading as max concurrency (${reading.length}), waiting last reading to end...`
93
+ );
94
+ return;
95
+ }
96
+ console.debug(`reading more from queue (${channel}), count: ${count}`);
97
+ this.read(channel, count).forEach((promise) => {
98
+ reading.push(promise);
99
+ promise.finally(() => {
100
+ const index = reading.indexOf(promise);
101
+ if (index > -1) {
102
+ reading.splice(index, 1);
103
+ }
104
+ });
105
+ });
94
106
  this.reading.set(channel, reading);
95
- await reading;
96
107
  }, "listen");
97
108
  isConnected() {
98
109
  return this.connected;
@@ -149,6 +160,9 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
149
160
  });
150
161
  }
151
162
  async close() {
163
+ if (!this.connected) {
164
+ return;
165
+ }
152
166
  this.connected = false;
153
167
  if (this.processing) {
154
168
  console.info("memory queue waiting for processing job...");
@@ -200,7 +214,7 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
200
214
  const interval = event.interval || QUEUE_DEFAULT_INTERVAL;
201
215
  const queue = this.queues.get(channel);
202
216
  if (event.idle() && (queue == null ? void 0 : queue.length)) {
203
- await this.listen(channel);
217
+ this.listen(channel);
204
218
  }
205
219
  if (once) {
206
220
  break;
@@ -208,47 +222,41 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
208
222
  await (0, import_utils.sleep)(interval);
209
223
  }
210
224
  }
211
- async read(channel) {
212
- const event = this.events.get(channel);
213
- if (!event) {
214
- this.reading.delete(channel);
215
- return;
216
- }
225
+ read(channel, n) {
217
226
  const queue = this.queues.get(channel);
218
- if (queue == null ? void 0 : queue.length) {
219
- const messages = queue.slice(0, event.concurrency || QUEUE_DEFAULT_CONCURRENCY);
220
- console.debug(`memory queue (${channel}) read ${messages.length} messages`, messages);
221
- queue.splice(0, messages.length);
222
- const batch = messages.map(({ id, ...message }) => this.process(channel, { id, message }));
223
- await Promise.all(batch);
227
+ if (!(queue == null ? void 0 : queue.length)) {
228
+ return [];
224
229
  }
225
- this.reading.delete(channel);
230
+ const messages = queue.slice(0, n);
231
+ console.debug(`memory queue (${channel}) read ${messages.length} messages`, messages);
232
+ queue.splice(0, messages.length);
233
+ const batch = messages.map(({ id, ...message }) => this.process(channel, { id, message }));
234
+ return batch;
226
235
  }
227
236
  async process(channel, { id, message }) {
228
237
  const event = this.events.get(channel);
229
238
  const { content, options: { timeout = QUEUE_DEFAULT_ACK_TIMEOUT, maxRetries = 0, retried = 0 } = {} } = message;
230
- try {
231
- console.debug(`memory queue (${channel}) processing message (${id})...`, content);
232
- await event.process(content, {
233
- id,
234
- retried,
235
- signal: AbortSignal.timeout(timeout)
236
- });
239
+ console.debug(`memory queue (${channel}) processing message (${id})...`, content);
240
+ return (async () => event.process(content, {
241
+ id,
242
+ retried,
243
+ signal: AbortSignal.timeout(timeout)
244
+ }))().then(() => {
237
245
  console.debug(`memory queue (${channel}) consumed message (${id})`);
238
- } catch (ex) {
246
+ }).catch((ex) => {
239
247
  if (maxRetries > 0 && retried < maxRetries) {
240
248
  const currentRetry = retried + 1;
241
249
  console.warn(
242
250
  `memory queue (${channel}) consum message (${id}) failed, retrying (${currentRetry} / ${maxRetries})...`,
243
251
  ex
244
252
  );
245
- setImmediate(() => {
253
+ setTimeout(() => {
246
254
  this.publish(channel, content, { timeout, maxRetries, retried: currentRetry, timestamp: Date.now() });
247
- });
255
+ }, 500);
248
256
  } else {
249
257
  console.error(ex);
250
258
  }
251
- }
259
+ });
252
260
  }
253
261
  };
254
262
  __name(_MemoryEventQueueAdapter, "MemoryEventQueueAdapter");
package/lib/helper.d.ts CHANGED
@@ -16,3 +16,4 @@ export declare const createAppProxy: (app: Application) => Application<import(".
16
16
  export declare const getCommandFullName: (command: Command) => string;
17
17
  export declare const tsxRerunning: () => Promise<void>;
18
18
  export declare const enablePerfHooks: (app: Application) => void;
19
+ export declare function getBodyLimit(): string;
package/lib/helper.js CHANGED
@@ -41,6 +41,7 @@ __export(helper_exports, {
41
41
  createI18n: () => createI18n,
42
42
  createResourcer: () => createResourcer,
43
43
  enablePerfHooks: () => enablePerfHooks,
44
+ getBodyLimit: () => getBodyLimit,
44
45
  getCommandFullName: () => getCommandFullName,
45
46
  registerMiddlewares: () => registerMiddlewares,
46
47
  tsxRerunning: () => tsxRerunning
@@ -99,7 +100,7 @@ function registerMiddlewares(app, options) {
99
100
  }
100
101
  );
101
102
  if (options.bodyParser !== false) {
102
- const bodyLimit = "10mb";
103
+ const bodyLimit = getBodyLimit();
103
104
  app.use(
104
105
  (0, import_koa_bodyparser.default)({
105
106
  jsonLimit: bodyLimit,
@@ -188,12 +189,17 @@ const enablePerfHooks = /* @__PURE__ */ __name((app) => {
188
189
  });
189
190
  app.acl.allow("perf", "*", "public");
190
191
  }, "enablePerfHooks");
192
+ function getBodyLimit() {
193
+ return process.env.REQUEST_BODY_LIMIT || "10mb";
194
+ }
195
+ __name(getBodyLimit, "getBodyLimit");
191
196
  // Annotate the CommonJS export names for ESM import in node:
192
197
  0 && (module.exports = {
193
198
  createAppProxy,
194
199
  createI18n,
195
200
  createResourcer,
196
201
  enablePerfHooks,
202
+ getBodyLimit,
197
203
  getCommandFullName,
198
204
  registerMiddlewares,
199
205
  tsxRerunning
@@ -46,7 +46,7 @@ const traverseHasMany = /* @__PURE__ */ __name((arr, { collection, exclude = [],
46
46
  if (!arr) {
47
47
  return arr;
48
48
  }
49
- return arr.map((item) => traverseJSON(item, { collection, exclude, include }));
49
+ return arr.map((item) => traverseJSON(item, { collection, exclude, include, isHasManyField: true }));
50
50
  }, "traverseHasMany");
51
51
  const traverseBelongsToMany = /* @__PURE__ */ __name((arr, { collection, exclude = [], through }) => {
52
52
  if (!arr) {
@@ -107,7 +107,10 @@ const traverseJSON = /* @__PURE__ */ __name((data, options) => {
107
107
  if (field.options.isForeignKey) {
108
108
  continue;
109
109
  }
110
- if (["sort", "password", "sequence"].includes(field.type)) {
110
+ if (!options.isHasManyField && ["sort"].includes(field.type)) {
111
+ continue;
112
+ }
113
+ if (["password", "sequence"].includes(field.type)) {
111
114
  continue;
112
115
  }
113
116
  if (field.type === "hasOne") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/server",
3
- "version": "1.9.0-beta.4",
3
+ "version": "1.9.0-beta.5",
4
4
  "main": "lib/index.js",
5
5
  "types": "./lib/index.d.ts",
6
6
  "license": "AGPL-3.0",
@@ -10,19 +10,19 @@
10
10
  "@koa/cors": "^5.0.0",
11
11
  "@koa/multer": "^3.1.0",
12
12
  "@koa/router": "^13.1.0",
13
- "@nocobase/acl": "1.9.0-beta.4",
14
- "@nocobase/actions": "1.9.0-beta.4",
15
- "@nocobase/auth": "1.9.0-beta.4",
16
- "@nocobase/cache": "1.9.0-beta.4",
17
- "@nocobase/data-source-manager": "1.9.0-beta.4",
18
- "@nocobase/database": "1.9.0-beta.4",
19
- "@nocobase/evaluators": "1.9.0-beta.4",
20
- "@nocobase/lock-manager": "1.9.0-beta.4",
21
- "@nocobase/logger": "1.9.0-beta.4",
22
- "@nocobase/resourcer": "1.9.0-beta.4",
23
- "@nocobase/sdk": "1.9.0-beta.4",
24
- "@nocobase/telemetry": "1.9.0-beta.4",
25
- "@nocobase/utils": "1.9.0-beta.4",
13
+ "@nocobase/acl": "1.9.0-beta.5",
14
+ "@nocobase/actions": "1.9.0-beta.5",
15
+ "@nocobase/auth": "1.9.0-beta.5",
16
+ "@nocobase/cache": "1.9.0-beta.5",
17
+ "@nocobase/data-source-manager": "1.9.0-beta.5",
18
+ "@nocobase/database": "1.9.0-beta.5",
19
+ "@nocobase/evaluators": "1.9.0-beta.5",
20
+ "@nocobase/lock-manager": "1.9.0-beta.5",
21
+ "@nocobase/logger": "1.9.0-beta.5",
22
+ "@nocobase/resourcer": "1.9.0-beta.5",
23
+ "@nocobase/sdk": "1.9.0-beta.5",
24
+ "@nocobase/telemetry": "1.9.0-beta.5",
25
+ "@nocobase/utils": "1.9.0-beta.5",
26
26
  "@types/decompress": "4.2.7",
27
27
  "@types/ini": "^1.3.31",
28
28
  "@types/koa-send": "^4.1.3",
@@ -57,5 +57,5 @@
57
57
  "@types/serve-handler": "^6.1.1",
58
58
  "@types/ws": "^8.5.5"
59
59
  },
60
- "gitHead": "0276aa12d87f82c73d62a9712134fe363e2c772a"
60
+ "gitHead": "9a61c60dd3db5af64244e82447309b0cb17aabb6"
61
61
  }