@eggjs/schedule 5.0.2 → 6.0.0-beta.15
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/README.md +6 -12
- package/dist/agent.d.ts +13 -0
- package/dist/agent.js +32 -0
- package/dist/app/extend/agent.d.ts +22 -0
- package/dist/app/extend/agent.js +32 -0
- package/dist/app/extend/application.d.ts +16 -0
- package/dist/app/extend/application.js +18 -0
- package/dist/app/extend/application.unittest.d.ts +13 -0
- package/dist/app/extend/application.unittest.js +46 -0
- package/dist/app.d.ts +11 -0
- package/dist/app.js +69 -0
- package/dist/config/config.default.d.ts +6 -0
- package/dist/config/config.default.js +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/lib/load_schedule.d.ts +7 -0
- package/dist/lib/load_schedule.js +61 -0
- package/dist/lib/schedule.d.ts +35 -0
- package/dist/lib/schedule.js +77 -0
- package/dist/lib/schedule_worker.d.ts +14 -0
- package/dist/lib/schedule_worker.js +22 -0
- package/dist/lib/strategy/all.d.ts +8 -0
- package/dist/lib/strategy/all.js +11 -0
- package/dist/lib/strategy/base.d.ts +35 -0
- package/dist/lib/strategy/base.js +73 -0
- package/dist/lib/strategy/timer.d.ts +24 -0
- package/dist/lib/strategy/timer.js +71 -0
- package/dist/lib/strategy/worker.d.ts +8 -0
- package/dist/lib/strategy/worker.js +11 -0
- package/dist/lib/types.d.ts +44 -0
- package/dist/lib/types.js +1 -0
- package/package.json +51 -55
- package/dist/commonjs/agent.d.ts +0 -7
- package/dist/commonjs/agent.js +0 -32
- package/dist/commonjs/app/extend/agent.d.ts +0 -2
- package/dist/commonjs/app/extend/agent.js +0 -29
- package/dist/commonjs/app/extend/application.d.ts +0 -2
- package/dist/commonjs/app/extend/application.js +0 -16
- package/dist/commonjs/app/extend/application.unittest.d.ts +0 -2
- package/dist/commonjs/app/extend/application.unittest.js +0 -58
- package/dist/commonjs/app.d.ts +0 -6
- package/dist/commonjs/app.js +0 -80
- package/dist/commonjs/config/config.default.d.ts +0 -2
- package/dist/commonjs/config/config.default.js +0 -17
- package/dist/commonjs/index.d.ts +0 -1
- package/dist/commonjs/index.js +0 -18
- package/dist/commonjs/lib/load_schedule.d.ts +0 -3
- package/dist/commonjs/lib/load_schedule.js +0 -71
- package/dist/commonjs/lib/schedule.d.ts +0 -31
- package/dist/commonjs/lib/schedule.js +0 -89
- package/dist/commonjs/lib/schedule_worker.d.ts +0 -10
- package/dist/commonjs/lib/schedule_worker.js +0 -22
- package/dist/commonjs/lib/strategy/all.d.ts +0 -4
- package/dist/commonjs/lib/strategy/all.js +0 -11
- package/dist/commonjs/lib/strategy/base.d.ts +0 -30
- package/dist/commonjs/lib/strategy/base.js +0 -79
- package/dist/commonjs/lib/strategy/timer.d.ts +0 -20
- package/dist/commonjs/lib/strategy/timer.js +0 -99
- package/dist/commonjs/lib/strategy/worker.d.ts +0 -4
- package/dist/commonjs/lib/strategy/worker.js +0 -11
- package/dist/commonjs/lib/types.d.ts +0 -53
- package/dist/commonjs/lib/types.js +0 -3
- package/dist/commonjs/package.json +0 -3
- package/dist/esm/agent.d.ts +0 -7
- package/dist/esm/agent.js +0 -29
- package/dist/esm/app/extend/agent.d.ts +0 -2
- package/dist/esm/app/extend/agent.js +0 -27
- package/dist/esm/app/extend/application.d.ts +0 -2
- package/dist/esm/app/extend/application.js +0 -14
- package/dist/esm/app/extend/application.unittest.d.ts +0 -2
- package/dist/esm/app/extend/application.unittest.js +0 -53
- package/dist/esm/app.d.ts +0 -6
- package/dist/esm/app.js +0 -77
- package/dist/esm/config/config.default.d.ts +0 -2
- package/dist/esm/config/config.default.js +0 -15
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/lib/load_schedule.d.ts +0 -3
- package/dist/esm/lib/load_schedule.js +0 -65
- package/dist/esm/lib/schedule.d.ts +0 -31
- package/dist/esm/lib/schedule.js +0 -85
- package/dist/esm/lib/schedule_worker.d.ts +0 -10
- package/dist/esm/lib/schedule_worker.js +0 -18
- package/dist/esm/lib/strategy/all.d.ts +0 -4
- package/dist/esm/lib/strategy/all.js +0 -7
- package/dist/esm/lib/strategy/base.d.ts +0 -30
- package/dist/esm/lib/strategy/base.js +0 -75
- package/dist/esm/lib/strategy/timer.d.ts +0 -20
- package/dist/esm/lib/strategy/timer.js +0 -92
- package/dist/esm/lib/strategy/worker.d.ts +0 -4
- package/dist/esm/lib/strategy/worker.js +0 -7
- package/dist/esm/lib/types.d.ts +0 -53
- package/dist/esm/lib/types.js +0 -2
- package/dist/esm/package.json +0 -3
- package/dist/package.json +0 -4
- package/src/agent.ts +0 -36
- package/src/app/extend/agent.ts +0 -30
- package/src/app/extend/application.ts +0 -16
- package/src/app/extend/application.unittest.ts +0 -57
- package/src/app.ts +0 -92
- package/src/config/config.default.ts +0 -17
- package/src/index.ts +0 -1
- package/src/lib/load_schedule.ts +0 -74
- package/src/lib/schedule.ts +0 -100
- package/src/lib/schedule_worker.ts +0 -24
- package/src/lib/strategy/all.ts +0 -7
- package/src/lib/strategy/base.ts +0 -91
- package/src/lib/strategy/timer.ts +0 -107
- package/src/lib/strategy/worker.ts +0 -7
- package/src/lib/types.ts +0 -58
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//#region src/lib/strategy/base.ts
|
|
2
|
+
var BaseStrategy = class {
|
|
3
|
+
agent;
|
|
4
|
+
scheduleConfig;
|
|
5
|
+
key;
|
|
6
|
+
logger;
|
|
7
|
+
closed = false;
|
|
8
|
+
count = 0;
|
|
9
|
+
constructor(scheduleConfig, agent, key) {
|
|
10
|
+
this.agent = agent;
|
|
11
|
+
this.key = key;
|
|
12
|
+
this.scheduleConfig = scheduleConfig;
|
|
13
|
+
this.logger = this.agent.getLogger("scheduleLogger");
|
|
14
|
+
}
|
|
15
|
+
/** keep compatibility */
|
|
16
|
+
get schedule() {
|
|
17
|
+
return this.scheduleConfig;
|
|
18
|
+
}
|
|
19
|
+
async start() {}
|
|
20
|
+
async close() {
|
|
21
|
+
this.closed = true;
|
|
22
|
+
}
|
|
23
|
+
onJobStart(_info) {}
|
|
24
|
+
onJobFinish(_info) {}
|
|
25
|
+
/**
|
|
26
|
+
* trigger one worker
|
|
27
|
+
*
|
|
28
|
+
* @param {...any} args - pass to job task
|
|
29
|
+
*/
|
|
30
|
+
sendOne(...args) {
|
|
31
|
+
/* istanbul ignore next */
|
|
32
|
+
if (this.agent.schedule.closed) {
|
|
33
|
+
this.logger.warn(`${this.key} skip due to schedule closed`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.count++;
|
|
37
|
+
const info = {
|
|
38
|
+
key: this.key,
|
|
39
|
+
id: this.getSeqId(),
|
|
40
|
+
args
|
|
41
|
+
};
|
|
42
|
+
this.logger.info(`[Job#${info.id}] ${info.key} triggered, send random by agent`);
|
|
43
|
+
this.agent.messenger.sendRandom("egg-schedule", info);
|
|
44
|
+
this.onJobStart(info);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* trigger all worker
|
|
48
|
+
*
|
|
49
|
+
* @param {...any} args - pass to job task
|
|
50
|
+
*/
|
|
51
|
+
sendAll(...args) {
|
|
52
|
+
/* istanbul ignore next */
|
|
53
|
+
if (this.agent.schedule.closed) {
|
|
54
|
+
this.logger.warn(`${this.key} skip due to schedule closed`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.count++;
|
|
58
|
+
const info = {
|
|
59
|
+
key: this.key,
|
|
60
|
+
id: this.getSeqId(),
|
|
61
|
+
args
|
|
62
|
+
};
|
|
63
|
+
this.logger.info(`[Job#${info.id}] ${info.key} triggered, send all by agent`);
|
|
64
|
+
this.agent.messenger.send("egg-schedule", info);
|
|
65
|
+
this.onJobStart(info);
|
|
66
|
+
}
|
|
67
|
+
getSeqId() {
|
|
68
|
+
return `${Date.now()}${process.hrtime().join("")}${this.count}`;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { BaseStrategy };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EggScheduleConfig } from "../types.js";
|
|
2
|
+
import { BaseStrategy } from "./base.js";
|
|
3
|
+
import Agent from "../../app/extend/agent.js";
|
|
4
|
+
import { CronExpression } from "cron-parser";
|
|
5
|
+
import safeTimers from "safe-timers";
|
|
6
|
+
|
|
7
|
+
//#region src/lib/strategy/timer.d.ts
|
|
8
|
+
declare abstract class TimerStrategy extends BaseStrategy {
|
|
9
|
+
#private;
|
|
10
|
+
protected cronInstance?: CronExpression;
|
|
11
|
+
constructor(scheduleConfig: EggScheduleConfig, agent: Agent, key: string);
|
|
12
|
+
protected handler(): void;
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
onJobStart(): void;
|
|
15
|
+
/**
|
|
16
|
+
* calculate next tick
|
|
17
|
+
*
|
|
18
|
+
* @return {Number|undefined} time interval, if out of range then return `undefined`
|
|
19
|
+
*/
|
|
20
|
+
protected getNextTick(): number | undefined;
|
|
21
|
+
protected safeTimeout(handler: () => void, delay: number, ...args: any[]): number | safeTimers.Timeout;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { TimerStrategy };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { BaseStrategy } from "./base.js";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import cronParser from "cron-parser";
|
|
4
|
+
import { ms } from "humanize-ms";
|
|
5
|
+
import safeTimers from "safe-timers";
|
|
6
|
+
import { logDate } from "utility";
|
|
7
|
+
|
|
8
|
+
//#region src/lib/strategy/timer.ts
|
|
9
|
+
var TimerStrategy = class extends BaseStrategy {
|
|
10
|
+
cronInstance;
|
|
11
|
+
constructor(scheduleConfig, agent, key) {
|
|
12
|
+
super(scheduleConfig, agent, key);
|
|
13
|
+
const { interval, cron, cronOptions, immediate } = this.scheduleConfig;
|
|
14
|
+
assert(interval || cron || immediate, `[@eggjs/schedule] ${this.key} \`schedule.interval\` or \`schedule.cron\` or \`schedule.immediate\` must be present`);
|
|
15
|
+
if (cron) try {
|
|
16
|
+
this.cronInstance = cronParser.parseExpression(cron, cronOptions);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
throw new TypeError(`[@eggjs/schedule] ${this.key} parse cron instruction(${cron}) error: ${err.message}`, { cause: err });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
handler() {
|
|
22
|
+
throw new TypeError(`[@eggjs/schedule] ${this.key} strategy should override \`handler()\` method`);
|
|
23
|
+
}
|
|
24
|
+
async start() {
|
|
25
|
+
/* istanbul ignore next */
|
|
26
|
+
if (this.agent.schedule.closed) return;
|
|
27
|
+
if (this.scheduleConfig.immediate) {
|
|
28
|
+
this.logger.info(`[Timer] ${this.key} next time will execute immediate`);
|
|
29
|
+
setImmediate(() => this.handler());
|
|
30
|
+
} else this.#scheduleNext();
|
|
31
|
+
}
|
|
32
|
+
#scheduleNext() {
|
|
33
|
+
/* istanbul ignore next */
|
|
34
|
+
if (this.agent.schedule.closed) return;
|
|
35
|
+
const nextTick = this.getNextTick();
|
|
36
|
+
if (nextTick) {
|
|
37
|
+
this.logger.info(`[Timer] ${this.key} next time will execute after ${nextTick}ms at ${logDate(new Date(Date.now() + nextTick))}`);
|
|
38
|
+
this.safeTimeout(() => this.handler(), nextTick);
|
|
39
|
+
} else this.logger.info(`[Timer] ${this.key} reach endDate, will stop`);
|
|
40
|
+
}
|
|
41
|
+
onJobStart() {
|
|
42
|
+
this.#scheduleNext();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* calculate next tick
|
|
46
|
+
*
|
|
47
|
+
* @return {Number|undefined} time interval, if out of range then return `undefined`
|
|
48
|
+
*/
|
|
49
|
+
getNextTick() {
|
|
50
|
+
if (this.scheduleConfig.interval) return ms(this.scheduleConfig.interval);
|
|
51
|
+
if (this.cronInstance) {
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
let nextTick;
|
|
54
|
+
do
|
|
55
|
+
try {
|
|
56
|
+
nextTick = this.cronInstance.next().getTime();
|
|
57
|
+
} catch (err) {
|
|
58
|
+
this.logger.info(`[Timer] ${this.key} cron out of the timespan range, error: %s`, err);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
while (now >= nextTick);
|
|
62
|
+
return nextTick - now;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
safeTimeout(handler, delay, ...args) {
|
|
66
|
+
return (delay < safeTimers.maxInterval ? setTimeout : safeTimers.setTimeout)(handler, delay, ...args);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { TimerStrategy };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ParserOptions } from "cron-parser";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/types.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Schedule Config
|
|
7
|
+
* @see https://www.eggjs.org/zh-CN/basics/schedule
|
|
8
|
+
*/
|
|
9
|
+
interface EggScheduleConfig {
|
|
10
|
+
type?: 'worker' | 'all';
|
|
11
|
+
interval?: string | number;
|
|
12
|
+
cron?: string;
|
|
13
|
+
cronOptions?: ParserOptions;
|
|
14
|
+
immediate?: boolean;
|
|
15
|
+
disable?: boolean;
|
|
16
|
+
env?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* custom additional directory, full path
|
|
19
|
+
*/
|
|
20
|
+
directory: string[];
|
|
21
|
+
}
|
|
22
|
+
type EggScheduleTask = (ctx: any, ...args: any[]) => Promise<void>;
|
|
23
|
+
interface EggScheduleItem {
|
|
24
|
+
schedule: EggScheduleConfig;
|
|
25
|
+
scheduleQueryString: string;
|
|
26
|
+
task: EggScheduleTask;
|
|
27
|
+
key: string;
|
|
28
|
+
}
|
|
29
|
+
interface EggScheduleJobInfo {
|
|
30
|
+
id: string;
|
|
31
|
+
key: string;
|
|
32
|
+
workerId: number;
|
|
33
|
+
args: any[];
|
|
34
|
+
success?: boolean;
|
|
35
|
+
message?: string;
|
|
36
|
+
rt?: number;
|
|
37
|
+
}
|
|
38
|
+
declare module 'egg' {
|
|
39
|
+
interface EggAppConfig {
|
|
40
|
+
schedule: EggScheduleConfig;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { EggScheduleConfig, EggScheduleItem, EggScheduleJobInfo, EggScheduleTask };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/package.json
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/schedule",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-beta.15",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=18.
|
|
8
|
+
"node": ">=22.18.0"
|
|
9
9
|
},
|
|
10
10
|
"description": "schedule plugin for egg, support corn job.",
|
|
11
11
|
"eggPlugin": {
|
|
12
|
-
"name": "schedule"
|
|
13
|
-
"exports": {
|
|
14
|
-
"import": "./dist/esm",
|
|
15
|
-
"require": "./dist/commonjs"
|
|
16
|
-
}
|
|
12
|
+
"name": "schedule"
|
|
17
13
|
},
|
|
18
14
|
"repository": {
|
|
19
15
|
"type": "git",
|
|
20
|
-
"url": "
|
|
16
|
+
"url": "https://github.com/eggjs/egg.git",
|
|
17
|
+
"directory": "plugins/schedule"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/eggjs/egg/tree/next/plugins/schedule",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/eggjs/egg/issues"
|
|
21
22
|
},
|
|
22
23
|
"keywords": [
|
|
23
24
|
"egg",
|
|
@@ -27,65 +28,60 @@
|
|
|
27
28
|
"cron"
|
|
28
29
|
],
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"@eggjs/utils": "^4.0.3",
|
|
31
31
|
"cron-parser": "^4.9.0",
|
|
32
32
|
"humanize-ms": "^2.0.0",
|
|
33
|
-
"is-type-of": "^2.
|
|
33
|
+
"is-type-of": "^2.2.0",
|
|
34
34
|
"safe-timers": "^1.1.0",
|
|
35
|
-
"utility": "^2.
|
|
35
|
+
"utility": "^2.5.0",
|
|
36
|
+
"@eggjs/utils": "5.0.0-beta.15"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"egg": "4.1.0-beta.15"
|
|
36
40
|
},
|
|
37
41
|
"devDependencies": {
|
|
38
|
-
"@arethetypeswrong/cli": "^0.17.1",
|
|
39
|
-
"@eggjs/tsconfig": "1",
|
|
40
|
-
"@types/mocha": "10",
|
|
41
|
-
"@types/node": "22",
|
|
42
42
|
"@types/safe-timers": "^1.1.2",
|
|
43
|
-
"egg": "
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"tshy-after": "1",
|
|
52
|
-
"typescript": "5"
|
|
53
|
-
},
|
|
54
|
-
"scripts": {
|
|
55
|
-
"lint": "eslint --cache src test --ext .ts",
|
|
56
|
-
"pretest": "npm run lint -- --fix && npm run prepublishOnly",
|
|
57
|
-
"test": "egg-bin test",
|
|
58
|
-
"preci": "npm run lint && npm run prepublishOnly && attw --pack",
|
|
59
|
-
"ci": "egg-bin cov",
|
|
60
|
-
"prepublishOnly": "tshy && tshy-after"
|
|
43
|
+
"egg-tracer": "^2.1.0",
|
|
44
|
+
"oxlint": "^1.18.0",
|
|
45
|
+
"tsdown": "^0.15.4",
|
|
46
|
+
"typescript": "5.9.2",
|
|
47
|
+
"vitest": "4.0.0-beta.13",
|
|
48
|
+
"@eggjs/bin": "8.0.0-beta.15",
|
|
49
|
+
"@eggjs/tsconfig": "3.1.0-beta.15",
|
|
50
|
+
"@eggjs/mock": "7.0.0-beta.15"
|
|
61
51
|
},
|
|
62
52
|
"author": "dead_horse",
|
|
63
53
|
"license": "MIT",
|
|
64
54
|
"type": "module",
|
|
65
|
-
"tshy": {
|
|
66
|
-
"exports": {
|
|
67
|
-
".": "./src/index.ts",
|
|
68
|
-
"./package.json": "./package.json"
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
55
|
"exports": {
|
|
72
|
-
".":
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
56
|
+
".": "./dist/index.js",
|
|
57
|
+
"./agent": "./dist/agent.js",
|
|
58
|
+
"./app": "./dist/app.js",
|
|
59
|
+
"./app/extend/agent": "./dist/app/extend/agent.js",
|
|
60
|
+
"./app/extend/application": "./dist/app/extend/application.js",
|
|
61
|
+
"./app/extend/application.unittest": "./dist/app/extend/application.unittest.js",
|
|
62
|
+
"./config/config.default": "./dist/config/config.default.js",
|
|
63
|
+
"./lib/load_schedule": "./dist/lib/load_schedule.js",
|
|
64
|
+
"./lib/schedule": "./dist/lib/schedule.js",
|
|
65
|
+
"./lib/schedule_worker": "./dist/lib/schedule_worker.js",
|
|
66
|
+
"./lib/strategy/all": "./dist/lib/strategy/all.js",
|
|
67
|
+
"./lib/strategy/base": "./dist/lib/strategy/base.js",
|
|
68
|
+
"./lib/strategy/timer": "./dist/lib/strategy/timer.js",
|
|
69
|
+
"./lib/strategy/worker": "./dist/lib/strategy/worker.js",
|
|
70
|
+
"./lib/types": "./dist/lib/types.js",
|
|
82
71
|
"./package.json": "./package.json"
|
|
83
72
|
},
|
|
84
73
|
"files": [
|
|
85
|
-
"dist"
|
|
86
|
-
"src"
|
|
74
|
+
"dist"
|
|
87
75
|
],
|
|
88
|
-
"types": "./dist/
|
|
89
|
-
"main": "./dist/
|
|
90
|
-
"module": "./dist/
|
|
91
|
-
|
|
76
|
+
"types": "./dist/index.d.ts",
|
|
77
|
+
"main": "./dist/index.js",
|
|
78
|
+
"module": "./dist/index.js",
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsdown",
|
|
81
|
+
"typecheck": "tsc --noEmit",
|
|
82
|
+
"lint": "oxlint --type-aware",
|
|
83
|
+
"lint:fix": "npm run lint -- --fix",
|
|
84
|
+
"test": "npm run lint:fix && vitest run",
|
|
85
|
+
"ci": "vitest run --coverage"
|
|
86
|
+
}
|
|
87
|
+
}
|
package/dist/commonjs/agent.d.ts
DELETED
package/dist/commonjs/agent.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const node_util_1 = require("node:util");
|
|
4
|
-
const worker_js_1 = require("./lib/strategy/worker.js");
|
|
5
|
-
const all_js_1 = require("./lib/strategy/all.js");
|
|
6
|
-
const debug = (0, node_util_1.debuglog)('@eggjs/schedule/agent');
|
|
7
|
-
class Boot {
|
|
8
|
-
#agent;
|
|
9
|
-
constructor(agent) {
|
|
10
|
-
this.#agent = agent;
|
|
11
|
-
}
|
|
12
|
-
async configDidLoad() {
|
|
13
|
-
// register built-in strategy
|
|
14
|
-
this.#agent.schedule.use('worker', worker_js_1.WorkerStrategy);
|
|
15
|
-
this.#agent.schedule.use('all', all_js_1.AllStrategy);
|
|
16
|
-
// wait for other plugin to register custom strategy
|
|
17
|
-
await this.#agent.schedule.init();
|
|
18
|
-
// dispatch job finish event to strategy
|
|
19
|
-
this.#agent.messenger.on('egg-schedule', (info) => {
|
|
20
|
-
// get job info from worker
|
|
21
|
-
this.#agent.schedule.onJobFinish(info);
|
|
22
|
-
});
|
|
23
|
-
debug('configDidLoad');
|
|
24
|
-
}
|
|
25
|
-
async serverDidReady() {
|
|
26
|
-
// start schedule after worker ready
|
|
27
|
-
this.#agent.schedule.start();
|
|
28
|
-
debug('serverDidReady, schedule start');
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
exports.default = Boot;
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWdlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBcUM7QUFFckMsd0RBQTBEO0FBQzFELGtEQUFvRDtBQUdwRCxNQUFNLEtBQUssR0FBRyxJQUFBLG9CQUFRLEVBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUVoRCxNQUFxQixJQUFJO0lBQ3ZCLE1BQU0sQ0FBUTtJQUNkLFlBQVksS0FBWTtRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWE7UUFDakIsNkJBQTZCO1FBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsMEJBQWMsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsb0JBQVcsQ0FBQyxDQUFDO1FBRTdDLG9EQUFvRDtRQUNwRCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBRWxDLHdDQUF3QztRQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLENBQUMsSUFBd0IsRUFBRSxFQUFFO1lBQ3BFLDJCQUEyQjtZQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELEtBQUssQ0FBQyxjQUFjO1FBQ2xCLG9DQUFvQztRQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM3QixLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUEzQkQsdUJBMkJDIn0=
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const base_js_1 = require("../../lib/strategy/base.js");
|
|
4
|
-
const timer_js_1 = require("../../lib/strategy/timer.js");
|
|
5
|
-
const schedule_js_1 = require("../../lib/schedule.js");
|
|
6
|
-
const SCHEDULE = Symbol('agent#schedule');
|
|
7
|
-
exports.default = {
|
|
8
|
-
/**
|
|
9
|
-
* @member agent#ScheduleStrategy
|
|
10
|
-
*/
|
|
11
|
-
ScheduleStrategy: base_js_1.BaseStrategy,
|
|
12
|
-
/**
|
|
13
|
-
* @member agent#TimerScheduleStrategy
|
|
14
|
-
*/
|
|
15
|
-
TimerScheduleStrategy: timer_js_1.TimerStrategy,
|
|
16
|
-
/**
|
|
17
|
-
* @member agent#schedule
|
|
18
|
-
*/
|
|
19
|
-
get schedule() {
|
|
20
|
-
if (!this[SCHEDULE]) {
|
|
21
|
-
this[SCHEDULE] = new schedule_js_1.Schedule(this);
|
|
22
|
-
this.lifecycle.registerBeforeClose(() => {
|
|
23
|
-
return this[SCHEDULE].close();
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return this[SCHEDULE];
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hZ2VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHdEQUEwRDtBQUMxRCwwREFBNEQ7QUFDNUQsdURBQWlEO0FBRWpELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBRTFDLGtCQUFlO0lBQ2I7O09BRUc7SUFDSCxnQkFBZ0IsRUFBRSxzQkFBWTtJQUU5Qjs7T0FFRztJQUNILHFCQUFxQixFQUFFLHdCQUFhO0lBRXBDOztPQUVHO0lBQ0gsSUFBSSxRQUFRO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLHNCQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3RDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hCLENBQUM7Q0FDSyxDQUFDIn0=
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const schedule_worker_js_1 = require("../../lib/schedule_worker.js");
|
|
4
|
-
const SCHEDULE_WORKER = Symbol('application#scheduleWorker');
|
|
5
|
-
exports.default = {
|
|
6
|
-
/**
|
|
7
|
-
* @member app#schedule
|
|
8
|
-
*/
|
|
9
|
-
get scheduleWorker() {
|
|
10
|
-
if (!this[SCHEDULE_WORKER]) {
|
|
11
|
-
this[SCHEDULE_WORKER] = new schedule_worker_js_1.ScheduleWorker(this);
|
|
12
|
-
}
|
|
13
|
-
return this[SCHEDULE_WORKER];
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hcHBsaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFFQUE4RDtBQUU5RCxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQztBQUU3RCxrQkFBZTtJQUNiOztPQUVHO0lBQ0gsSUFBSSxjQUFjO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsSUFBSSxtQ0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMvQixDQUFDO0NBQ0ssQ0FBQyJ9
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const node_util_1 = require("node:util");
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
const utils_1 = require("@eggjs/utils");
|
|
9
|
-
const debug = (0, node_util_1.debuglog)('@eggjs/schedule/app');
|
|
10
|
-
exports.default = {
|
|
11
|
-
async runSchedule(schedulePath, ...args) {
|
|
12
|
-
debug('[runSchedule] start schedulePath: %o, args: %o', schedulePath, args);
|
|
13
|
-
// for test purpose
|
|
14
|
-
const config = this.config;
|
|
15
|
-
const directory = [
|
|
16
|
-
node_path_1.default.join(config.baseDir, 'app/schedule'),
|
|
17
|
-
...config.schedule.directory,
|
|
18
|
-
];
|
|
19
|
-
// resolve real path
|
|
20
|
-
if (node_path_1.default.isAbsolute(schedulePath)) {
|
|
21
|
-
schedulePath = (0, utils_1.importResolve)(schedulePath);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
for (const dir of directory) {
|
|
25
|
-
const trySchedulePath = node_path_1.default.join(dir, schedulePath);
|
|
26
|
-
try {
|
|
27
|
-
schedulePath = (0, utils_1.importResolve)(trySchedulePath);
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
catch (err) {
|
|
31
|
-
debug('[runSchedule] importResolve %o error: %s', trySchedulePath, err);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
debug('[runSchedule] resolve schedulePath: %o', schedulePath);
|
|
36
|
-
const scheduleWorker = this.scheduleWorker;
|
|
37
|
-
let schedule;
|
|
38
|
-
try {
|
|
39
|
-
schedule = scheduleWorker.scheduleItems[schedulePath];
|
|
40
|
-
if (!schedule) {
|
|
41
|
-
throw new TypeError(`Cannot find schedule ${schedulePath}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
err.message = `[@eggjs/schedule] ${err.message}`;
|
|
46
|
-
throw err;
|
|
47
|
-
}
|
|
48
|
-
// run with anonymous context
|
|
49
|
-
const ctx = this.createAnonymousContext({
|
|
50
|
-
method: 'SCHEDULE',
|
|
51
|
-
url: `/__schedule?path=${schedulePath}&${schedule.scheduleQueryString}`,
|
|
52
|
-
});
|
|
53
|
-
return await this.ctxStorage.run(ctx, async () => {
|
|
54
|
-
return await schedule.task(ctx, ...args);
|
|
55
|
-
});
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24udW5pdHRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hcHBsaWNhdGlvbi51bml0dGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlDQUFxQztBQUNyQywwREFBNkI7QUFDN0Isd0NBQTZDO0FBSTdDLE1BQU0sS0FBSyxHQUFHLElBQUEsb0JBQVEsRUFBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBRTlDLGtCQUFlO0lBQ2IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFvQixFQUFFLEdBQUcsSUFBVztRQUNwRCxLQUFLLENBQUMsZ0RBQWdELEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVFLG1CQUFtQjtRQUNuQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLE1BQU0sU0FBUyxHQUFHO1lBQ2hCLG1CQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDO1lBQ3pDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTO1NBQzdCLENBQUM7UUFFRixvQkFBb0I7UUFDcEIsSUFBSSxtQkFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ2xDLFlBQVksR0FBRyxJQUFBLHFCQUFhLEVBQUMsWUFBWSxDQUFDLENBQUM7UUFDN0MsQ0FBQzthQUFNLENBQUM7WUFDTixLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUM1QixNQUFNLGVBQWUsR0FBRyxtQkFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ3JELElBQUksQ0FBQztvQkFDSCxZQUFZLEdBQUcsSUFBQSxxQkFBYSxFQUFDLGVBQWUsQ0FBQyxDQUFDO29CQUM5QyxNQUFNO2dCQUNSLENBQUM7Z0JBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztvQkFDYixLQUFLLENBQUMsMENBQTBDLEVBQUUsZUFBZSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUMxRSxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLENBQUMsd0NBQXdDLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDOUQsTUFBTSxjQUFjLEdBQW1CLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDM0QsSUFBSSxRQUF5QixDQUFDO1FBQzlCLElBQUksQ0FBQztZQUNILFFBQVEsR0FBRyxjQUFjLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxNQUFNLElBQUksU0FBUyxDQUFDLHdCQUF3QixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztZQUNsQixHQUFHLENBQUMsT0FBTyxHQUFHLHFCQUFxQixHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakQsTUFBTSxHQUFHLENBQUM7UUFDWixDQUFDO1FBRUQsNkJBQTZCO1FBQzdCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQztZQUN0QyxNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsb0JBQW9CLFlBQVksSUFBSSxRQUFRLENBQUMsbUJBQW1CLEVBQUU7U0FDeEUsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMvQyxPQUFPLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDSyxDQUFDIn0=
|
package/dist/commonjs/app.d.ts
DELETED
package/dist/commonjs/app.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const node_util_1 = require("node:util");
|
|
4
|
-
const debug = (0, node_util_1.debuglog)('@eggjs/schedule/app');
|
|
5
|
-
class Boot {
|
|
6
|
-
#app;
|
|
7
|
-
#logger;
|
|
8
|
-
constructor(app) {
|
|
9
|
-
this.#app = app;
|
|
10
|
-
this.#logger = app.getLogger('scheduleLogger');
|
|
11
|
-
}
|
|
12
|
-
async configDidLoad() {
|
|
13
|
-
const scheduleWorker = this.#app.scheduleWorker;
|
|
14
|
-
await scheduleWorker.init();
|
|
15
|
-
// log schedule list
|
|
16
|
-
for (const s in scheduleWorker.scheduleItems) {
|
|
17
|
-
const schedule = scheduleWorker.scheduleItems[s];
|
|
18
|
-
if (!schedule.schedule.disable) {
|
|
19
|
-
this.#logger.info('[@eggjs/schedule]: register schedule %s', schedule.key);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
// register schedule event
|
|
23
|
-
this.#app.messenger.on('egg-schedule', async (info) => {
|
|
24
|
-
debug('app got "egg-schedule" message: %o', info);
|
|
25
|
-
const { id, key } = info;
|
|
26
|
-
this.#logger.debug(`[Job#${id}] ${key} await app ready`);
|
|
27
|
-
await this.#app.ready();
|
|
28
|
-
const schedule = scheduleWorker.scheduleItems[key];
|
|
29
|
-
this.#logger.debug(`[Job#${id}] ${key} task received by app`);
|
|
30
|
-
if (!schedule) {
|
|
31
|
-
this.#logger.warn(`[Job#${id}] ${key} unknown task`);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
/* istanbul ignore next */
|
|
35
|
-
if (schedule.schedule.disable) {
|
|
36
|
-
this.#logger.warn(`[Job#${id}] ${key} disable`);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
this.#logger.info(`[Job#${id}] ${key} executing by app`);
|
|
40
|
-
// run with anonymous context
|
|
41
|
-
const ctx = this.#app.createAnonymousContext({
|
|
42
|
-
method: 'SCHEDULE',
|
|
43
|
-
url: `/__schedule?path=${key}&${schedule.scheduleQueryString}`,
|
|
44
|
-
});
|
|
45
|
-
const start = Date.now();
|
|
46
|
-
let success;
|
|
47
|
-
let e;
|
|
48
|
-
try {
|
|
49
|
-
// execute
|
|
50
|
-
await this.#app.ctxStorage.run(ctx, async () => {
|
|
51
|
-
return await schedule.task(ctx, ...info.args);
|
|
52
|
-
});
|
|
53
|
-
success = true;
|
|
54
|
-
}
|
|
55
|
-
catch (err) {
|
|
56
|
-
success = false;
|
|
57
|
-
e = err;
|
|
58
|
-
}
|
|
59
|
-
const rt = Date.now() - start;
|
|
60
|
-
const msg = `[Job#${id}] ${key} execute ${success ? 'succeed' : 'failed'}, used ${rt}ms.`;
|
|
61
|
-
if (success) {
|
|
62
|
-
this.#logger.info(msg);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
this.#logger.error(msg, e);
|
|
66
|
-
}
|
|
67
|
-
// notify agent job finish
|
|
68
|
-
this.#app.messenger.sendToAgent('egg-schedule', {
|
|
69
|
-
...info,
|
|
70
|
-
success,
|
|
71
|
-
workerId: process.pid,
|
|
72
|
-
rt,
|
|
73
|
-
message: e?.message,
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
debug('configDidLoad');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
exports.default = Boot;
|
|
80
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUFxQztBQU1yQyxNQUFNLEtBQUssR0FBRyxJQUFBLG9CQUFRLEVBQUMscUJBQXFCLENBQUMsQ0FBQztBQUU5QyxNQUFxQixJQUFJO0lBQ3ZCLElBQUksQ0FBYztJQUNsQixPQUFPLENBQVk7SUFDbkIsWUFBWSxHQUFnQjtRQUMxQixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUNoQixJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWE7UUFDakIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDaEQsTUFBTSxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFNUIsb0JBQW9CO1FBQ3BCLEtBQUssTUFBTSxDQUFDLElBQUksY0FBYyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzdDLE1BQU0sUUFBUSxHQUFHLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM3RSxDQUFDO1FBQ0gsQ0FBQztRQUVELDBCQUEwQjtRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtZQUNsRCxLQUFLLENBQUMsb0NBQW9DLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbEQsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENB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
|