@contember/engine-server 2.1.0-alpha.30 → 2.1.0-alpha.36

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 (44) hide show
  1. package/package.json +17 -12
  2. package/src/cluster.ts +15 -17
  3. package/src/start.ts +3 -4
  4. package/dist/development/src/cluster.cjs +0 -87
  5. package/dist/development/src/cluster.cjs.map +0 -1
  6. package/dist/development/src/cluster.js +0 -87
  7. package/dist/development/src/cluster.js.map +0 -1
  8. package/dist/development/src/loadPlugins.cjs +0 -9
  9. package/dist/development/src/loadPlugins.cjs.map +0 -1
  10. package/dist/development/src/loadPlugins.js +0 -10
  11. package/dist/development/src/loadPlugins.js.map +0 -1
  12. package/dist/development/src/utils.cjs +0 -7
  13. package/dist/development/src/utils.cjs.map +0 -1
  14. package/dist/development/src/utils.js +0 -7
  15. package/dist/development/src/utils.js.map +0 -1
  16. package/dist/development/start.cjs +0 -152
  17. package/dist/development/start.cjs.map +0 -1
  18. package/dist/development/start.js +0 -134
  19. package/dist/development/start.js.map +0 -1
  20. package/dist/production/src/cluster.cjs +0 -87
  21. package/dist/production/src/cluster.cjs.map +0 -1
  22. package/dist/production/src/cluster.js +0 -87
  23. package/dist/production/src/cluster.js.map +0 -1
  24. package/dist/production/src/loadPlugins.cjs +0 -9
  25. package/dist/production/src/loadPlugins.cjs.map +0 -1
  26. package/dist/production/src/loadPlugins.js +0 -10
  27. package/dist/production/src/loadPlugins.js.map +0 -1
  28. package/dist/production/src/utils.cjs +0 -7
  29. package/dist/production/src/utils.cjs.map +0 -1
  30. package/dist/production/src/utils.js +0 -7
  31. package/dist/production/src/utils.js.map +0 -1
  32. package/dist/production/start.cjs +0 -152
  33. package/dist/production/start.cjs.map +0 -1
  34. package/dist/production/start.js +0 -134
  35. package/dist/production/start.js.map +0 -1
  36. package/dist/types/cluster.d.ts +0 -16
  37. package/dist/types/cluster.d.ts.map +0 -1
  38. package/dist/types/loadPlugins.d.ts +0 -3
  39. package/dist/types/loadPlugins.d.ts.map +0 -1
  40. package/dist/types/start.d.ts +0 -3
  41. package/dist/types/start.d.ts.map +0 -1
  42. package/dist/types/tsconfig.tsbuildinfo +0 -1
  43. package/dist/types/utils.d.ts +0 -2
  44. package/dist/types/utils.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-server",
3
- "version": "2.1.0-alpha.30",
3
+ "version": "2.1.0-alpha.36",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/production/index.js",
6
6
  "typings": "./dist/types/index.d.ts",
@@ -23,18 +23,23 @@
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@contember/engine-actions": "2.1.0-alpha.30",
27
- "@contember/engine-http": "2.1.0-alpha.30",
28
- "@contember/engine-plugins": "2.1.0-alpha.30",
29
- "@contember/engine-s3-plugin": "2.1.0-alpha.30",
30
- "@contember/engine-vimeo-plugin": "2.1.0-alpha.30",
31
- "graphql": "^16.9.0",
32
- "pg": "^8.12.0",
33
- "uuid": "^11.0.5"
26
+ "@contember/engine-actions": "workspace:*",
27
+ "@contember/engine-http": "workspace:*",
28
+ "@contember/engine-plugins": "workspace:*",
29
+ "@contember/engine-s3-plugin": "workspace:*",
30
+ "@contember/engine-vimeo-plugin": "workspace:*",
31
+ "graphql": "catalog:",
32
+ "pg": "catalog:",
33
+ "uuid": "catalog:"
34
34
  },
35
35
  "devDependencies": {
36
- "@types/koa-compress": "^4.0.6",
37
- "@types/node": "^20.17.22"
36
+ "@types/koa-compress": "catalog:",
37
+ "@types/node": "catalog:"
38
38
  },
39
- "type": "module"
39
+ "type": "module",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/contember/contember.git",
43
+ "directory": "packages/engine-server"
44
+ }
40
45
  }
package/src/cluster.ts CHANGED
@@ -39,7 +39,6 @@ export const notifyWorkerStarted = () =>
39
39
  })
40
40
 
41
41
  export class WorkerManager {
42
-
43
42
  private isTerminating = false
44
43
 
45
44
  private workers: Set<Worker> = new Set()
@@ -61,7 +60,6 @@ export class WorkerManager {
61
60
  worker.on('exit', async (code, signal) => {
62
61
  this.workers.delete(worker)
63
62
  if (!this.isTerminating) {
64
- // eslint-disable-next-line no-console
65
63
  console.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)
66
64
  await timeout(2000)
67
65
  await this.startWorker(env)
@@ -76,20 +74,20 @@ export class WorkerManager {
76
74
  throw new Error(`Worker manager is terminating`)
77
75
  }
78
76
  this.isTerminating = true
79
- await Promise.allSettled(Array.from(this.workers).map(async it => {
80
- if (!it) {
81
- return
82
- }
83
- // eslint-disable-next-line no-console
84
- console.log(`Terminating worker ${it.process.pid}`)
85
- const disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))
86
- it.disconnect()
87
- await disconnectPromise
88
- const killPromise = new Promise(resolve => it.once('exit', resolve))
89
- it.kill(signal)
90
- await killPromise
91
- // eslint-disable-next-line no-console
92
- console.log(`Worker ${it.process.pid} terminated`)
93
- }))
77
+ await Promise.allSettled(
78
+ Array.from(this.workers).map(async it => {
79
+ if (!it) {
80
+ return
81
+ }
82
+ console.log(`Terminating worker ${it.process.pid}`)
83
+ const disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))
84
+ it.disconnect()
85
+ await disconnectPromise
86
+ const killPromise = new Promise(resolve => it.once('exit', resolve))
87
+ it.kill(signal)
88
+ await killPromise
89
+ console.log(`Worker ${it.process.pid} terminated`)
90
+ }),
91
+ )
94
92
  }
