@nocobase/plugin-async-task-manager 1.7.0-beta.9 → 1.8.0-beta.1

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.
Files changed (121) hide show
  1. package/LICENSE.txt +4 -4
  2. package/dist/client/AsyncTaskManagerProvider.d.ts +8 -2
  3. package/dist/client/components/AsyncTasks.d.ts +8 -0
  4. package/dist/client/index.js +1 -1
  5. package/dist/externalVersion.js +5 -5
  6. package/dist/locale/en-US.json +2 -1
  7. package/dist/locale/nl-NL.json +45 -4
  8. package/dist/locale/zh-CN.json +1 -1
  9. package/dist/node_modules/p-queue/dist/index.d.ts +101 -0
  10. package/dist/node_modules/p-queue/dist/index.js +1 -0
  11. package/dist/node_modules/p-queue/dist/lower-bound.d.ts +1 -0
  12. package/dist/node_modules/p-queue/dist/lower-bound.js +21 -0
  13. package/dist/node_modules/p-queue/dist/options.d.ts +64 -0
  14. package/dist/node_modules/p-queue/dist/options.js +2 -0
  15. package/dist/node_modules/p-queue/dist/priority-queue.d.ts +12 -0
  16. package/dist/node_modules/p-queue/dist/priority-queue.js +32 -0
  17. package/dist/node_modules/p-queue/dist/queue.d.ts +7 -0
  18. package/dist/node_modules/p-queue/dist/queue.js +2 -0
  19. package/dist/node_modules/p-queue/license +9 -0
  20. package/dist/node_modules/p-queue/node_modules/eventemitter3/index.d.ts +134 -0
  21. package/dist/node_modules/p-queue/node_modules/eventemitter3/index.js +336 -0
  22. package/dist/node_modules/p-queue/node_modules/eventemitter3/package.json +56 -0
  23. package/dist/node_modules/p-queue/node_modules/eventemitter3/umd/eventemitter3.js +340 -0
  24. package/dist/node_modules/p-queue/node_modules/eventemitter3/umd/eventemitter3.min.js +1 -0
  25. package/dist/node_modules/p-queue/package.json +1 -0
  26. package/dist/node_modules/uuid/dist/bin/uuid +2 -0
  27. package/dist/node_modules/uuid/dist/commonjs-browser/index.js +79 -0
  28. package/dist/node_modules/uuid/dist/commonjs-browser/md5.js +223 -0
  29. package/dist/node_modules/uuid/dist/commonjs-browser/native.js +11 -0
  30. package/dist/node_modules/uuid/dist/commonjs-browser/nil.js +8 -0
  31. package/dist/node_modules/uuid/dist/commonjs-browser/parse.js +45 -0
  32. package/dist/node_modules/uuid/dist/commonjs-browser/regex.js +8 -0
  33. package/dist/node_modules/uuid/dist/commonjs-browser/rng.js +25 -0
  34. package/dist/node_modules/uuid/dist/commonjs-browser/sha1.js +104 -0
  35. package/dist/node_modules/uuid/dist/commonjs-browser/stringify.js +44 -0
  36. package/dist/node_modules/uuid/dist/commonjs-browser/v1.js +107 -0
  37. package/dist/node_modules/uuid/dist/commonjs-browser/v3.js +16 -0
  38. package/dist/node_modules/uuid/dist/commonjs-browser/v35.js +80 -0
  39. package/dist/node_modules/uuid/dist/commonjs-browser/v4.js +43 -0
  40. package/dist/node_modules/uuid/dist/commonjs-browser/v5.js +16 -0
  41. package/dist/node_modules/uuid/dist/commonjs-browser/validate.js +17 -0
  42. package/dist/node_modules/uuid/dist/commonjs-browser/version.js +21 -0
  43. package/dist/node_modules/uuid/dist/esm-browser/index.js +9 -0
  44. package/dist/node_modules/uuid/{lib/md5-browser.js → dist/esm-browser/md5.js} +80 -81
  45. package/dist/node_modules/uuid/dist/esm-browser/native.js +4 -0
  46. package/dist/node_modules/uuid/dist/esm-browser/nil.js +1 -0
  47. package/dist/node_modules/uuid/dist/esm-browser/parse.js +35 -0
  48. package/dist/node_modules/uuid/dist/esm-browser/regex.js +1 -0
  49. package/dist/node_modules/uuid/dist/esm-browser/rng.js +18 -0
  50. package/dist/node_modules/uuid/dist/esm-browser/sha1.js +96 -0
  51. package/dist/node_modules/uuid/dist/esm-browser/stringify.js +33 -0
  52. package/dist/node_modules/uuid/dist/esm-browser/v1.js +95 -0
  53. package/dist/node_modules/uuid/dist/esm-browser/v3.js +4 -0
  54. package/dist/node_modules/uuid/dist/esm-browser/v35.js +66 -0
  55. package/dist/node_modules/uuid/dist/esm-browser/v4.js +29 -0
  56. package/dist/node_modules/uuid/dist/esm-browser/v5.js +4 -0
  57. package/dist/node_modules/uuid/dist/esm-browser/validate.js +7 -0
  58. package/dist/node_modules/uuid/dist/esm-browser/version.js +11 -0
  59. package/dist/node_modules/uuid/dist/esm-node/index.js +9 -0
  60. package/dist/node_modules/uuid/dist/esm-node/md5.js +13 -0
  61. package/dist/node_modules/uuid/dist/esm-node/native.js +4 -0
  62. package/dist/node_modules/uuid/dist/esm-node/nil.js +1 -0
  63. package/dist/node_modules/uuid/dist/esm-node/parse.js +35 -0
  64. package/dist/node_modules/uuid/dist/esm-node/regex.js +1 -0
  65. package/dist/node_modules/uuid/dist/esm-node/rng.js +12 -0
  66. package/dist/node_modules/uuid/dist/esm-node/sha1.js +13 -0
  67. package/dist/node_modules/uuid/dist/esm-node/stringify.js +33 -0
  68. package/dist/node_modules/uuid/dist/esm-node/v1.js +95 -0
  69. package/dist/node_modules/uuid/dist/esm-node/v3.js +4 -0
  70. package/dist/node_modules/uuid/dist/esm-node/v35.js +66 -0
  71. package/dist/node_modules/uuid/dist/esm-node/v4.js +29 -0
  72. package/dist/node_modules/uuid/dist/esm-node/v5.js +4 -0
  73. package/dist/node_modules/uuid/dist/esm-node/validate.js +7 -0
  74. package/dist/node_modules/uuid/dist/esm-node/version.js +11 -0
  75. package/dist/node_modules/uuid/dist/index.js +1 -0
  76. package/dist/node_modules/uuid/dist/md5-browser.js +223 -0
  77. package/dist/node_modules/uuid/dist/md5.js +23 -0
  78. package/dist/node_modules/uuid/dist/native-browser.js +11 -0
  79. package/dist/node_modules/uuid/dist/native.js +15 -0
  80. package/dist/node_modules/uuid/dist/nil.js +8 -0
  81. package/dist/node_modules/uuid/dist/parse.js +45 -0
  82. package/dist/node_modules/uuid/dist/regex.js +8 -0
  83. package/dist/node_modules/uuid/dist/rng-browser.js +25 -0
  84. package/dist/node_modules/uuid/dist/rng.js +24 -0
  85. package/dist/node_modules/uuid/dist/sha1-browser.js +104 -0
  86. package/dist/node_modules/uuid/dist/sha1.js +23 -0
  87. package/dist/node_modules/uuid/dist/stringify.js +44 -0
  88. package/dist/node_modules/uuid/dist/uuid-bin.js +85 -0
  89. package/dist/node_modules/uuid/dist/v1.js +107 -0
  90. package/dist/node_modules/uuid/dist/v3.js +16 -0
  91. package/dist/node_modules/uuid/dist/v35.js +80 -0
  92. package/dist/node_modules/uuid/dist/v4.js +43 -0
  93. package/dist/node_modules/uuid/dist/v5.js +16 -0
  94. package/dist/node_modules/uuid/dist/validate.js +17 -0
  95. package/dist/node_modules/uuid/dist/version.js +21 -0
  96. package/dist/node_modules/uuid/package.json +1 -1
  97. package/dist/server/base-task-manager.d.ts +14 -0
  98. package/dist/server/base-task-manager.js +64 -0
  99. package/dist/server/interfaces/async-task-manager.d.ts +11 -0
  100. package/dist/server/interfaces/task.d.ts +9 -0
  101. package/dist/server/plugin.d.ts +8 -0
  102. package/dist/server/plugin.js +2 -2
  103. package/dist/server/resourcers/async-tasks.d.ts +10 -0
  104. package/dist/server/resourcers/async-tasks.js +29 -2
  105. package/dist/server/task-type.d.ts +9 -0
  106. package/dist/server/task-type.js +9 -4
  107. package/package.json +5 -2
  108. package/dist/node_modules/uuid/AUTHORS +0 -5
  109. package/dist/node_modules/uuid/bin/uuid +0 -65
  110. package/dist/node_modules/uuid/index.js +0 -1
  111. package/dist/node_modules/uuid/lib/bytesToUuid.js +0 -26
  112. package/dist/node_modules/uuid/lib/md5.js +0 -25
  113. package/dist/node_modules/uuid/lib/rng-browser.js +0 -34
  114. package/dist/node_modules/uuid/lib/rng.js +0 -8
  115. package/dist/node_modules/uuid/lib/sha1-browser.js +0 -89
  116. package/dist/node_modules/uuid/lib/sha1.js +0 -25
  117. package/dist/node_modules/uuid/lib/v35.js +0 -57
  118. package/dist/node_modules/uuid/v1.js +0 -109
  119. package/dist/node_modules/uuid/v3.js +0 -4
  120. package/dist/node_modules/uuid/v4.js +0 -29
  121. package/dist/node_modules/uuid/v5.js +0 -3