95
93
  }
package/src/start.ts CHANGED
@@ -106,11 +106,10 @@ process.on('warning', message => {
106
106
  },
107
107
  })
108
108
  terminationJobs.push(async () => {
109
- (await runningWorker).end()
109
+ ;(await runningWorker).end()
110
110
  })
111
111
  await runningWorker
112
112
  logger.info(`Contember Worker ${workerName} started.`)
113
-
114
113
  }
115
114
 
116
115
  const applicationWorker = serverConfig.applicationWorker
@@ -133,7 +132,8 @@ process.on('warning', message => {
133
132
  if (applicationWorker === 'all') {
134
133
  for (const workerName of container.applicationWorkers.getWorkerNames()) {
135
134
  await workerManager.start({
136
- workerCount, env: {
135
+ workerCount,
136
+ env: {
137
137
  CONTEMBER_APPLICATION_WORKER: workerName,
138
138
  },
139
139
  })
@@ -158,7 +158,6 @@ process.on('warning', message => {
158
158
  }
159
159
  printStarted()
160
160
  }
161
-
162
161
  })().catch(e => {
163
162
  logger.crit(e)
164
163
  process.exit(1)
@@ -1,87 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const cluster = require("node:cluster");
4
- const utils = require("./utils.cjs");
5
- var __defProp = Object.defineProperty;
6
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
- const getClusterProcessType = (isClusterMode) => !isClusterMode ? "singleNode" : cluster.isMaster ? "clusterMaster" : "clusterWorker";
9
- const MSG_WORKER_STARTED = "msg_worker_started";
10
- const waitForWorker = (worker, timeoutMs) => {
11
- let ok = false;
12
- return Promise.race([
13
- new Promise(async (resolve) => {
14
- const listener = (message) => {
15
- if ("type" in message && message.type === MSG_WORKER_STARTED) {
16
- ok = true;
17
- resolve(null);
18
- worker.removeListener("message", listener);
19
- }
20
- };
21
- await worker.on("message", listener);
22
- }),
23
- utils.timeout(timeoutMs).then(() => {
24
- if (!ok) {
25
- throw new Error("Worker start timed out");
26
- }
27
- return true;
28
- })
29
- ]);
30
- };
31
- const notifyWorkerStarted = () => process.send?.({
32
- type: MSG_WORKER_STARTED
33
- });
34
- class WorkerManager {
35
- constructor() {
36
- __publicField(this, "isTerminating", false);
37
- __publicField(this, "workers", /* @__PURE__ */ new Set());
38
- }
39
- async start({ workerCount, env }) {
40
- if (this.isTerminating) {
41
- throw new Error(`Worker manager is terminating`);
42
- }
43
- for (let i = 0; i < workerCount; i++) {
44
- await this.startWorker(env);
45
- if (this.isTerminating) {
46
- return;
47
- }
48
- }
49
- }
50
- async startWorker(env) {
51
- const worker = cluster.fork(env);
52
- worker.on("exit", async (code, signal) => {
53
- this.workers.delete(worker);
54
- if (!this.isTerminating) {
55
- console.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`);
56
- await utils.timeout(2e3);
57
- await this.startWorker(env);
58
- }
59
- });
60
- this.workers.add(worker);
61
- await waitForWorker(worker, 15e3);
62
- }
63
- async terminate(signal) {
64
- if (this.isTerminating) {
65
- throw new Error(`Worker manager is terminating`);
66
- }
67
- this.isTerminating = true;
68
- await Promise.allSettled(Array.from(this.workers).map(async (it) => {
69
- if (!it) {
70
- return;
71
- }
72
- console.log(`Terminating worker ${it.process.pid}`);
73
- const disconnectPromise = new Promise((resolve) => it.once("disconnect", resolve));
74
- it.disconnect();
75
- await disconnectPromise;
76
- const killPromise = new Promise((resolve) => it.once("exit", resolve));
77
- it.kill(signal);
78
- await killPromise;
79
- console.log(`Worker ${it.process.pid} terminated`);
80
- }));
81
- }
82
- }
83
- exports.WorkerManager = WorkerManager;
84
- exports.getClusterProcessType = getClusterProcessType;
85
- exports.notifyWorkerStarted = notifyWorkerStarted;
86
- exports.waitForWorker = waitForWorker;
87
- //# sourceMappingURL=cluster.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cluster.cjs","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(Array.from(this.workers).map(async it => {\n\t\t\tif (!it) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\tit.disconnect()\n\t\t\tawait disconnectPromise\n\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\tit.kill(signal)\n\t\t\tawait killPromise\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t}))\n\t}\n}\n"],"names":["timeout"],"mappings":";;;;;;;AAGa,MAAA,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEd,MAAA,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AACtB,YAAA,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AACxD,eAAA;AACL,kBAAQ,IAAI;AACL,iBAAA,eAAe,WAAW,QAAQ;AAAA,QAAA;AAAA,MAE3C;AACM,YAAA,OAAO,GAAG,WAAW,QAAQ;AAAA,IAAA,CACnC;AAAA,IACDA,cAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACF,cAAA,IAAI,MAAM,wBAAwB;AAAA,MAAA;AAElC,aAAA;AAAA,IACP,CAAA;AAAA,EAAA,CACD;AACF;AAEa,MAAA,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AAEN,kBAAA,MAAQ,iBAAgB,KAAA;AAEhB,kBAAA,MAAA,+BAA2B,IAAI,CAAA;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACjB,YAAA,IAAI,MAAM,+BAA+B;AAAA,IAAA;AAEhD,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AAC/B,YAAA,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MAAA;AAAA,IACD;AAAA,EACD;AAAA,EAGD,MAAc,YAAY,KAAW;AAC9B,UAAA,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACpC,WAAA,QAAQ,OAAO,MAAM;AACtB,UAAA,CAAC,KAAK,eAAe;AAExB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAMA,MAAAA,QAAQ,GAAI;AACZ,cAAA,KAAK,YAAY,GAAG;AAAA,MAAA;AAAA,IAC3B,CACA;AACI,SAAA,QAAQ,IAAI,MAAM;AACjB,UAAA,cAAc,QAAQ,IAAK;AAAA,EAAA;AAAA,EAGlC,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACjB,YAAA,IAAI,MAAM,+BAA+B;AAAA,IAAA;AAEhD,SAAK,gBAAgB;AACf,UAAA,QAAQ,WAAW,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACjE,UAAI,CAAC,IAAI;AACR;AAAA,MAAA;AAGD,cAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAC5C,YAAA,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,SAAG,WAAW;AACR,YAAA;AACA,YAAA,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,SAAG,KAAK,MAAM;AACR,YAAA;AAEN,cAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,IAAA,CACjD,CAAC;AAAA,EAAA;AAEJ;;;;;"}
@@ -1,87 +0,0 @@
1
- import cluster from "node:cluster";
2
- import { timeout } from "./utils.js";
3
- var __defProp = Object.defineProperty;
4
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
- const getClusterProcessType = (isClusterMode) => !isClusterMode ? "singleNode" : cluster.isMaster ? "clusterMaster" : "clusterWorker";
7
- const MSG_WORKER_STARTED = "msg_worker_started";
8
- const waitForWorker = (worker, timeoutMs) => {
9
- let ok = false;
10
- return Promise.race([
11
- new Promise(async (resolve) => {
12
- const listener = (message) => {
13
- if ("type" in message && message.type === MSG_WORKER_STARTED) {
14
- ok = true;
15
- resolve(null);
16
- worker.removeListener("message", listener);
17
- }
18
- };
19
- await worker.on("message", listener);
20
- }),
21
- timeout(timeoutMs).then(() => {
22
- if (!ok) {
23
- throw new Error("Worker start timed out");
24
- }
25
- return true;
26
- })
27
- ]);
28
- };
29
- const notifyWorkerStarted = () => process.send?.({
30
- type: MSG_WORKER_STARTED
31
- });
32
- class WorkerManager {
33
- constructor() {
34
- __publicField(this, "isTerminating", false);
35
- __publicField(this, "workers", /* @__PURE__ */ new Set());
36
- }
37
- async start({ workerCount, env }) {
38
- if (this.isTerminating) {
39
- throw new Error(`Worker manager is terminating`);
40
- }
41
- for (let i = 0; i < workerCount; i++) {
42
- await this.startWorker(env);
43
- if (this.isTerminating) {
44
- return;
45
- }
46
- }
47
- }
48
- async startWorker(env) {
49
- const worker = cluster.fork(env);
50
- worker.on("exit", async (code, signal) => {
51
- this.workers.delete(worker);
52
- if (!this.isTerminating) {
53
- console.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`);
54
- await timeout(2e3);
55
- await this.startWorker(env);
56
- }
57
- });
58
- this.workers.add(worker);
59
- await waitForWorker(worker, 15e3);
60
- }
61
- async terminate(signal) {
62
- if (this.isTerminating) {
63
- throw new Error(`Worker manager is terminating`);
64
- }
65
- this.isTerminating = true;
66
- await Promise.allSettled(Array.from(this.workers).map(async (it) => {
67
- if (!it) {
68
- return;
69
- }
70
- console.log(`Terminating worker ${it.process.pid}`);
71
- const disconnectPromise = new Promise((resolve) => it.once("disconnect", resolve));
72
- it.disconnect();
73
- await disconnectPromise;
74
- const killPromise = new Promise((resolve) => it.once("exit", resolve));
75
- it.kill(signal);
76
- await killPromise;
77
- console.log(`Worker ${it.process.pid} terminated`);
78
- }));
79
- }
80
- }
81
- export {
82
- WorkerManager,
83
- getClusterProcessType,
84
- notifyWorkerStarted,
85
- waitForWorker
86
- };
87
- //# sourceMappingURL=cluster.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cluster.js","sources":["../../../../packages/engine-server/src/cluster.ts"],"sourcesContent":["import cluster, { Worker } from 'node:cluster'\nimport { timeout } from './utils'\n\nexport const getClusterProcessType = (isClusterMode: boolean): ProcessType =>\n\t!isClusterMode ? 'singleNode' : cluster.isMaster ? 'clusterMaster' : 'clusterWorker'\n\nexport type ProcessType =\n\t| 'singleNode'\n\t| 'clusterMaster'\n\t| 'clusterWorker'\n\nconst MSG_WORKER_STARTED = 'msg_worker_started'\n\nexport const waitForWorker = (worker: Worker, timeoutMs: number) => {\n\tlet ok = false\n\treturn Promise.race([\n\t\tnew Promise(async resolve => {\n\t\t\tconst listener = (message: any) => {\n\t\t\t\tif ('type' in message && message.type === MSG_WORKER_STARTED) {\n\t\t\t\t\tok = true\n\t\t\t\t\tresolve(null)\n\t\t\t\t\tworker.removeListener('message', listener)\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait worker.on('message', listener)\n\t\t}),\n\t\ttimeout(timeoutMs).then(() => {\n\t\t\tif (!ok) {\n\t\t\t\tthrow new Error('Worker start timed out')\n\t\t\t}\n\t\t\treturn true\n\t\t}),\n\t])\n}\n\nexport const notifyWorkerStarted = () =>\n\tprocess.send?.({\n\t\ttype: MSG_WORKER_STARTED,\n\t})\n\nexport class WorkerManager {\n\n\tprivate isTerminating = false\n\n\tprivate workers: Set<Worker> = new Set()\n\n\tpublic async start({ workerCount, env }: { workerCount: number; env?: any }): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\tawait this.startWorker(env)\n\t\t\tif (this.isTerminating) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async startWorker(env?: any) {\n\t\tconst worker = cluster.fork(env)\n\t\tworker.on('exit', async (code, signal) => {\n\t\t\tthis.workers.delete(worker)\n\t\t\tif (!this.isTerminating) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(`Worker ${worker.process.pid} died with signal ${signal}, restarting`)\n\t\t\t\tawait timeout(2000)\n\t\t\t\tawait this.startWorker(env)\n\t\t\t}\n\t\t})\n\t\tthis.workers.add(worker)\n\t\tawait waitForWorker(worker, 15000)\n\t}\n\n\tpublic async terminate(signal: NodeJS.Signals): Promise<void> {\n\t\tif (this.isTerminating) {\n\t\t\tthrow new Error(`Worker manager is terminating`)\n\t\t}\n\t\tthis.isTerminating = true\n\t\tawait Promise.allSettled(Array.from(this.workers).map(async it => {\n\t\t\tif (!it) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(`Terminating worker ${it.process.pid}`)\n\t\t\tconst disconnectPromise = new Promise(resolve => it.once('disconnect', resolve))\n\t\t\tit.disconnect()\n\t\t\tawait disconnectPromise\n\t\t\tconst killPromise = new Promise(resolve => it.once('exit', resolve))\n\t\t\tit.kill(signal)\n\t\t\tawait killPromise\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(`Worker ${it.process.pid} terminated`)\n\t\t}))\n\t}\n}\n"],"names":[],"mappings":";;;;;AAGa,MAAA,wBAAwB,CAAC,kBACrC,CAAC,gBAAgB,eAAe,QAAQ,WAAW,kBAAkB;AAOtE,MAAM,qBAAqB;AAEd,MAAA,gBAAgB,CAAC,QAAgB,cAAsB;AACnE,MAAI,KAAK;AACT,SAAO,QAAQ,KAAK;AAAA,IACnB,IAAI,QAAQ,OAAM,YAAW;AACtB,YAAA,WAAW,CAAC,YAAiB;AAClC,YAAI,UAAU,WAAW,QAAQ,SAAS,oBAAoB;AACxD,eAAA;AACL,kBAAQ,IAAI;AACL,iBAAA,eAAe,WAAW,QAAQ;AAAA,QAAA;AAAA,MAE3C;AACM,YAAA,OAAO,GAAG,WAAW,QAAQ;AAAA,IAAA,CACnC;AAAA,IACD,QAAQ,SAAS,EAAE,KAAK,MAAM;AAC7B,UAAI,CAAC,IAAI;AACF,cAAA,IAAI,MAAM,wBAAwB;AAAA,MAAA;AAElC,aAAA;AAAA,IACP,CAAA;AAAA,EAAA,CACD;AACF;AAEa,MAAA,sBAAsB,MAClC,QAAQ,OAAO;AAAA,EACd,MAAM;AACP,CAAC;AAEK,MAAM,cAAc;AAAA,EAApB,cAAA;AAEN,kBAAA,MAAQ,iBAAgB,KAAA;AAEhB,kBAAA,MAAA,+BAA2B,IAAI,CAAA;AAAA,EAAA;AAAA,EAEvC,MAAa,MAAM,EAAE,aAAa,OAA0D;AAC3F,QAAI,KAAK,eAAe;AACjB,YAAA,IAAI,MAAM,+BAA+B;AAAA,IAAA;AAEhD,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AAC/B,YAAA,KAAK,YAAY,GAAG;AAC1B,UAAI,KAAK,eAAe;AACvB;AAAA,MAAA;AAAA,IACD;AAAA,EACD;AAAA,EAGD,MAAc,YAAY,KAAW;AAC9B,UAAA,SAAS,QAAQ,KAAK,GAAG;AAC/B,WAAO,GAAG,QAAQ,OAAO,MAAM,WAAW;AACpC,WAAA,QAAQ,OAAO,MAAM;AACtB,UAAA,CAAC,KAAK,eAAe;AAExB,gBAAQ,IAAI,UAAU,OAAO,QAAQ,GAAG,qBAAqB,MAAM,cAAc;AACjF,cAAM,QAAQ,GAAI;AACZ,cAAA,KAAK,YAAY,GAAG;AAAA,MAAA;AAAA,IAC3B,CACA;AACI,SAAA,QAAQ,IAAI,MAAM;AACjB,UAAA,cAAc,QAAQ,IAAK;AAAA,EAAA;AAAA,EAGlC,MAAa,UAAU,QAAuC;AAC7D,QAAI,KAAK,eAAe;AACjB,YAAA,IAAI,MAAM,+BAA+B;AAAA,IAAA;AAEhD,SAAK,gBAAgB;AACf,UAAA,QAAQ,WAAW,MAAM,KAAK,KAAK,OAAO,EAAE,IAAI,OAAM,OAAM;AACjE,UAAI,CAAC,IAAI;AACR;AAAA,MAAA;AAGD,cAAQ,IAAI,sBAAsB,GAAG,QAAQ,GAAG,EAAE;AAC5C,YAAA,oBAAoB,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,cAAc,OAAO,CAAC;AAC/E,SAAG,WAAW;AACR,YAAA;AACA,YAAA,cAAc,IAAI,QAAQ,CAAA,YAAW,GAAG,KAAK,QAAQ,OAAO,CAAC;AACnE,SAAG,KAAK,MAAM;AACR,YAAA;AAEN,cAAQ,IAAI,UAAU,GAAG,QAAQ,GAAG,aAAa;AAAA,IAAA,CACjD,CAAC;AAAA,EAAA;AAEJ;"}
@@ -1,9 +0,0 @@
1
- "use strict";
2
- const ActionsPlugin = require("@contember/engine-actions");
3
- const S3Plugin = require("@contember/engine-s3-plugin");
4
- const VimeoPlugin = require("@contember/engine-vimeo-plugin");
5
- function loadPlugins() {
6
- return Promise.resolve([new S3Plugin(), new VimeoPlugin(), new ActionsPlugin()]);
7
- }
8
- module.exports = loadPlugins;
9
- //# sourceMappingURL=loadPlugins.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadPlugins.cjs","sources":["../../../../packages/engine-server/src/loadPlugins.ts"],"sourcesContent":["import ActionsPlugin from '@contember/engine-actions'\nimport { Plugin } from '@contember/engine-plugins'\nimport S3Plugin from '@contember/engine-s3-plugin'\nimport VimeoPlugin from '@contember/engine-vimeo-plugin'\n\nexport default function loadPlugins(): Promise<Plugin[]> {\n\treturn Promise.resolve([new S3Plugin(), new VimeoPlugin(), new ActionsPlugin()])\n}\n"],"names":[],"mappings":";;;;AAKA,SAAwB,cAAiC;AACxD,SAAO,QAAQ,QAAQ,CAAC,IAAI,SAAS,GAAG,IAAI,YAAe,GAAA,IAAI,cAAc,CAAC,CAAC;AAChF;;"}
@@ -1,10 +0,0 @@
1
- import ActionsPlugin from "@contember/engine-actions";
2
- import S3Plugin from "@contember/engine-s3-plugin";
3
- import VimeoPlugin from "@contember/engine-vimeo-plugin";
4
- function loadPlugins() {
5
- return Promise.resolve([new S3Plugin(), new VimeoPlugin(), new ActionsPlugin()]);
6
- }
7
- export {
8
- loadPlugins as default
9
- };
10
- //# sourceMappingURL=loadPlugins.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadPlugins.js","sources":["../../../../packages/engine-server/src/loadPlugins.ts"],"sourcesContent":["import ActionsPlugin from '@contember/engine-actions'\nimport { Plugin } from '@contember/engine-plugins'\nimport S3Plugin from '@contember/engine-s3-plugin'\nimport VimeoPlugin from '@contember/engine-vimeo-plugin'\n\nexport default function loadPlugins(): Promise<Plugin[]> {\n\treturn Promise.resolve([new S3Plugin(), new VimeoPlugin(), new ActionsPlugin()])\n}\n"],"names":[],"mappings":";;;AAKA,SAAwB,cAAiC;AACxD,SAAO,QAAQ,QAAQ,CAAC,IAAI,SAAS,GAAG,IAAI,YAAe,GAAA,IAAI,cAAc,CAAC,CAAC;AAChF;"}
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const timeout = (ms) => new Promise((resolve) => {
4
- setTimeout(resolve, ms);
5
- });
6
- exports.timeout = timeout;
7
- //# sourceMappingURL=utils.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.cjs","sources":["../../../../packages/engine-server/src/utils.ts"],"sourcesContent":["export const timeout = (ms: number) =>\n\tnew Promise(resolve => {\n\t\tsetTimeout(resolve, ms)\n\t})\n"],"names":[],"mappings":";;AAAO,MAAM,UAAU,CAAC,OACvB,IAAI,QAAQ,CAAW,YAAA;AACtB,aAAW,SAAS,EAAE;AACvB,CAAC;;"}
@@ -1,7 +0,0 @@
1
- const timeout = (ms) => new Promise((resolve) => {
2
- setTimeout(resolve, ms);
3
- });
4
- export {
5
- timeout
6
- };
7
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../packages/engine-server/src/utils.ts"],"sourcesContent":["export const timeout = (ms: number) =>\n\tnew Promise(resolve => {\n\t\tsetTimeout(resolve, ms)\n\t})\n"],"names":[],"mappings":"AAAO,MAAM,UAAU,CAAC,OACvB,IAAI,QAAQ,CAAW,YAAA;AACtB,aAAW,SAAS,EAAE;AACvB,CAAC;"}
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- const engineHttp = require("@contember/engine-http");
4
- const loadPlugins = require("./src/loadPlugins.cjs");
5
- const cluster$1 = require("node:cluster");
6
- const os = require("node:os");
7
- const utils = require("./src/utils.cjs");
8
- const cluster = require("./src/cluster.cjs");
9
- function _interopNamespaceDefault(e) {
10
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
11
- if (e) {
12
- for (const k in e) {
13
- if (k !== "default") {
14
- const d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: () => e[k]
18
- });
19
- }
20
- }
21
- }
22
- n.default = e;
23
- return Object.freeze(n);
24
- }
25
- const os__namespace = /* @__PURE__ */ _interopNamespaceDefault(os);
26
- const logger = engineHttp.createDefaultLogger();
27
- process.on("warning", (message) => {
28
- logger.warn(message);
29
- });
30
- (async () => {
31
- const isDebug = engineHttp.isDebugMode();
32
- const version = await engineHttp.getServerVersion();
33
- engineHttp.printStartInfo({ version, isDebug }, logger);
34
- const plugins = await loadPlugins();
35
- const { serverConfig, projectConfigResolver, tenantConfigResolver } = await engineHttp.resolveServerConfig({ plugins, serverConfigSchema: engineHttp.serverConfigSchema });
36
- if (process.argv[2] === "validate") {
37
- process.exit(0);
38
- }
39
- const sentryhandler = engineHttp.createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn);
40
- if (sentryhandler !== null) {
41
- logger.addHandler(sentryhandler);
42
- }
43
- const workerConfig = serverConfig.workerCount || 1;
44
- const workerCount = workerConfig === "auto" ? os__namespace.cpus().length : Number(workerConfig);
45
- const isClusterMode = serverConfig.workerCount !== void 0;
46
- const processType = cluster.getClusterProcessType(isClusterMode);
47
- const container = engineHttp.createContainer({
48
- debugMode: isDebug,
49
- serverConfig,
50
- projectConfigResolver,
51
- tenantConfigResolver,
52
- plugins,
53
- processType,
54
- version,
55
- logger
56
- });
57
- let initializedProjects = [];
58
- const terminationJobs = [];
59
- engineHttp.listenOnProcessTermination(terminationJobs, logger);
60
- if (cluster$1.isMaster) {
61
- const monitoringPort = serverConfig.monitoringPort;
62
- const monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {
63
- logger.info(`Monitoring running on http://localhost:${monitoringPort}`);
64
- });
65
- terminationJobs.push(async () => {
66
- await new Promise((resolve) => monitoringServer.close(resolve));
67
- logger.info("Monitoring server terminated");
68
- });
69
- if (!serverConfig.projectGroup) {
70
- initializedProjects = await container.initializer.initialize();
71
- }
72
- }
73
- const port = serverConfig.port;
74
- const printStarted = () => {
75
- if (serverConfig.projectGroup) {
76
- logger.info("Contember Cloud running");
77
- } else {
78
- logger.info(`Contember API running on http://localhost:${port}`);
79
- }
80
- if (initializedProjects.length) {
81
- logger.info(`Initialized projects: ${initializedProjects.join(", ")}`);
82
- }
83
- };
84
- const startApplication = async () => {
85
- const httpServerPromise = container.application.listen();
86
- terminationJobs.push(async () => {
87
- await (await httpServerPromise).close();
88
- logger.info("API server terminated");
89
- });
90
- await httpServerPromise;
91
- };
92
- const startWorker = async (workerName) => {
93
- const worker = container.applicationWorkers.getWorker(workerName);
94
- const runningWorker = worker.run({
95
- logger,
96
- onError: (e) => {
97
- logger.crit(e);
98
- process.exit(1);
99
- }
100
- });
101
- terminationJobs.push(async () => {
102
- (await runningWorker).end();
103
- });
104
- await runningWorker;
105
- logger.info(`Contember Worker ${workerName} started.`);
106
- };
107
- const applicationWorker = serverConfig.applicationWorker;
108
- if (applicationWorker && applicationWorker !== "all") {
109
- await startWorker(applicationWorker);
110
- if (isClusterMode) {
111
- cluster.notifyWorkerStarted();
112
- }
113
- } else if (isClusterMode) {
114
- if (cluster$1.isMaster) {
115
- logger.info(`Master ${process.pid} is running`);
116
- const workerManager = new cluster.WorkerManager();
117
- terminationJobs.push(async ({ signal }) => {
118
- await workerManager.terminate(signal);
119
- logger.info("Workers terminated");
120
- });
121
- await workerManager.start({ workerCount });
122
- if (applicationWorker === "all") {
123
- for (const workerName of container.applicationWorkers.getWorkerNames()) {
124
- await workerManager.start({
125
- workerCount,
126
- env: {
127
- CONTEMBER_APPLICATION_WORKER: workerName
128
- }
129
- });
130
- }
131
- }
132
- printStarted();
133
- } else {
134
- logger.info(`Starting worker ${process.pid}`);
135
- process.on("disconnect", () => utils.timeout(0));
136
- await startApplication();
137
- cluster.notifyWorkerStarted();
138
- }
139
- } else {
140
- await startApplication();
141
- if (applicationWorker === "all") {
142
- for (const workerName of container.applicationWorkers.getWorkerNames()) {
143
- await startWorker(workerName);
144
- }
145
- }
146
- printStarted();
147
- }
148
- })().catch((e) => {
149
- logger.crit(e);
150
- process.exit(1);
151
- });
152
- //# sourceMappingURL=start.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"start.cjs","sources":["../../../packages/engine-server/src/start.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {\n\tcreateContainer,\n\tcreateDefaultLogger,\n\tcreateSentryLoggerHandler,\n\tgetServerVersion,\n\tisDebugMode,\n\tlistenOnProcessTermination,\n\tprintStartInfo,\n\tresolveServerConfig,\n\tserverConfigSchema,\n\tTerminationJob,\n} from '@contember/engine-http'\nimport loadPlugins from './loadPlugins'\nimport cluster from 'node:cluster'\nimport * as os from 'node:os'\nimport { timeout } from './utils'\nimport { getClusterProcessType, notifyWorkerStarted, WorkerManager } from './cluster'\n\nconst logger = createDefaultLogger()\nprocess.on('warning', message => {\n\tlogger.warn(message)\n})\n;(async () => {\n\tconst isDebug = isDebugMode()\n\n\tconst version = await getServerVersion()\n\tprintStartInfo({ version, isDebug }, logger)\n\tconst plugins = await loadPlugins()\n\tconst { serverConfig, projectConfigResolver, tenantConfigResolver } = await resolveServerConfig({ plugins, serverConfigSchema })\n\n\tif (process.argv[2] === 'validate') {\n\t\tprocess.exit(0)\n\t}\n\n\tconst sentryhandler = createSentryLoggerHandler(serverConfig.logging?.sentry?.dsn)\n\tif (sentryhandler !== null) {\n\t\tlogger.addHandler(sentryhandler)\n\t}\n\n\tconst workerConfig = serverConfig.workerCount || 1\n\n\tconst workerCount = workerConfig === 'auto' ? os.cpus().length : Number(workerConfig)\n\tconst isClusterMode = serverConfig.workerCount !== undefined\n\n\tconst processType = getClusterProcessType(isClusterMode)\n\n\tconst container = createContainer({\n\t\tdebugMode: isDebug,\n\t\tserverConfig,\n\t\tprojectConfigResolver,\n\t\ttenantConfigResolver,\n\t\tplugins,\n\t\tprocessType,\n\t\tversion,\n\t\tlogger,\n\t})\n\n\tlet initializedProjects: string[] = []\n\tconst terminationJobs: TerminationJob[] = []\n\tlistenOnProcessTermination(terminationJobs, logger)\n\n\tif (cluster.isMaster) {\n\t\tconst monitoringPort = serverConfig.monitoringPort\n\t\tconst monitoringServer = container.monitoringKoa.listen(monitoringPort, () => {\n\t\t\tlogger.info(`Monitoring running on http://localhost:${monitoringPort}`)\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\tawait new Promise<any>(resolve => monitoringServer.close(resolve))\n\t\t\tlogger.info('Monitoring server terminated')\n\t\t})\n\t\tif (!serverConfig.projectGroup) {\n\t\t\tinitializedProjects = await container.initializer.initialize()\n\t\t}\n\t}\n\n\tconst port = serverConfig.port\n\tconst printStarted = () => {\n\t\tif (serverConfig.projectGroup) {\n\t\t\tlogger.info('Contember Cloud running')\n\t\t} else {\n\t\t\tlogger.info(`Contember API running on http://localhost:${port}`)\n\t\t}\n\t\tif (initializedProjects.length) {\n\t\t\tlogger.info(`Initialized projects: ${initializedProjects.join(', ')}`)\n\t\t}\n\t}\n\n\tconst startApplication = async () => {\n\t\tconst httpServerPromise = container.application.listen()\n\t\tterminationJobs.push(async () => {\n\t\t\tawait (await httpServerPromise).close()\n\t\t\tlogger.info('API server terminated')\n\t\t})\n\t\tawait httpServerPromise\n\t}\n\n\tconst startWorker = async (workerName: string) => {\n\t\tconst worker = container.applicationWorkers.getWorker(workerName)\n\t\tconst runningWorker = worker.run({\n\t\t\tlogger,\n\t\t\tonError: e => {\n\t\t\t\tlogger.crit(e)\n\t\t\t\tprocess.exit(1)\n\t\t\t},\n\t\t})\n\t\tterminationJobs.push(async () => {\n\t\t\t(await runningWorker).end()\n\t\t})\n\t\tawait runningWorker\n\t\tlogger.info(`Contember Worker ${workerName} started.`)\n\n\t}\n\n\tconst applicationWorker = serverConfig.applicationWorker\n\tif (applicationWorker && applicationWorker !== 'all') {\n\t\tawait startWorker(applicationWorker)\n\t\tif (isClusterMode) {\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else if (isClusterMode) {\n\t\tif (cluster.isMaster) {\n\t\t\tlogger.info(`Master ${process.pid} is running`)\n\t\t\tconst workerManager = new WorkerManager()\n\t\t\tterminationJobs.push(async ({ signal }) => {\n\t\t\t\tawait workerManager.terminate(signal)\n\t\t\t\tlogger.info('Workers terminated')\n\t\t\t})\n\n\t\t\tawait workerManager.start({ workerCount })\n\n\t\t\tif (applicationWorker === 'all') {\n\t\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\t\tawait workerManager.start({\n\t\t\t\t\t\tworkerCount, env: {\n\t\t\t\t\t\t\tCONTEMBER_APPLICATION_WORKER: workerName,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintStarted()\n\t\t} else {\n\t\t\tlogger.info(`Starting worker ${process.pid}`)\n\n\t\t\t// this line somehow ensures, that worker waits for termination of all jobs\n\t\t\tprocess.on('disconnect', () => timeout(0))\n\n\t\t\tawait startApplication()\n\t\t\tnotifyWorkerStarted()\n\t\t}\n\t} else {\n\t\tawait startApplication()\n\t\tif (applicationWorker === 'all') {\n\t\t\tfor (const workerName of container.applicationWorkers.getWorkerNames()) {\n\t\t\t\tawait startWorker(workerName)\n\t\t\t}\n\t\t}\n\t\tprintStarted()\n\t}\n\n})().catch(e => {\n\tlogger.crit(e)\n\tprocess.exit(1)\n})\n"],"names":["createDefaultLogger","isDebugMode","getServerVersion","printStartInfo","resolveServerConfig","serverConfigSchema","createSentryLoggerHandler","os","getClusterProcessType","createContainer","listenOnProcessTermination","cluster","notifyWorkerStarted","WorkerManager","timeout"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAM,SAASA,WAAAA,oBAAoB;AACnC,QAAQ,GAAG,WAAW,CAAW,YAAA;AAChC,SAAO,KAAK,OAAO;AACpB,CAAC;AAAA,CACC,YAAY;AACb,QAAM,UAAUC,WAAAA,YAAY;AAEtB,QAAA,UAAU,MAAMC,4BAAiB;AACvCC,aAAAA,eAAe,EAAE,SAAS,QAAQ,GAAG,MAAM;AACrC,QAAA,UAAU,MAAM,YAAY;AAC5B,QAAA,EAAE,cAAc,uBAAuB,qBAAqB,IAAI,MAAMC,+BAAoB,EAAE,SAASC,oBAAAA,WAAAA,oBAAoB;AAE/H,MAAI,QAAQ,KAAK,CAAC,MAAM,YAAY;AACnC,YAAQ,KAAK,CAAC;AAAA,EAAA;AAGf,QAAM,gBAAgBC,WAAAA,0BAA0B,aAAa,SAAS,QAAQ,GAAG;AACjF,MAAI,kBAAkB,MAAM;AAC3B,WAAO,WAAW,aAAa;AAAA,EAAA;AAG1B,QAAA,eAAe,aAAa,eAAe;AAE3C,QAAA,cAAc,iBAAiB,SAASC,cAAG,OAAO,SAAS,OAAO,YAAY;AAC9E,QAAA,gBAAgB,aAAa,gBAAgB;AAE7C,QAAA,cAAcC,8BAAsB,aAAa;AAEvD,QAAM,YAAYC,WAAAA,gBAAgB;AAAA,IACjC,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACA;AAED,MAAI,sBAAgC,CAAC;AACrC,QAAM,kBAAoC,CAAC;AAC3CC,aAAA,2BAA2B,iBAAiB,MAAM;AAElD,MAAIC,UAAQ,UAAU;AACrB,UAAM,iBAAiB,aAAa;AACpC,UAAM,mBAAmB,UAAU,cAAc,OAAO,gBAAgB,MAAM;AACtE,aAAA,KAAK,0CAA0C,cAAc,EAAE;AAAA,IAAA,CACtE;AACD,oBAAgB,KAAK,YAAY;AAChC,YAAM,IAAI,QAAa,CAAA,YAAW,iBAAiB,MAAM,OAAO,CAAC;AACjE,aAAO,KAAK,8BAA8B;AAAA,IAAA,CAC1C;AACG,QAAA,CAAC,aAAa,cAAc;AACT,4BAAA,MAAM,UAAU,YAAY,WAAW;AAAA,IAAA;AAAA,EAC9D;AAGD,QAAM,OAAO,aAAa;AAC1B,QAAM,eAAe,MAAM;AAC1B,QAAI,aAAa,cAAc;AAC9B,aAAO,KAAK,yBAAyB;AAAA,IAAA,OAC/B;AACC,aAAA,KAAK,6CAA6C,IAAI,EAAE;AAAA,IAAA;AAEhE,QAAI,oBAAoB,QAAQ;AAC/B,aAAO,KAAK,yBAAyB,oBAAoB,KAAK,IAAI,CAAC,EAAE;AAAA,IAAA;AAAA,EAEvE;AAEA,QAAM,mBAAmB,YAAY;AAC9B,UAAA,oBAAoB,UAAU,YAAY,OAAO;AACvD,oBAAgB,KAAK,YAAY;AACzB,aAAA,MAAM,mBAAmB,MAAM;AACtC,aAAO,KAAK,uBAAuB;AAAA,IAAA,CACnC;AACK,UAAA;AAAA,EACP;AAEM,QAAA,cAAc,OAAO,eAAuB;AACjD,UAAM,SAAS,UAAU,mBAAmB,UAAU,UAAU;AAC1D,UAAA,gBAAgB,OAAO,IAAI;AAAA,MAChC;AAAA,MACA,SAAS,CAAK,MAAA;AACb,eAAO,KAAK,CAAC;AACb,gBAAQ,KAAK,CAAC;AAAA,MAAA;AAAA,IACf,CACA;AACD,oBAAgB,KAAK,YAAY;AAC/B,OAAA,MAAM,eAAe,IAAI;AAAA,IAAA,CAC1B;AACK,UAAA;AACC,WAAA,KAAK,oBAAoB,UAAU,WAAW;AAAA,EAEtD;AAEA,QAAM,oBAAoB,aAAa;AACnC,MAAA,qBAAqB,sBAAsB,OAAO;AACrD,UAAM,YAAY,iBAAiB;AACnC,QAAI,eAAe;AACEC,kCAAA;AAAA,IAAA;AAAA,aAEX,eAAe;AACzB,QAAID,UAAQ,UAAU;AACrB,aAAO,KAAK,UAAU,QAAQ,GAAG,aAAa;AACxC,YAAA,gBAAgB,IAAIE,sBAAc;AACxC,sBAAgB,KAAK,OAAO,EAAE,aAAa;AACpC,cAAA,cAAc,UAAU,MAAM;AACpC,eAAO,KAAK,oBAAoB;AAAA,MAAA,CAChC;AAED,YAAM,cAAc,MAAM,EAAE,aAAa;AAEzC,UAAI,sBAAsB,OAAO;AAChC,mBAAW,cAAc,UAAU,mBAAmB,eAAA,GAAkB;AACvE,gBAAM,cAAc,MAAM;AAAA,YACzB;AAAA,YAAa,KAAK;AAAA,cACjB,8BAA8B;AAAA,YAAA;AAAA,UAC/B,CACA;AAAA,QAAA;AAAA,MACF;AAEY,mBAAA;AAAA,IAAA,OACP;AACN,aAAO,KAAK,mBAAmB,QAAQ,GAAG,EAAE;AAG5C,cAAQ,GAAG,cAAc,MAAMC,MAAA,QAAQ,CAAC,CAAC;AAEzC,YAAM,iBAAiB;AACHF,kCAAA;AAAA,IAAA;AAAA,EACrB,OACM;AACN,UAAM,iBAAiB;AACvB,QAAI,sBAAsB,OAAO;AAChC,iBAAW,cAAc,UAAU,mBAAmB,eAAA,GAAkB;AACvE,cAAM,YAAY,UAAU;AAAA,MAAA;AAAA,IAC7B;AAEY,iBAAA;AAAA,EAAA;AAGf,KAAK,MAAM,CAAK,MAAA;AACf,SAAO,KAAK,CAAC;AACb,UAAQ,KAAK,CAAC;AACf,CAAC;"}