@@ -1 +1 @@
1
- {"name":"uuid","version":"3.4.0","description":"RFC4122 (v1, v4, and v5) UUIDs","commitlint":{"extends":["@commitlint/config-conventional"]},"keywords":["uuid","guid","rfc4122"],"license":"MIT","bin":{"uuid":"./bin/uuid"},"devDependencies":{"@commitlint/cli":"~8.2.0","@commitlint/config-conventional":"~8.2.0","eslint":"~6.4.0","husky":"~3.0.5","mocha":"6.2.0","runmd":"1.2.1","standard-version":"7.0.0"},"scripts":{"lint":"eslint .","test":"npm run lint && mocha test/test.js","md":"runmd --watch --output=README.md README_js.md","release":"standard-version","prepare":"runmd --output=README.md README_js.md"},"browser":{"./lib/rng.js":"./lib/rng-browser.js","./lib/sha1.js":"./lib/sha1-browser.js","./lib/md5.js":"./lib/md5-browser.js"},"repository":{"type":"git","url":"https://github.com/uuidjs/uuid.git"},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"_lastModified":"2025-03-25T05:43:54.380Z"}
1
+ {"name":"uuid","version":"9.0.1","description":"RFC4122 (v1, v4, and v5) UUIDs","funding":["https://github.com/sponsors/broofa","https://github.com/sponsors/ctavan"],"commitlint":{"extends":["@commitlint/config-conventional"]},"keywords":["uuid","guid","rfc4122"],"license":"MIT","bin":{"uuid":"./dist/bin/uuid"},"sideEffects":false,"main":"./dist/index.js","exports":{".":{"node":{"module":"./dist/esm-node/index.js","require":"./dist/index.js","import":"./wrapper.mjs"},"browser":{"import":"./dist/esm-browser/index.js","require":"./dist/commonjs-browser/index.js"},"default":"./dist/esm-browser/index.js"},"./package.json":"./package.json"},"module":"./dist/esm-node/index.js","browser":{"./dist/md5.js":"./dist/md5-browser.js","./dist/native.js":"./dist/native-browser.js","./dist/rng.js":"./dist/rng-browser.js","./dist/sha1.js":"./dist/sha1-browser.js","./dist/esm-node/index.js":"./dist/esm-browser/index.js"},"files":["CHANGELOG.md","CONTRIBUTING.md","LICENSE.md","README.md","dist","wrapper.mjs"],"devDependencies":{"@babel/cli":"7.18.10","@babel/core":"7.18.10","@babel/eslint-parser":"7.18.9","@babel/preset-env":"7.18.10","@commitlint/cli":"17.0.3","@commitlint/config-conventional":"17.0.3","bundlewatch":"0.3.3","eslint":"8.21.0","eslint-config-prettier":"8.5.0","eslint-config-standard":"17.0.0","eslint-plugin-import":"2.26.0","eslint-plugin-node":"11.1.0","eslint-plugin-prettier":"4.2.1","eslint-plugin-promise":"6.0.0","husky":"8.0.1","jest":"28.1.3","lint-staged":"13.0.3","npm-run-all":"4.1.5","optional-dev-dependency":"2.0.1","prettier":"2.7.1","random-seed":"0.3.0","runmd":"1.3.9","standard-version":"9.5.0"},"optionalDevDependencies":{"@wdio/browserstack-service":"7.16.10","@wdio/cli":"7.16.10","@wdio/jasmine-framework":"7.16.6","@wdio/local-runner":"7.16.10","@wdio/spec-reporter":"7.16.9","@wdio/static-server-service":"7.16.6"},"scripts":{"examples:browser:webpack:build":"cd examples/browser-webpack && npm install && npm run build","examples:browser:rollup:build":"cd examples/browser-rollup && npm install && npm run build","examples:node:commonjs:test":"cd examples/node-commonjs && npm install && npm test","examples:node:esmodules:test":"cd examples/node-esmodules && npm install && npm test","examples:node:jest:test":"cd examples/node-jest && npm install && npm test","prepare":"cd $( git rev-parse --show-toplevel ) && husky install","lint":"npm run eslint:check && npm run prettier:check","eslint:check":"eslint src/ test/ examples/ *.js","eslint:fix":"eslint --fix src/ test/ examples/ *.js","pretest":"[ -n $CI ] || npm run build","test":"BABEL_ENV=commonjsNode node --throw-deprecation node_modules/.bin/jest test/unit/","pretest:browser":"optional-dev-dependency && npm run build && npm-run-all --parallel examples:browser:**","test:browser":"wdio run ./wdio.conf.js","pretest:node":"npm run build","test:node":"npm-run-all --parallel examples:node:**","test:pack":"./scripts/testpack.sh","pretest:benchmark":"npm run build","test:benchmark":"cd examples/benchmark && npm install && npm test","prettier:check":"prettier --check '**/*.{js,jsx,json,md}'","prettier:fix":"prettier --write '**/*.{js,jsx,json,md}'","bundlewatch":"npm run pretest:browser && bundlewatch --config bundlewatch.config.json","md":"runmd --watch --output=README.md README_js.md","docs":"( node --version | grep -q 'v18' ) && ( npm run build && npx runmd --output=README.md README_js.md )","docs:diff":"npm run docs && git diff --quiet README.md","build":"./scripts/build.sh","prepack":"npm run build","release":"standard-version --no-verify"},"repository":{"type":"git","url":"https://github.com/uuidjs/uuid.git"},"lint-staged":{"*.{js,jsx,json,md}":["prettier --write"],"*.{js,jsx}":["eslint --fix"]},"standard-version":{"scripts":{"postchangelog":"prettier --write CHANGELOG.md"}},"_lastModified":"2025-06-03T16:04:53.531Z"}
@@ -1,3 +1,11 @@
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
+ */
1
9
  /// <reference types="node" />
2
10
  import { EventEmitter } from 'events';
3
11
  import { AsyncTasksManager, CreateTaskOptions, TaskId, TaskStatus } from './interfaces/async-task-manager';
@@ -10,12 +18,18 @@ export declare class BaseTaskManager extends EventEmitter implements AsyncTasksM
10
18
  private readonly cleanupDelay;
11
19
  private logger;
12
20
  private app;
21
+ queue: any;
22
+ private queueOptions;
13
23
  setLogger(logger: Logger): void;
14
24
  setApp(app: Application): void;
15
25
  private scheduleCleanup;
16
26
  constructor();
27
+ private enqueueTask;
28
+ pauseQueue(): void;
29
+ resumeQueue(): void;
17
30
  cancelTask(taskId: TaskId): Promise<boolean>;
18
31
  createTask<T>(options: CreateTaskOptions): ITask;
32
+ runTask(taskId: TaskId): void;
19
33
  getTask(taskId: TaskId): ITask | undefined;
20
34
  getTaskStatus(taskId: TaskId): Promise<TaskStatus>;
21
35
  registerTaskType(taskType: TaskConstructor): void;
@@ -7,9 +7,11 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
+ var __create = Object.create;
10
11
  var __defProp = Object.defineProperty;
11
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
13
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
13
15
  var __hasOwnProp = Object.prototype.hasOwnProperty;
14
16
  var __export = (target, all) => {
15
17
  for (var name in all)
@@ -23,6 +25,14 @@ var __copyProps = (to, from, except, desc) => {
23
25
  }
24
26
  return to;
25
27
  };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
26
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
37
  var base_task_manager_exports = {};
28
38
  __export(base_task_manager_exports, {
@@ -30,6 +40,7 @@ __export(base_task_manager_exports, {
30
40
  });
31
41
  module.exports = __toCommonJS(base_task_manager_exports);
32
42
  var import_events = require("events");
43
+ var import_p_queue = __toESM(require("p-queue"));
33
44
  class BaseTaskManager extends import_events.EventEmitter {
34
45
  taskTypes = /* @__PURE__ */ new Map();
35
46
  tasks = /* @__PURE__ */ new Map();
@@ -37,6 +48,8 @@ class BaseTaskManager extends import_events.EventEmitter {
37
48
  cleanupDelay = 30 * 60 * 1e3;
38
49
  logger;
39
50
  app;
51
+ queue;
52
+ queueOptions;
40
53
  setLogger(logger) {
41
54
  this.logger = logger;
42
55
  }
@@ -51,6 +64,42 @@ class BaseTaskManager extends import_events.EventEmitter {
51
64
  }
52
65
  constructor() {
53
66
  super();
67
+ this.queueOptions = {
68
+ concurrency: process.env.ASYNC_TASK_MAX_CONCURRENCY ? parseInt(process.env.ASYNC_TASK_MAX_CONCURRENCY) : 3,
69
+ autoStart: true
70
+ };
71
+ this.queue = new import_p_queue.default(this.queueOptions);
72
+ this.queue.on("idle", () => {
73
+ this.logger.debug("Task queue is idle");
74
+ this.emit("queueIdle");
75
+ });
76
+ this.queue.on("add", () => {
77
+ this.logger.debug(`Task added to queue. Size: ${this.queue.size}, Pending: ${this.queue.pending}`);
78
+ this.emit("queueAdd", { size: this.queue.size, pending: this.queue.pending });
79
+ });
80
+ }
81
+ enqueueTask(task) {
82
+ const taskHandler = async () => {
83
+ if (task.status.type === "pending") {
84
+ try {
85
+ this.logger.debug(`Starting execution of task ${task.taskId} from queue`);
86
+ await task.run();
87
+ } catch (error) {
88
+ this.logger.error(`Error executing task ${task.taskId} from queue: ${error.message}`);
89
+ }
90
+ }
91
+ };
92
+ this.queue.add(taskHandler);
93
+ }
94
+ pauseQueue() {
95
+ this.logger.info("Pausing task queue");
96
+ this.queue.pause();
97
+ this.emit("queuePaused");
98
+ }
99
+ resumeQueue() {
100
+ this.logger.info("Resuming task queue");
101
+ this.queue.start();
102
+ this.emit("queueResumed");
54
103
  }
55
104
  async cancelTask(taskId) {
56
105
  const task = this.tasks.get(taskId);
@@ -59,6 +108,10 @@ class BaseTaskManager extends import_events.EventEmitter {
59
108
  return false;
60
109
  }
61
110
  this.logger.info(`Cancelling task ${taskId}, type: ${task.constructor.name}, tags: ${JSON.stringify(task.tags)}`);
111
+ if (task.status.type === "pending") {
112
+ await task.statusChange({ type: "cancelled" });
113
+ return true;
114
+ }
62
115
  return task.cancel();
63
116
  }
64
117
  createTask(options) {
@@ -96,8 +149,19 @@ class BaseTaskManager extends import_events.EventEmitter {
96
149
  }
97
150
  this.emit("taskStatusChange", { task, status });
98
151
  });
152
+ if (options.immediateExecute !== false) {
153
+ this.enqueueTask(task);
154
+ }
99
155
  return task;
100
156
  }
157
+ runTask(taskId) {
158
+ const task = this.tasks.get(taskId);
159
+ if (task) {
160
+ this.enqueueTask(task);
161
+ } else {
162
+ this.logger.warn(`Attempted to enqueue non-existent task ${taskId}`);
163
+ }
164
+ }
101
165
  getTask(taskId) {
102
166
  const task = this.tasks.get(taskId);
103
167
  if (!task) {
@@ -1,3 +1,11 @@
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
+ */
1
9
  /// <reference types="node" />
2
10
  import { Logger } from '@nocobase/logger';
3
11
  import { ITask, TaskConstructor } from './task';
@@ -14,6 +22,7 @@ export interface CreateTaskOptions {
14
22
  dataSource: string;
15
23
  };
16
24
  context?: any;
25
+ immediateExecute: boolean;
17
26
  }
18
27
  export type TaskId = string;
19
28
  export type TaskStatus = PendingStatus | SuccessStatus<any> | RunningStatus | FailedStatus | CancelledStatus;
@@ -44,6 +53,7 @@ export interface CancelledStatus {
44
53
  type: 'cancelled';
45
54
  }
46
55
  export interface AsyncTasksManager extends EventEmitter {
56
+ queue: any;
47
57
  setLogger(logger: Logger): void;
48
58
  setApp(app: Application): void;
49
59
  registerTaskType(taskType: TaskConstructor): void;
@@ -52,6 +62,7 @@ export interface AsyncTasksManager extends EventEmitter {
52
62
  cancelTask(taskId: TaskId): Promise<boolean>;
53
63
  getTaskStatus(taskId: TaskId): Promise<TaskStatus>;
54
64
  getTask(taskId: TaskId): ITask | undefined;
65
+ runTask(taskId: TaskId): void;
55
66
  }
56
67
  export declare class CancelError extends Error {
57
68
  constructor(message?: string);
@@ -1,3 +1,11 @@
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
+ */
1
9
  /// <reference types="node" />
2
10
  import { Logger } from '@nocobase/logger';
3
11
  import { TaskStatus } from './async-task-manager';
@@ -21,6 +29,7 @@ export interface ITask extends EventEmitter {
21
29
  setApp(app: Application): void;
22
30
  setContext(context: any): void;
23
31
  cancel(): Promise<boolean>;
32
+ statusChange: (status: TaskStatus) => Promise<void>;
24
33
  execute(): Promise<any>;
25
34
  reportProgress(progress: {
26
35
  total: number;
@@ -1,3 +1,11 @@
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
+ */
1
9
  import { Plugin } from '@nocobase/server';
2
10
  export declare class PluginAsyncExportServer extends Plugin {
3
11
  private progressThrottles;
@@ -41,10 +41,10 @@ __export(plugin_exports, {
41
41
  });
42
42
  module.exports = __toCommonJS(plugin_exports);
43
43
  var import_server = require("@nocobase/server");
44
+ var import_lodash = require("lodash");
44
45
  var import_base_task_manager = require("./base-task-manager");
45
46
  var import_command_task_type = require("./command-task-type");
46
47
  var import_async_tasks = __toESM(require("./resourcers/async-tasks"));
47
- var import_lodash = require("lodash");
48
48
  class PluginAsyncExportServer extends import_server.Plugin {
49
49
  progressThrottles = /* @__PURE__ */ new Map();
50
50
  async afterAdd() {
@@ -57,7 +57,7 @@ class PluginAsyncExportServer extends import_server.Plugin {
57
57
  return manager;
58
58
  });
59
59
  this.app.container.get("AsyncTaskManager").registerTaskType(import_command_task_type.CommandTaskType);
60
- this.app.acl.allow("asyncTasks", ["get", "fetchFile"], "loggedIn");
60
+ this.app.acl.allow("asyncTasks", ["list", "get", "fetchFile", "cancel"], "loggedIn");
61
61
  }
62
62
  getThrottledProgressEmitter(taskId, userId) {
63
63
  if (!this.progressThrottles.has(taskId)) {
@@ -1,7 +1,17 @@
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
+ */
1
9
  declare const _default: {
2
10
  name: string;
3
11
  actions: {
12
+ list(ctx: any, next: any): Promise<void>;
4
13
  get(ctx: any, next: any): Promise<void>;
14
+ cancel(ctx: any, next: any): Promise<void>;
5
15
  fetchFile(ctx: any, next: any): Promise<void>;
6
16
  };
7
17
  };
@@ -40,10 +40,18 @@ __export(async_tasks_exports, {
40
40
  });
41
41
  module.exports = __toCommonJS(async_tasks_exports);
42
42
  var import_fs = __toESM(require("fs"));
43
+ var import_lodash = __toESM(require("lodash"));
43
44
  var import_path = require("path");
44
45
  var async_tasks_default = {
45
46
  name: "asyncTasks",
46
47
  actions: {
48
+ async list(ctx, next) {
49
+ const userId = ctx.auth.user.id;
50
+ const asyncTaskManager = ctx.app.container.get("AsyncTaskManager");
51
+ const tasks = await asyncTaskManager.getTasksByTag("userId", userId);
52
+ ctx.body = import_lodash.default.orderBy(tasks, "createdAt", "desc");
53
+ await next();
54
+ },
47
55
  async get(ctx, next) {
48
56
  const { filterByTk } = ctx.action.params;
49
57
  const taskManager = ctx.app.container.get("AsyncTaskManager");
@@ -51,8 +59,25 @@ var async_tasks_default = {
51
59
  ctx.body = taskStatus;
52
60
  await next();
53
61
  },
54
- async fetchFile(ctx, next) {
62
+ async cancel(ctx, next) {
55
63
  const { filterByTk } = ctx.action.params;
64
+ const userId = ctx.auth.user.id;
65
+ const asyncTaskManager = ctx.app.container.get("AsyncTaskManager");
66
+ const task = asyncTaskManager.getTask(filterByTk);
67
+ if (!task) {
68
+ ctx.body = "ok";
69
+ await next();
70
+ return;
71
+ }
72
+ if (task.tags["userId"] != userId) {
73
+ ctx.throw(403);
74
+ }
75
+ const cancelled = await asyncTaskManager.cancelTask(filterByTk);
76
+ ctx.body = cancelled;
77
+ await next();
78
+ },
79
+ async fetchFile(ctx, next) {
80
+ const { filterByTk, filename } = ctx.action.params;
56
81
  const taskManager = ctx.app.container.get("AsyncTaskManager");
57
82
  const taskStatus = await taskManager.getTaskStatus(filterByTk);
58
83
  if (taskStatus.type !== "success") {
@@ -63,9 +88,11 @@ var async_tasks_default = {
63
88
  throw new Error("not a file task");
64
89
  }
65
90
  ctx.body = import_fs.default.createReadStream(filePath);
91
+ let finalFileName = filename ? filename : (0, import_path.basename)(filePath);
92
+ finalFileName = encodeURIComponent(finalFileName);
66
93
  ctx.set({
67
94
  "Content-Type": "application/octet-stream",
68
- "Content-Disposition": `attachment; filename=${(0, import_path.basename)(filePath)}`
95
+ "Content-Disposition": `attachment; filename=${finalFileName}`
69
96
  });
70
97
  await next();
71
98
  }
@@ -1,3 +1,11 @@
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
+ */
1
9
  /// <reference types="node" />
2
10
  import EventEmitter from 'events';
3
11
  import { Logger } from '@nocobase/logger';
@@ -33,6 +41,7 @@ export declare abstract class TaskType extends EventEmitter implements ITask {
33
41
  * Cancel the task
34
42
  */
35
43
  cancel(): Promise<boolean>;
44
+ statusChange(status: TaskStatus): Promise<void>;
36
45
  /**
37
46
  * Execute the task implementation
38
47
  * @returns Promise that resolves with the task result
@@ -44,6 +44,7 @@ var import_events = __toESM(require("events"));
44
44
  var import_async_task_manager = require("./interfaces/async-task-manager");
45
45
  class TaskType extends import_events.default {
46
46
  constructor(options, tags) {
47
+ var _a;
47
48
  super();
48
49
  this.options = options;
49
50
  this.status = {
@@ -53,6 +54,7 @@ class TaskType extends import_events.default {
53
54
  this.taskId = (0, import_uuid.v4)();
54
55
  this.tags = tags || {};
55
56
  this.createdAt = /* @__PURE__ */ new Date();
57
+ (_a = this.options.argv) == null ? void 0 : _a.push(`--taskId=${this.taskId}`);
56
58
  }
57
59
  static type;
58
60
  static cancelable = true;
@@ -94,6 +96,10 @@ class TaskType extends import_events.default {
94
96
  (_a = this.logger) == null ? void 0 : _a.debug(`Task ${this.taskId} cancelled`);
95
97
  return true;
96
98
  }
99
+ async statusChange(status) {
100
+ this.status = status;
101
+ this.emit("statusChange", this.status);
102
+ }
97
103
  /**
98
104
  * Report task progress
99
105
  * @param progress Progress information containing total and current values
@@ -141,10 +147,9 @@ class TaskType extends import_events.default {
141
147
  this.emit("statusChange", this.status);
142
148
  } catch (error) {
143
149
  if (error instanceof import_async_task_manager.CancelError) {
144
- this.status = {
145
- type: "cancelled"
146
- };
150
+ this.statusChange({ type: "cancelled" });
147
151
  (_d = this.logger) == null ? void 0 : _d.info(`Task ${this.taskId} was cancelled during execution`);
152
+ return;
148
153
  } else {
149
154
  this.status = {
150
155
  type: "failed",
@@ -152,8 +157,8 @@ class TaskType extends import_events.default {
152
157
  errors: [{ message: this.renderErrorMessage(error) }]
153
158
  };
154
159
  (_e = this.logger) == null ? void 0 : _e.error(`Task ${this.taskId} failed with error: ${error.message}`);
160
+ this.emit("statusChange", this.status);
155
161
  }
156
- this.emit("statusChange", this.status);
157
162
  } finally {
158
163
  this.fulfilledAt = /* @__PURE__ */ new Date();
159
164
  const duration = this.fulfilledAt.getTime() - this.startedAt.getTime();
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "异步任务管理器",
5
5
  "description": "Manage and monitor asynchronous tasks such as data import/export. Support task progress tracking and notification.",
6
6
  "description.zh-CN": "管理和监控数据导入导出等异步任务。支持任务进度跟踪和通知。",
7
- "version": "1.7.0-beta.9",
7
+ "version": "1.8.0-beta.1",
8
8
  "main": "dist/server/index.js",
9
9
  "peerDependencies": {
10
10
  "@nocobase/client": "1.x",
@@ -12,5 +12,8 @@
12
12
  "@nocobase/server": "1.x",
13
13
  "@nocobase/test": "1.x"
14
14
  },
15
- "gitHead": "7013a5080f3695d7750ab21005c90d2172c16480"
15
+ "dependencies": {
16
+ "p-queue": "^6.6.2"
17
+ },
18
+ "gitHead": "103935669123174f2942247202e3d9ff15f0d4ed"
16
19
  }
@@ -1,5 +0,0 @@
1
- Robert Kieffer <robert@broofa.com>
2
- Christoph Tavan <dev@tavan.de>
3
- AJ ONeal <coolaj86@gmail.com>
4
- Vincent Voyer <vincent@zeroload.net>
5
- Roman Shtylman <shtylman@gmail.com>
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env node
2
- var assert = require('assert');
3
-
4
- function usage() {
5
- console.log('Usage:');
6
- console.log(' uuid');
7
- console.log(' uuid v1');
8
- console.log(' uuid v3 <name> <namespace uuid>');
9
- console.log(' uuid v4');
10
- console.log(' uuid v5 <name> <namespace uuid>');
11
- console.log(' uuid --help');
12
- console.log('\nNote: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC4122');
13
- }
14
-
15
- var args = process.argv.slice(2);
16
-
17
- if (args.indexOf('--help') >= 0) {
18
- usage();
19
- process.exit(0);
20
- }
21
- var version = args.shift() || 'v4';
22
-
23
- switch (version) {
24
- case 'v1':
25
- var uuidV1 = require('../v1');
26
- console.log(uuidV1());
27
- break;
28
-
29
- case 'v3':
30
- var uuidV3 = require('../v3');
31
-
32
- var name = args.shift();
33
- var namespace = args.shift();
34
- assert(name != null, 'v3 name not specified');
35
- assert(namespace != null, 'v3 namespace not specified');
36
-
37
- if (namespace == 'URL') namespace = uuidV3.URL;
38
- if (namespace == 'DNS') namespace = uuidV3.DNS;
39
-
40
- console.log(uuidV3(name, namespace));
41
- break;
42
-
43
- case 'v4':
44
- var uuidV4 = require('../v4');
45
- console.log(uuidV4());
46
- break;
47
-
48
- case 'v5':
49
- var uuidV5 = require('../v5');
50
-
51
- var name = args.shift();
52
- var namespace = args.shift();
53
- assert(name != null, 'v5 name not specified');
54
- assert(namespace != null, 'v5 namespace not specified');
55
-
56
- if (namespace == 'URL') namespace = uuidV5.URL;
57
- if (namespace == 'DNS') namespace = uuidV5.DNS;
58
-
59
- console.log(uuidV5(name, namespace));
60
- break;
61
-
62
- default:
63
- usage();
64
- process.exit(1);
65
- }
@@ -1 +0,0 @@
1
- (function(){var r={155:function(r,e,n){var a=n(749);var t=n(824);var i=t;i.v1=a;i.v4=t;r.exports=i},707:function(r){var e=[];for(var n=0;n<256;++n){e[n]=(n+256).toString(16).substr(1)}function bytesToUuid(r,n){var a=n||0;var t=e;return[t[r[a++]],t[r[a++]],t[r[a++]],t[r[a++]],"-",t[r[a++]],t[r[a++]],"-",t[r[a++]],t[r[a++]],"-",t[r[a++]],t[r[a++]],"-",t[r[a++]],t[r[a++]],t[r[a++]],t[r[a++]],t[r[a++]],t[r[a++]]].join("")}r.exports=bytesToUuid},859:function(r,e,n){var a=n(113);r.exports=function nodeRNG(){return a.randomBytes(16)}},749:function(r,e,n){var a=n(859);var t=n(707);var i;var u;var o=0;var v=0;function v1(r,e,n){var f=e&&n||0;var s=e||[];r=r||{};var c=r.node||i;var _=r.clockseq!==undefined?r.clockseq:u;if(c==null||_==null){var d=a();if(c==null){c=i=[d[0]|1,d[1],d[2],d[3],d[4],d[5]]}if(_==null){_=u=(d[6]<<8|d[7])&16383}}var l=r.msecs!==undefined?r.msecs:(new Date).getTime();var p=r.nsecs!==undefined?r.nsecs:v+1;var x=l-o+(p-v)/1e4;if(x<0&&r.clockseq===undefined){_=_+1&16383}if((x<0||l>o)&&r.nsecs===undefined){p=0}if(p>=1e4){throw new Error("uuid.v1(): Can't create more than 10M uuids/sec")}o=l;v=p;u=_;l+=122192928e5;var b=((l&268435455)*1e4+p)%4294967296;s[f++]=b>>>24&255;s[f++]=b>>>16&255;s[f++]=b>>>8&255;s[f++]=b&255;var y=l/4294967296*1e4&268435455;s[f++]=y>>>8&255;s[f++]=y&255;s[f++]=y>>>24&15|16;s[f++]=y>>>16&255;s[f++]=_>>>8|128;s[f++]=_&255;for(var q=0;q<6;++q){s[f+q]=c[q]}return e?e:t(s)}r.exports=v1},824:function(r,e,n){var a=n(859);var t=n(707);function v4(r,e,n){var i=e&&n||0;if(typeof r=="string"){e=r==="binary"?new Array(16):null;r=null}r=r||{};var u=r.random||(r.rng||a)();u[6]=u[6]&15|64;u[8]=u[8]&63|128;if(e){for(var o=0;o<16;++o){e[i+o]=u[o]}}return e||t(u)}r.exports=v4},113:function(r){"use strict";r.exports=require("crypto")}};var e={};function __nccwpck_require__(n){var a=e[n];if(a!==undefined){return a.exports}var t=e[n]={exports:{}};var i=true;try{r[n](t,t.exports,__nccwpck_require__);i=false}finally{if(i)delete e[n]}return t.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var n=__nccwpck_require__(155);module.exports=n})();
@@ -1,26 +0,0 @@
1
- /**
2
- * Convert array of 16 byte values to UUID string format of the form:
3
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
4
- */
5
- var byteToHex = [];
6
- for (var i = 0; i < 256; ++i) {
7
- byteToHex[i] = (i + 0x100).toString(16).substr(1);
8
- }
9
-
10
- function bytesToUuid(buf, offset) {
11
- var i = offset || 0;
12
- var bth = byteToHex;
13
- // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
14
- return ([
15
- bth[buf[i++]], bth[buf[i++]],
16
- bth[buf[i++]], bth[buf[i++]], '-',
17
- bth[buf[i++]], bth[buf[i++]], '-',
18
- bth[buf[i++]], bth[buf[i++]], '-',
19
- bth[buf[i++]], bth[buf[i++]], '-',
20
- bth[buf[i++]], bth[buf[i++]],
21
- bth[buf[i++]], bth[buf[i++]],
22
- bth[buf[i++]], bth[buf[i++]]
23
- ]).join('');
24
- }
25
-
26
- module.exports = bytesToUuid;
@@ -1,25 +0,0 @@
1
- 'use strict';
2
-
3
- var crypto = require('crypto');
4
-
5
- function md5(bytes) {
6
- if (typeof Buffer.from === 'function') {
7
- // Modern Buffer API
8
- if (Array.isArray(bytes)) {
9
- bytes = Buffer.from(bytes);
10
- } else if (typeof bytes === 'string') {
11
- bytes = Buffer.from(bytes, 'utf8');
12
- }
13
- } else {
14
- // Pre-v4 Buffer API
15
- if (Array.isArray(bytes)) {
16
- bytes = new Buffer(bytes);
17
- } else if (typeof bytes === 'string') {
18
- bytes = new Buffer(bytes, 'utf8');
19
- }
20
- }
21
-
22
- return crypto.createHash('md5').update(bytes).digest();
23
- }
24
-
25
- module.exports = md5;
@@ -1,34 +0,0 @@
1
- // Unique ID creation requires a high quality random # generator. In the
2
- // browser this is a little complicated due to unknown quality of Math.random()
3
- // and inconsistent support for the `crypto` API. We do the best we can via
4
- // feature-detection
5
-
6
- // getRandomValues needs to be invoked in a context where "this" is a Crypto
7
- // implementation. Also, find the complete implementation of crypto on IE11.
8
- var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
9
- (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
10
-
11
- if (getRandomValues) {
12
- // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
13
- var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
14
-
15
- module.exports = function whatwgRNG() {
16
- getRandomValues(rnds8);
17
- return rnds8;
18
- };
19
- } else {
20
- // Math.random()-based (RNG)
21
- //
22
- // If all else fails, use Math.random(). It's fast, but is of unspecified
23
- // quality.
24
- var rnds = new Array(16);
25
-
26
- module.exports = function mathRNG() {
27
- for (var i = 0, r; i < 16; i++) {
28
- if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
29
- rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
30
- }
31
-
32
- return rnds;
33
- };
34
- }
@@ -1,8 +0,0 @@
1
- // Unique ID creation requires a high quality random # generator. In node.js
2
- // this is pretty straight-forward - we use the crypto API.
3
-
4
- var crypto = require('crypto');
5
-
6
- module.exports = function nodeRNG() {
7
- return crypto.randomBytes(16);
8
- };