@sonamu-kit/tasks 0.0.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 (280) hide show
  1. package/.swcrc +17 -0
  2. package/README.md +7 -0
  3. package/dist/backend.d.ts +107 -0
  4. package/dist/backend.d.ts.map +1 -0
  5. package/dist/backend.js +3 -0
  6. package/dist/backend.js.map +1 -0
  7. package/dist/chaos.test.d.ts +2 -0
  8. package/dist/chaos.test.d.ts.map +1 -0
  9. package/dist/chaos.test.js +92 -0
  10. package/dist/chaos.test.js.map +1 -0
  11. package/dist/client.d.ts +178 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +223 -0
  14. package/dist/client.js.map +1 -0
  15. package/dist/client.test.d.ts +2 -0
  16. package/dist/client.test.d.ts.map +1 -0
  17. package/dist/client.test.js +339 -0
  18. package/dist/client.test.js.map +1 -0
  19. package/dist/config.d.ts +22 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +23 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/config.test.d.ts +2 -0
  24. package/dist/config.test.d.ts.map +1 -0
  25. package/dist/config.test.js +24 -0
  26. package/dist/config.test.js.map +1 -0
  27. package/dist/core/duration.d.ts +22 -0
  28. package/dist/core/duration.d.ts.map +1 -0
  29. package/dist/core/duration.js +64 -0
  30. package/dist/core/duration.js.map +1 -0
  31. package/dist/core/duration.test.d.ts +2 -0
  32. package/dist/core/duration.test.d.ts.map +1 -0
  33. package/dist/core/duration.test.js +265 -0
  34. package/dist/core/duration.test.js.map +1 -0
  35. package/dist/core/error.d.ts +15 -0
  36. package/dist/core/error.d.ts.map +1 -0
  37. package/dist/core/error.js +25 -0
  38. package/dist/core/error.js.map +1 -0
  39. package/dist/core/error.test.d.ts +2 -0
  40. package/dist/core/error.test.d.ts.map +1 -0
  41. package/dist/core/error.test.js +63 -0
  42. package/dist/core/error.test.js.map +1 -0
  43. package/dist/core/json.d.ts +5 -0
  44. package/dist/core/json.d.ts.map +1 -0
  45. package/dist/core/json.js +3 -0
  46. package/dist/core/json.js.map +1 -0
  47. package/dist/core/result.d.ts +22 -0
  48. package/dist/core/result.d.ts.map +1 -0
  49. package/dist/core/result.js +22 -0
  50. package/dist/core/result.js.map +1 -0
  51. package/dist/core/result.test.d.ts +2 -0
  52. package/dist/core/result.test.d.ts.map +1 -0
  53. package/dist/core/result.test.js +19 -0
  54. package/dist/core/result.test.js.map +1 -0
  55. package/dist/core/retry.d.ts +21 -0
  56. package/dist/core/retry.d.ts.map +1 -0
  57. package/dist/core/retry.js +25 -0
  58. package/dist/core/retry.js.map +1 -0
  59. package/dist/core/retry.test.d.ts +2 -0
  60. package/dist/core/retry.test.d.ts.map +1 -0
  61. package/dist/core/retry.test.js +37 -0
  62. package/dist/core/retry.test.js.map +1 -0
  63. package/dist/core/schema.d.ts +57 -0
  64. package/dist/core/schema.d.ts.map +1 -0
  65. package/dist/core/schema.js +4 -0
  66. package/dist/core/schema.js.map +1 -0
  67. package/dist/core/step.d.ts +96 -0
  68. package/dist/core/step.d.ts.map +1 -0
  69. package/dist/core/step.js +78 -0
  70. package/dist/core/step.js.map +1 -0
  71. package/dist/core/step.test.d.ts +2 -0
  72. package/dist/core/step.test.d.ts.map +1 -0
  73. package/dist/core/step.test.js +356 -0
  74. package/dist/core/step.test.js.map +1 -0
  75. package/dist/core/workflow.d.ts +78 -0
  76. package/dist/core/workflow.d.ts.map +1 -0
  77. package/dist/core/workflow.js +46 -0
  78. package/dist/core/workflow.js.map +1 -0
  79. package/dist/core/workflow.test.d.ts +2 -0
  80. package/dist/core/workflow.test.d.ts.map +1 -0
  81. package/dist/core/workflow.test.js +172 -0
  82. package/dist/core/workflow.test.js.map +1 -0
  83. package/dist/database/backend.d.ts +60 -0
  84. package/dist/database/backend.d.ts.map +1 -0
  85. package/dist/database/backend.js +387 -0
  86. package/dist/database/backend.js.map +1 -0
  87. package/dist/database/backend.test.d.ts +2 -0
  88. package/dist/database/backend.test.d.ts.map +1 -0
  89. package/dist/database/backend.test.js +17 -0
  90. package/dist/database/backend.test.js.map +1 -0
  91. package/dist/database/backend.testsuite.d.ts +20 -0
  92. package/dist/database/backend.testsuite.d.ts.map +1 -0
  93. package/dist/database/backend.testsuite.js +1174 -0
  94. package/dist/database/backend.testsuite.js.map +1 -0
  95. package/dist/database/base.d.ts +12 -0
  96. package/dist/database/base.d.ts.map +1 -0
  97. package/dist/database/base.js +19 -0
  98. package/dist/database/base.js.map +1 -0
  99. package/dist/database/migrations/20251212000000_0_init.js +9 -0
  100. package/dist/database/migrations/20251212000000_0_init.js.map +1 -0
  101. package/dist/database/migrations/20251212000000_1_tables.js +88 -0
  102. package/dist/database/migrations/20251212000000_1_tables.js.map +1 -0
  103. package/dist/database/migrations/20251212000000_2_fk.js +48 -0
  104. package/dist/database/migrations/20251212000000_2_fk.js.map +1 -0
  105. package/dist/database/migrations/20251212000000_3_indexes.js +107 -0
  106. package/dist/database/migrations/20251212000000_3_indexes.js.map +1 -0
  107. package/dist/database/pubsub.d.ts +17 -0
  108. package/dist/database/pubsub.d.ts.map +1 -0
  109. package/dist/database/pubsub.js +70 -0
  110. package/dist/database/pubsub.js.map +1 -0
  111. package/dist/database/pubsub.test.d.ts +2 -0
  112. package/dist/database/pubsub.test.d.ts.map +1 -0
  113. package/dist/database/pubsub.test.js +86 -0
  114. package/dist/database/pubsub.test.js.map +1 -0
  115. package/dist/errors.d.ts +8 -0
  116. package/dist/errors.d.ts.map +1 -0
  117. package/dist/errors.js +21 -0
  118. package/dist/errors.js.map +1 -0
  119. package/dist/execution.d.ts +82 -0
  120. package/dist/execution.d.ts.map +1 -0
  121. package/dist/execution.js +182 -0
  122. package/dist/execution.js.map +1 -0
  123. package/dist/execution.test.d.ts +2 -0
  124. package/dist/execution.test.d.ts.map +1 -0
  125. package/dist/execution.test.js +556 -0
  126. package/dist/execution.test.js.map +1 -0
  127. package/dist/index.d.ts +8 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +6 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/internal.d.ts +12 -0
  132. package/dist/internal.d.ts.map +1 -0
  133. package/dist/internal.js +5 -0
  134. package/dist/internal.js.map +1 -0
  135. package/dist/practices/01-remote-workflow.d.ts +2 -0
  136. package/dist/practices/01-remote-workflow.d.ts.map +1 -0
  137. package/dist/practices/01-remote-workflow.js +69 -0
  138. package/dist/practices/01-remote-workflow.js.map +1 -0
  139. package/dist/practices/01-remote.d.ts +2 -0
  140. package/dist/practices/01-remote.d.ts.map +1 -0
  141. package/dist/practices/01-remote.js +87 -0
  142. package/dist/practices/01-remote.js.map +1 -0
  143. package/dist/practices/02-local.d.ts +2 -0
  144. package/dist/practices/02-local.d.ts.map +1 -0
  145. package/dist/practices/02-local.js +84 -0
  146. package/dist/practices/02-local.js.map +1 -0
  147. package/dist/practices/03-local-retry.d.ts +2 -0
  148. package/dist/practices/03-local-retry.d.ts.map +1 -0
  149. package/dist/practices/03-local-retry.js +85 -0
  150. package/dist/practices/03-local-retry.js.map +1 -0
  151. package/dist/practices/04-scheduler-dispose.d.ts +2 -0
  152. package/dist/practices/04-scheduler-dispose.d.ts.map +1 -0
  153. package/dist/practices/04-scheduler-dispose.js +65 -0
  154. package/dist/practices/04-scheduler-dispose.js.map +1 -0
  155. package/dist/practices/05-router.d.ts +2 -0
  156. package/dist/practices/05-router.d.ts.map +1 -0
  157. package/dist/practices/05-router.js +80 -0
  158. package/dist/practices/05-router.js.map +1 -0
  159. package/dist/registry.d.ts +33 -0
  160. package/dist/registry.d.ts.map +1 -0
  161. package/dist/registry.js +54 -0
  162. package/dist/registry.js.map +1 -0
  163. package/dist/registry.test.d.ts +2 -0
  164. package/dist/registry.test.d.ts.map +1 -0
  165. package/dist/registry.test.js +95 -0
  166. package/dist/registry.test.js.map +1 -0
  167. package/dist/scheduler.d.ts +22 -0
  168. package/dist/scheduler.d.ts.map +1 -0
  169. package/dist/scheduler.js +117 -0
  170. package/dist/scheduler.js.map +1 -0
  171. package/dist/tasks/index.d.ts +4 -0
  172. package/dist/tasks/index.d.ts.map +1 -0
  173. package/dist/tasks/index.js +5 -0
  174. package/dist/tasks/index.js.map +1 -0
  175. package/dist/tasks/local-task.d.ts +6 -0
  176. package/dist/tasks/local-task.d.ts.map +1 -0
  177. package/dist/tasks/local-task.js +95 -0
  178. package/dist/tasks/local-task.js.map +1 -0
  179. package/dist/tasks/remote-task.d.ts +11 -0
  180. package/dist/tasks/remote-task.d.ts.map +1 -0
  181. package/dist/tasks/remote-task.js +213 -0
  182. package/dist/tasks/remote-task.js.map +1 -0
  183. package/dist/tasks/shared.d.ts +8 -0
  184. package/dist/tasks/shared.d.ts.map +1 -0
  185. package/dist/tasks/shared.js +41 -0
  186. package/dist/tasks/shared.js.map +1 -0
  187. package/dist/testing/connection.d.ts +7 -0
  188. package/dist/testing/connection.d.ts.map +1 -0
  189. package/dist/testing/connection.js +38 -0
  190. package/dist/testing/connection.js.map +1 -0
  191. package/dist/types/config.d.ts +44 -0
  192. package/dist/types/config.d.ts.map +1 -0
  193. package/dist/types/config.js +3 -0
  194. package/dist/types/config.js.map +1 -0
  195. package/dist/types/context.d.ts +18 -0
  196. package/dist/types/context.d.ts.map +1 -0
  197. package/dist/types/context.js +4 -0
  198. package/dist/types/context.js.map +1 -0
  199. package/dist/types/events.d.ts +43 -0
  200. package/dist/types/events.d.ts.map +1 -0
  201. package/dist/types/events.js +3 -0
  202. package/dist/types/events.js.map +1 -0
  203. package/dist/types/index.d.ts +6 -0
  204. package/dist/types/index.d.ts.map +1 -0
  205. package/dist/types/index.js +3 -0
  206. package/dist/types/index.js.map +1 -0
  207. package/dist/types/task-items.d.ts +12 -0
  208. package/dist/types/task-items.d.ts.map +1 -0
  209. package/dist/types/task-items.js +3 -0
  210. package/dist/types/task-items.js.map +1 -0
  211. package/dist/types/utils.d.ts +4 -0
  212. package/dist/types/utils.d.ts.map +1 -0
  213. package/dist/types/utils.js +8 -0
  214. package/dist/types/utils.js.map +1 -0
  215. package/dist/worker.d.ts +61 -0
  216. package/dist/worker.d.ts.map +1 -0
  217. package/dist/worker.js +206 -0
  218. package/dist/worker.js.map +1 -0
  219. package/dist/worker.test.d.ts +2 -0
  220. package/dist/worker.test.d.ts.map +1 -0
  221. package/dist/worker.test.js +1163 -0
  222. package/dist/worker.test.js.map +1 -0
  223. package/dist/workflow.d.ts +44 -0
  224. package/dist/workflow.d.ts.map +1 -0
  225. package/dist/workflow.js +21 -0
  226. package/dist/workflow.js.map +1 -0
  227. package/dist/workflow.test.d.ts +2 -0
  228. package/dist/workflow.test.d.ts.map +1 -0
  229. package/dist/workflow.test.js +73 -0
  230. package/dist/workflow.test.js.map +1 -0
  231. package/nodemon.json +6 -0
  232. package/package.json +63 -0
  233. package/scripts/migrate.ts +11 -0
  234. package/src/backend.ts +133 -0
  235. package/src/chaos.test.ts +108 -0
  236. package/src/client.test.ts +297 -0
  237. package/src/client.ts +331 -0
  238. package/src/config.test.ts +23 -0
  239. package/src/config.ts +35 -0
  240. package/src/core/duration.test.ts +326 -0
  241. package/src/core/duration.ts +86 -0
  242. package/src/core/error.test.ts +77 -0
  243. package/src/core/error.ts +30 -0
  244. package/src/core/json.ts +2 -0
  245. package/src/core/result.test.ts +13 -0
  246. package/src/core/result.ts +29 -0
  247. package/src/core/retry.test.ts +41 -0
  248. package/src/core/retry.ts +29 -0
  249. package/src/core/schema.ts +74 -0
  250. package/src/core/step.test.ts +362 -0
  251. package/src/core/step.ts +152 -0
  252. package/src/core/workflow.test.ts +184 -0
  253. package/src/core/workflow.ts +127 -0
  254. package/src/database/backend.test.ts +16 -0
  255. package/src/database/backend.testsuite.ts +1376 -0
  256. package/src/database/backend.ts +655 -0
  257. package/src/database/base.ts +23 -0
  258. package/src/database/migrations/20251212000000_0_init.ts +10 -0
  259. package/src/database/migrations/20251212000000_1_tables.ts +54 -0
  260. package/src/database/migrations/20251212000000_2_fk.ts +46 -0
  261. package/src/database/migrations/20251212000000_3_indexes.ts +82 -0
  262. package/src/database/pubsub.test.ts +92 -0
  263. package/src/database/pubsub.ts +92 -0
  264. package/src/execution.test.ts +508 -0
  265. package/src/execution.ts +291 -0
  266. package/src/index.ts +7 -0
  267. package/src/internal.ts +11 -0
  268. package/src/practices/01-remote-workflow.ts +61 -0
  269. package/src/registry.test.ts +122 -0
  270. package/src/registry.ts +65 -0
  271. package/src/testing/connection.ts +44 -0
  272. package/src/worker.test.ts +1138 -0
  273. package/src/worker.ts +281 -0
  274. package/src/workflow.test.ts +68 -0
  275. package/src/workflow.ts +84 -0
  276. package/table_ddl.sql +60 -0
  277. package/templates/openworkflow.config.ts +22 -0
  278. package/tsconfig.json +40 -0
  279. package/tsconfig.test.json +4 -0
  280. package/vite.config.ts +13 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * A registry for storing and retrieving workflows by name and version.
3
+ * Provides a centralized way to manage workflow registrations.
4
+ */ export class WorkflowRegistry {
5
+ workflows = new Map();
6
+ /**
7
+ * Register a workflow in the registry.
8
+ * @param workflow - The workflow to register
9
+ * @throws {Error} If a workflow with the same name and version is already registered
10
+ */ register(workflow) {
11
+ const name = workflow.spec.name;
12
+ const version = workflow.spec.version ?? null;
13
+ const key = registryKey(name, version);
14
+ if (this.workflows.has(key)) {
15
+ const versionStr = version ? ` (version: ${version})` : "";
16
+ throw new Error(`Workflow "${name}"${versionStr} is already registered`);
17
+ }
18
+ this.workflows.set(key, workflow);
19
+ }
20
+ /**
21
+ * Get a workflow from the registry by name and version.
22
+ * @param name - The workflow name
23
+ * @param version - The workflow version (null for unversioned)
24
+ * @returns The workflow if found, undefined otherwise
25
+ */ get(name, version) {
26
+ const key = registryKey(name, version);
27
+ return this.workflows.get(key);
28
+ }
29
+ /**
30
+ * Get a workflow from the registry by name and version.
31
+ * @param name - The workflow name
32
+ * @param version - The workflow version (null for unversioned)
33
+ * @returns The workflow if found, undefined otherwise
34
+ */ has(name, version) {
35
+ const key = registryKey(name, version);
36
+ return this.workflows.has(key);
37
+ }
38
+ /**
39
+ * Remove a workflow from the registry by name and version.
40
+ */ remove(name, version) {
41
+ const key = registryKey(name, version);
42
+ this.workflows.delete(key);
43
+ }
44
+ }
45
+ /**
46
+ * Build a registry key from name and version.
47
+ * @param name - Workflow name
48
+ * @param version - Workflow version (or null)
49
+ * @returns Registry key
50
+ */ function registryKey(name, version) {
51
+ return version ? `${name}@${version}` : name;
52
+ }
53
+
54
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry.ts"],"sourcesContent":["import type { Workflow } from \"./workflow\";\n\n/**\n * A registry for storing and retrieving workflows by name and version.\n * Provides a centralized way to manage workflow registrations.\n */\nexport class WorkflowRegistry {\n private readonly workflows = new Map<string, Workflow<unknown, unknown, unknown>>();\n\n /**\n * Register a workflow in the registry.\n * @param workflow - The workflow to register\n * @throws {Error} If a workflow with the same name and version is already registered\n */\n register(workflow: Workflow<unknown, unknown, unknown>): void {\n const name = workflow.spec.name;\n const version = workflow.spec.version ?? null;\n const key = registryKey(name, version);\n if (this.workflows.has(key)) {\n const versionStr = version ? ` (version: ${version})` : \"\";\n throw new Error(`Workflow \"${name}\"${versionStr} is already registered`);\n }\n this.workflows.set(key, workflow);\n }\n\n /**\n * Get a workflow from the registry by name and version.\n * @param name - The workflow name\n * @param version - The workflow version (null for unversioned)\n * @returns The workflow if found, undefined otherwise\n */\n get(name: string, version: string | null): Workflow<unknown, unknown, unknown> | undefined {\n const key = registryKey(name, version);\n return this.workflows.get(key);\n }\n\n /**\n * Get a workflow from the registry by name and version.\n * @param name - The workflow name\n * @param version - The workflow version (null for unversioned)\n * @returns The workflow if found, undefined otherwise\n */\n has(name: string, version: string | null): boolean {\n const key = registryKey(name, version);\n return this.workflows.has(key);\n }\n\n /**\n * Remove a workflow from the registry by name and version.\n */\n remove(name: string, version: string | null): void {\n const key = registryKey(name, version);\n this.workflows.delete(key);\n }\n}\n\n/**\n * Build a registry key from name and version.\n * @param name - Workflow name\n * @param version - Workflow version (or null)\n * @returns Registry key\n */\nfunction registryKey(name: string, version: string | null): string {\n return version ? `${name}@${version}` : name;\n}\n"],"names":["WorkflowRegistry","workflows","Map","register","workflow","name","spec","version","key","registryKey","has","versionStr","Error","set","get","remove","delete"],"mappings":"AAEA;;;CAGC,GACD,OAAO,MAAMA;IACMC,YAAY,IAAIC,MAAmD;IAEpF;;;;GAIC,GACDC,SAASC,QAA6C,EAAQ;QAC5D,MAAMC,OAAOD,SAASE,IAAI,CAACD,IAAI;QAC/B,MAAME,UAAUH,SAASE,IAAI,CAACC,OAAO,IAAI;QACzC,MAAMC,MAAMC,YAAYJ,MAAME;QAC9B,IAAI,IAAI,CAACN,SAAS,CAACS,GAAG,CAACF,MAAM;YAC3B,MAAMG,aAAaJ,UAAU,CAAC,WAAW,EAAEA,QAAQ,CAAC,CAAC,GAAG;YACxD,MAAM,IAAIK,MAAM,CAAC,UAAU,EAAEP,KAAK,CAAC,EAAEM,WAAW,sBAAsB,CAAC;QACzE;QACA,IAAI,CAACV,SAAS,CAACY,GAAG,CAACL,KAAKJ;IAC1B;IAEA;;;;;GAKC,GACDU,IAAIT,IAAY,EAAEE,OAAsB,EAAmD;QACzF,MAAMC,MAAMC,YAAYJ,MAAME;QAC9B,OAAO,IAAI,CAACN,SAAS,CAACa,GAAG,CAACN;IAC5B;IAEA;;;;;GAKC,GACDE,IAAIL,IAAY,EAAEE,OAAsB,EAAW;QACjD,MAAMC,MAAMC,YAAYJ,MAAME;QAC9B,OAAO,IAAI,CAACN,SAAS,CAACS,GAAG,CAACF;IAC5B;IAEA;;GAEC,GACDO,OAAOV,IAAY,EAAEE,OAAsB,EAAQ;QACjD,MAAMC,MAAMC,YAAYJ,MAAME;QAC9B,IAAI,CAACN,SAAS,CAACe,MAAM,CAACR;IACxB;AACF;AAEA;;;;;CAKC,GACD,SAASC,YAAYJ,IAAY,EAAEE,OAAsB;IACvD,OAAOA,UAAU,GAAGF,KAAK,CAAC,EAAEE,SAAS,GAAGF;AAC1C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.test.d.ts","sourceRoot":"","sources":["../src/registry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,95 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { WorkflowRegistry } from "./registry.js";
3
+ import { defineWorkflow } from "./workflow.js";
4
+ describe("WorkflowRegistry", ()=>{
5
+ describe("register", ()=>{
6
+ test("registers a workflow without version", ()=>{
7
+ const registry = new WorkflowRegistry();
8
+ const workflow = createMockWorkflow("my-workflow");
9
+ registry.register(workflow);
10
+ expect(registry.get("my-workflow", null)).toBe(workflow);
11
+ });
12
+ test("registers a workflow with version", ()=>{
13
+ const registry = new WorkflowRegistry();
14
+ const workflow = createMockWorkflow("my-workflow", "v1");
15
+ registry.register(workflow);
16
+ expect(registry.get("my-workflow", "v1")).toBe(workflow);
17
+ });
18
+ test("registers multiple versions of the same workflow", ()=>{
19
+ const registry = new WorkflowRegistry();
20
+ const v1 = createMockWorkflow("my-workflow", "v1");
21
+ const v2 = createMockWorkflow("my-workflow", "v2");
22
+ registry.register(v1);
23
+ registry.register(v2);
24
+ expect(registry.get("my-workflow", "v1")).toBe(v1);
25
+ expect(registry.get("my-workflow", "v2")).toBe(v2);
26
+ });
27
+ test("registers different workflows with same version", ()=>{
28
+ const registry = new WorkflowRegistry();
29
+ const workflow1 = createMockWorkflow("workflow-a", "v1");
30
+ const workflow2 = createMockWorkflow("workflow-b", "v1");
31
+ registry.register(workflow1);
32
+ registry.register(workflow2);
33
+ expect(registry.get("workflow-a", "v1")).toBe(workflow1);
34
+ expect(registry.get("workflow-b", "v1")).toBe(workflow2);
35
+ });
36
+ test("throws when registering duplicate unversioned workflow", ()=>{
37
+ const registry = new WorkflowRegistry();
38
+ registry.register(createMockWorkflow("my-workflow"));
39
+ expect(()=>{
40
+ registry.register(createMockWorkflow("my-workflow"));
41
+ }).toThrow('Workflow "my-workflow" is already registered');
42
+ });
43
+ test("throws when registering duplicate versioned workflow", ()=>{
44
+ const registry = new WorkflowRegistry();
45
+ registry.register(createMockWorkflow("my-workflow", "v1"));
46
+ expect(()=>{
47
+ registry.register(createMockWorkflow("my-workflow", "v1"));
48
+ }).toThrow('Workflow "my-workflow" (version: v1) is already registered');
49
+ });
50
+ test("allows same name with different versions", ()=>{
51
+ const registry = new WorkflowRegistry();
52
+ const versioned = createMockWorkflow("my-workflow", "v1");
53
+ const unversioned = createMockWorkflow("my-workflow");
54
+ registry.register(versioned);
55
+ registry.register(unversioned);
56
+ expect(registry.get("my-workflow", "v1")).toBe(versioned);
57
+ expect(registry.get("my-workflow", null)).toBe(unversioned);
58
+ });
59
+ });
60
+ describe("get", ()=>{
61
+ test("returns undefined for non-existent workflow", ()=>{
62
+ const registry = new WorkflowRegistry();
63
+ expect(registry.get("non-existent", null)).toBeUndefined();
64
+ });
65
+ test("returns undefined for wrong version", ()=>{
66
+ const registry = new WorkflowRegistry();
67
+ registry.register(createMockWorkflow("my-workflow", "v1"));
68
+ expect(registry.get("my-workflow", "v2")).toBeUndefined();
69
+ expect(registry.get("my-workflow", null)).toBeUndefined();
70
+ });
71
+ test("returns undefined for versioned lookup on unversioned workflow", ()=>{
72
+ const registry = new WorkflowRegistry();
73
+ registry.register(createMockWorkflow("my-workflow"));
74
+ expect(registry.get("my-workflow", "v1")).toBeUndefined();
75
+ });
76
+ test("returns the registered workflow", ()=>{
77
+ const registry = new WorkflowRegistry();
78
+ const workflow = createMockWorkflow("my-workflow");
79
+ registry.register(workflow);
80
+ expect(registry.get("my-workflow", null)).toBe(workflow);
81
+ });
82
+ });
83
+ });
84
+ function createMockWorkflow(name, version) {
85
+ return defineWorkflow({
86
+ name,
87
+ ...version && {
88
+ version
89
+ }
90
+ }, async ()=>{
91
+ // no-op
92
+ });
93
+ }
94
+
95
+ //# sourceMappingURL=registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry.test.ts"],"sourcesContent":["import { describe, expect, test } from \"vitest\";\nimport { WorkflowRegistry } from \"./registry\";\nimport { defineWorkflow } from \"./workflow\";\n\ndescribe(\"WorkflowRegistry\", () => {\n describe(\"register\", () => {\n test(\"registers a workflow without version\", () => {\n const registry = new WorkflowRegistry();\n const workflow = createMockWorkflow(\"my-workflow\");\n\n registry.register(workflow);\n\n expect(registry.get(\"my-workflow\", null)).toBe(workflow);\n });\n\n test(\"registers a workflow with version\", () => {\n const registry = new WorkflowRegistry();\n const workflow = createMockWorkflow(\"my-workflow\", \"v1\");\n\n registry.register(workflow);\n\n expect(registry.get(\"my-workflow\", \"v1\")).toBe(workflow);\n });\n\n test(\"registers multiple versions of the same workflow\", () => {\n const registry = new WorkflowRegistry();\n const v1 = createMockWorkflow(\"my-workflow\", \"v1\");\n const v2 = createMockWorkflow(\"my-workflow\", \"v2\");\n\n registry.register(v1);\n registry.register(v2);\n\n expect(registry.get(\"my-workflow\", \"v1\")).toBe(v1);\n expect(registry.get(\"my-workflow\", \"v2\")).toBe(v2);\n });\n\n test(\"registers different workflows with same version\", () => {\n const registry = new WorkflowRegistry();\n const workflow1 = createMockWorkflow(\"workflow-a\", \"v1\");\n const workflow2 = createMockWorkflow(\"workflow-b\", \"v1\");\n\n registry.register(workflow1);\n registry.register(workflow2);\n\n expect(registry.get(\"workflow-a\", \"v1\")).toBe(workflow1);\n expect(registry.get(\"workflow-b\", \"v1\")).toBe(workflow2);\n });\n\n test(\"throws when registering duplicate unversioned workflow\", () => {\n const registry = new WorkflowRegistry();\n registry.register(createMockWorkflow(\"my-workflow\"));\n\n expect(() => {\n registry.register(createMockWorkflow(\"my-workflow\"));\n }).toThrow('Workflow \"my-workflow\" is already registered');\n });\n\n test(\"throws when registering duplicate versioned workflow\", () => {\n const registry = new WorkflowRegistry();\n registry.register(createMockWorkflow(\"my-workflow\", \"v1\"));\n\n expect(() => {\n registry.register(createMockWorkflow(\"my-workflow\", \"v1\"));\n }).toThrow('Workflow \"my-workflow\" (version: v1) is already registered');\n });\n\n test(\"allows same name with different versions\", () => {\n const registry = new WorkflowRegistry();\n const versioned = createMockWorkflow(\"my-workflow\", \"v1\");\n const unversioned = createMockWorkflow(\"my-workflow\");\n\n registry.register(versioned);\n registry.register(unversioned);\n\n expect(registry.get(\"my-workflow\", \"v1\")).toBe(versioned);\n expect(registry.get(\"my-workflow\", null)).toBe(unversioned);\n });\n });\n\n describe(\"get\", () => {\n test(\"returns undefined for non-existent workflow\", () => {\n const registry = new WorkflowRegistry();\n\n expect(registry.get(\"non-existent\", null)).toBeUndefined();\n });\n\n test(\"returns undefined for wrong version\", () => {\n const registry = new WorkflowRegistry();\n registry.register(createMockWorkflow(\"my-workflow\", \"v1\"));\n\n expect(registry.get(\"my-workflow\", \"v2\")).toBeUndefined();\n expect(registry.get(\"my-workflow\", null)).toBeUndefined();\n });\n\n test(\"returns undefined for versioned lookup on unversioned workflow\", () => {\n const registry = new WorkflowRegistry();\n registry.register(createMockWorkflow(\"my-workflow\"));\n\n expect(registry.get(\"my-workflow\", \"v1\")).toBeUndefined();\n });\n\n test(\"returns the registered workflow\", () => {\n const registry = new WorkflowRegistry();\n const workflow = createMockWorkflow(\"my-workflow\");\n registry.register(workflow);\n\n expect(registry.get(\"my-workflow\", null)).toBe(workflow);\n });\n });\n});\n\nfunction createMockWorkflow(name: string, version?: string) {\n return defineWorkflow(\n {\n name,\n ...(version && { version }),\n },\n async () => {\n // no-op\n },\n );\n}\n"],"names":["describe","expect","test","WorkflowRegistry","defineWorkflow","registry","workflow","createMockWorkflow","register","get","toBe","v1","v2","workflow1","workflow2","toThrow","versioned","unversioned","toBeUndefined","name","version"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type Knex } from "knex";
2
+ import { type RouterContext } from "rou3";
3
+ import { type EventType, type LocalTaskConfig, type SchedulerInfo, type OnEventFunction, type RemoteTaskConfig, type Resolvable, type RetryConfig, type SchedulerConfig, type TaskRouterContext } from "./types";
4
+ export declare class SonamuScheduler {
5
+ #private;
6
+ readonly info: SchedulerInfo;
7
+ constructor(knex: Knex, router: RouterContext<TaskRouterContext & {
8
+ info: SchedulerInfo;
9
+ }>, info: SchedulerInfo, retry?: RetryConfig);
10
+ [Symbol.asyncDispose](): Promise<void>;
11
+ addRoute(...routes: (Omit<TaskRouterContext, "retry"> & {
12
+ retry?: RetryConfig;
13
+ })[]): void;
14
+ addTask(...tasks: (RemoteTaskConfig | LocalTaskConfig)[]): void;
15
+ start(): void;
16
+ stop(): void;
17
+ dispose(): Promise<void>;
18
+ on(name: EventType | "*", fn: OnEventFunction): void;
19
+ off(name: EventType | "*", fn: OnEventFunction): void;
20
+ }
21
+ export declare function createScheduler(input: Resolvable<SchedulerConfig>): Promise<SonamuScheduler>;
22
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AACA,OAAa,EAAE,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAEvC,OAAO,EAAE,KAAK,aAAa,EAA0B,MAAM,MAAM,CAAC;AAGlE,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,SAAS,CAAC;AAGjB,qBAAa,eAAe;;IAQ1B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;gBAG3B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,CAAC,iBAAiB,GAAG;QAAE,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC,EAClE,IAAI,EAAE,aAAa,EACnB,KAAK,CAAC,EAAE,WAAW;IAWf,CAAC,MAAM,CAAC,YAAY,CAAC;IAI3B,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC,EAAE;IAclF,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC,gBAAgB,GAAG,eAAe,CAAC,EAAE;IA2BxD,KAAK;IASL,IAAI;IASE,OAAO;IAcb,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE,EAAE,EAAE,eAAe;IAM7C,GAAG,CAAC,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE,EAAE,EAAE,eAAe;CAW/C;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GACjC,OAAO,CAAC,eAAe,CAAC,CAY1B"}
@@ -0,0 +1,117 @@
1
+ import EventEmitter from "events";
2
+ import knex from "knex";
3
+ import { createTask } from "node-cron";
4
+ import { addRoute, createRouter } from "rou3";
5
+ import { v7 } from "uuid";
6
+ import { wrapRemoteTask, wrapLocalTask } from "./tasks/index.js";
7
+ import { resolve } from "./types/index.js";
8
+ // 태스크를 관리하는 Scheduler
9
+ export class SonamuScheduler {
10
+ #status = "stopped";
11
+ #event;
12
+ #knex;
13
+ #retry;
14
+ #router;
15
+ #tasks;
16
+ info;
17
+ constructor(knex, router, info, retry){
18
+ this.#event = new EventEmitter();
19
+ this.#knex = knex;
20
+ this.#retry = retry;
21
+ this.#router = router;
22
+ this.#tasks = [];
23
+ this.info = info;
24
+ }
25
+ // async disposable 처리를 위함
26
+ async [Symbol.asyncDispose]() {
27
+ return this.dispose();
28
+ }
29
+ addRoute(...routes) {
30
+ for (const route of routes){
31
+ addRoute(this.#router, "", route.path, {
32
+ ...route,
33
+ info: this.info,
34
+ // route의 기본 설정 -> 글로벌 설정 -> 없을 경우 재시도는 안 함.
35
+ retry: {
36
+ delay: route.retry?.delay ?? this.#retry?.delay,
37
+ maxAttempts: route.retry?.maxAttempts ?? this.#retry?.maxAttempts ?? 1
38
+ }
39
+ });
40
+ }
41
+ }
42
+ addTask(...tasks) {
43
+ for (const task of tasks){
44
+ const onEvent = this.#emit.bind(this);
45
+ // remote냐 local이냐에 따라서 인자가 달라짐.
46
+ const func = task.type === "remote" ? wrapRemoteTask.bind(this, this.#router, this.info, onEvent, this.#knex) : wrapLocalTask.bind(this, this.#router, this.info, onEvent, {
47
+ id: v7(),
48
+ createdAt: new Date(),
49
+ updatedAt: new Date(),
50
+ status: "pending",
51
+ namespace: task.namespace,
52
+ attempt: 1,
53
+ payload: task.payload
54
+ });
55
+ const cronTask = createTask(task.expression, func, task.options);
56
+ this.#tasks.push(cronTask);
57
+ // Scheduler가 실행 상태일 때 task가 추가되면 Task도 같이 실행함
58
+ if (this.#status === "running") {
59
+ cronTask.start();
60
+ }
61
+ }
62
+ }
63
+ start() {
64
+ this.#status = "running";
65
+ for (const task of this.#tasks){
66
+ if (task.getStatus() === "stopped") {
67
+ task.start();
68
+ }
69
+ }
70
+ }
71
+ stop() {
72
+ this.#status = "stopped";
73
+ for (const task of this.#tasks){
74
+ if (task.getStatus() !== "stopped") {
75
+ task.stop();
76
+ }
77
+ }
78
+ }
79
+ async dispose() {
80
+ if (this.#status === "disposed") return;
81
+ this.#status = "disposed";
82
+ this.#event.removeAllListeners();
83
+ await this.#knex.destroy();
84
+ for (const task of this.#tasks){
85
+ task.stop();
86
+ await task.destroy();
87
+ }
88
+ }
89
+ // *를 넣으면 모든 이벤트에 대응함
90
+ on(name, fn) {
91
+ if (this.#status === "disposed") return;
92
+ this.#event.on(name, fn);
93
+ }
94
+ // *를 넣으면 모든 이벤트에 대응함
95
+ off(name, fn) {
96
+ if (this.#status === "disposed") return;
97
+ this.#event.off(name, fn);
98
+ }
99
+ // 내부 wrapLocalTask/wrapRemoteTask를 실행할 때 전달되는 event callback
100
+ #emit(evt) {
101
+ if (this.#status === "disposed") return;
102
+ this.#event.emit("*", evt);
103
+ this.#event.emit(evt.type, evt);
104
+ }
105
+ }
106
+ export async function createScheduler(input) {
107
+ const config = await resolve(input);
108
+ const scheduler = new SonamuScheduler(knex(config.database), createRouter(), {
109
+ id: v7(),
110
+ name: config.name
111
+ }, config.retry);
112
+ scheduler.addRoute(...config.routes);
113
+ scheduler.addTask(...config.tasks);
114
+ return scheduler;
115
+ }
116
+
117
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scheduler.ts"],"sourcesContent":["import EventEmitter from \"events\";\nimport knex, { type Knex } from \"knex\";\nimport { createTask, type ScheduledTask } from \"node-cron\";\nimport { type RouterContext, addRoute, createRouter } from \"rou3\";\nimport { v7 } from \"uuid\";\nimport { wrapRemoteTask, wrapLocalTask } from \"./tasks\";\nimport {\n resolve,\n type EventType,\n type LocalTaskConfig,\n type SchedulerInfo,\n type OnEventFunction,\n type RemoteTaskConfig,\n type Resolvable,\n type RetryConfig,\n type TaskEvent,\n type SchedulerConfig,\n type TaskRouterContext,\n} from \"./types\";\n\n// 태스크를 관리하는 Scheduler\nexport class SonamuScheduler {\n #status: \"running\" | \"stopped\" | \"disposed\" = \"stopped\";\n\n readonly #event: EventEmitter;\n readonly #knex: Knex;\n readonly #retry?: RetryConfig;\n readonly #router: RouterContext<TaskRouterContext & { info: SchedulerInfo }>;\n readonly #tasks: ScheduledTask[];\n readonly info: SchedulerInfo;\n\n constructor(\n knex: Knex,\n router: RouterContext<TaskRouterContext & { info: SchedulerInfo }>,\n info: SchedulerInfo,\n retry?: RetryConfig,\n ) {\n this.#event = new EventEmitter();\n this.#knex = knex;\n this.#retry = retry;\n this.#router = router;\n this.#tasks = [];\n this.info = info;\n }\n\n // async disposable 처리를 위함\n async [Symbol.asyncDispose]() {\n return this.dispose();\n }\n\n addRoute(...routes: (Omit<TaskRouterContext, \"retry\"> & { retry?: RetryConfig })[]) {\n for (const route of routes) {\n addRoute(this.#router, \"\", route.path, {\n ...route,\n info: this.info,\n // route의 기본 설정 -> 글로벌 설정 -> 없을 경우 재시도는 안 함.\n retry: {\n delay: route.retry?.delay ?? this.#retry?.delay,\n maxAttempts: route.retry?.maxAttempts ?? this.#retry?.maxAttempts ?? 1,\n },\n });\n }\n }\n\n addTask(...tasks: (RemoteTaskConfig | LocalTaskConfig)[]) {\n for (const task of tasks) {\n const onEvent = this.#emit.bind(this);\n // remote냐 local이냐에 따라서 인자가 달라짐.\n const func =\n task.type === \"remote\"\n ? wrapRemoteTask.bind(this, this.#router, this.info, onEvent, this.#knex)\n : wrapLocalTask.bind(this, this.#router, this.info, onEvent, {\n id: v7(),\n createdAt: new Date(),\n updatedAt: new Date(),\n status: \"pending\",\n namespace: task.namespace,\n attempt: 1,\n payload: task.payload,\n });\n\n const cronTask = createTask(task.expression, func, task.options);\n this.#tasks.push(cronTask);\n\n // Scheduler가 실행 상태일 때 task가 추가되면 Task도 같이 실행함\n if (this.#status === \"running\") {\n cronTask.start();\n }\n }\n }\n\n start() {\n this.#status = \"running\";\n for (const task of this.#tasks) {\n if (task.getStatus() === \"stopped\") {\n task.start();\n }\n }\n }\n\n stop() {\n this.#status = \"stopped\";\n for (const task of this.#tasks) {\n if (task.getStatus() !== \"stopped\") {\n task.stop();\n }\n }\n }\n\n async dispose() {\n if (this.#status === \"disposed\") return;\n\n this.#status = \"disposed\";\n this.#event.removeAllListeners();\n await this.#knex.destroy();\n\n for (const task of this.#tasks) {\n task.stop();\n await task.destroy();\n }\n }\n\n // *를 넣으면 모든 이벤트에 대응함\n on(name: EventType | \"*\", fn: OnEventFunction) {\n if (this.#status === \"disposed\") return;\n this.#event.on(name, fn);\n }\n\n // *를 넣으면 모든 이벤트에 대응함\n off(name: EventType | \"*\", fn: OnEventFunction) {\n if (this.#status === \"disposed\") return;\n this.#event.off(name, fn);\n }\n\n // 내부 wrapLocalTask/wrapRemoteTask를 실행할 때 전달되는 event callback\n #emit(evt: TaskEvent) {\n if (this.#status === \"disposed\") return;\n this.#event.emit(\"*\", evt);\n this.#event.emit(evt.type, evt);\n }\n}\n\nexport async function createScheduler(\n input: Resolvable<SchedulerConfig>,\n): Promise<SonamuScheduler> {\n const config = await resolve(input);\n const scheduler = new SonamuScheduler(\n knex(config.database),\n createRouter(),\n { id: v7(), name: config.name },\n config.retry,\n );\n\n scheduler.addRoute(...config.routes);\n scheduler.addTask(...config.tasks);\n return scheduler;\n}\n"],"names":["EventEmitter","knex","createTask","addRoute","createRouter","v7","wrapRemoteTask","wrapLocalTask","resolve","SonamuScheduler","info","router","retry","Symbol","asyncDispose","dispose","routes","route","path","delay","maxAttempts","addTask","tasks","task","onEvent","bind","func","type","id","createdAt","Date","updatedAt","status","namespace","attempt","payload","cronTask","expression","options","push","start","getStatus","stop","removeAllListeners","destroy","on","name","fn","off","evt","emit","createScheduler","input","config","scheduler","database"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from "./local-task";
2
+ export * from "./remote-task";
3
+ export * from "./shared";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tasks/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from "./local-task.js";
2
+ export * from "./remote-task.js";
3
+ export * from "./shared.js";
4
+
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tasks/index.ts"],"sourcesContent":["export * from \"./local-task\";\nexport * from \"./remote-task\";\nexport * from \"./shared\";\n"],"names":[],"mappings":"AAAA,cAAc,kBAAe;AAC7B,cAAc,mBAAgB;AAC9B,cAAc,cAAW"}
@@ -0,0 +1,6 @@
1
+ import { type RouterContext } from "rou3";
2
+ import type { SchedulerInfo, TaskEvent, TaskItem, TaskRouterContext } from "../types";
3
+ export declare function wrapLocalTask(router: RouterContext<TaskRouterContext & {
4
+ info: SchedulerInfo;
5
+ }>, info: SchedulerInfo, onEvent: (data: TaskEvent) => void, item: TaskItem): Promise<void>;
6
+ //# sourceMappingURL=local-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-task.d.ts","sourceRoot":"","sources":["../../src/tasks/local-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAErD,OAAO,KAAK,EACV,aAAa,EAGb,SAAS,EACT,QAAQ,EACR,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAoClB,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,CAAC,iBAAiB,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAClE,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,EAClC,IAAI,EAAE,QAAQ,iBA0Ef"}
@@ -0,0 +1,95 @@
1
+ import { findRoute } from "rou3";
2
+ import { isSonamuTaskError } from "../errors.js";
3
+ import { routedAction } from "./shared.js";
4
+ // Local 실행일 떄 Retry 설정에서 duration을 체크하는 법.
5
+ function getDuration(attempt, delay) {
6
+ // duration이 함수일 경우, 시도 횟수를 넣어서 계산
7
+ if (delay instanceof Function) {
8
+ return delay(attempt);
9
+ }
10
+ return delay ?? {
11
+ minutes: 1
12
+ };
13
+ }
14
+ // date를 기점으로 duration을 계산해서 ms로 변환.
15
+ function calculateToMs(duration) {
16
+ const MS_PER_SECOND = 1000;
17
+ const MS_PER_MINUTE = 60 * MS_PER_SECOND;
18
+ const MS_PER_HOUR = 60 * MS_PER_MINUTE;
19
+ const MS_PER_DAY = 24 * MS_PER_HOUR;
20
+ const MS_PER_WEEK = 7 * MS_PER_DAY;
21
+ const MS_PER_MONTH = 30 * MS_PER_DAY;
22
+ const MS_PER_YEAR = 365 * MS_PER_DAY;
23
+ return (duration.years ?? 0) * MS_PER_YEAR + (duration.months ?? 0) * MS_PER_MONTH + (duration.weeks ?? 0) * MS_PER_WEEK + (duration.days ?? 0) * MS_PER_DAY + (duration.hours ?? 0) * MS_PER_HOUR + (duration.minutes ?? 0) * MS_PER_MINUTE + (duration.seconds ?? 0) * MS_PER_SECOND;
24
+ }
25
+ // Scheduler에서 Local Task가 돌아갈 때 실행되는 부분
26
+ export async function wrapLocalTask(router, info, onEvent, item) {
27
+ // Router에서 Route를 찾아서
28
+ const matched = findRoute(router, "", item.namespace);
29
+ if (!matched) {
30
+ onEvent({
31
+ type: "process:error",
32
+ task: item,
33
+ timestamp: new Date(),
34
+ info: info,
35
+ reason: "no_route"
36
+ });
37
+ return;
38
+ }
39
+ // 재시도 처리를 함
40
+ while(item.attempt <= matched.data.retry.maxAttempts){
41
+ try {
42
+ await routedAction(matched, item);
43
+ await (async ()=>{
44
+ const event = {
45
+ type: "process:complete",
46
+ task: item,
47
+ timestamp: new Date(),
48
+ info: matched.data.info
49
+ };
50
+ onEvent(event);
51
+ })();
52
+ return;
53
+ } catch (err) {
54
+ let evt;
55
+ if (isSonamuTaskError(err)) {
56
+ evt = {
57
+ type: "process:error",
58
+ task: item,
59
+ timestamp: new Date(),
60
+ info: matched.data.info,
61
+ reason: err.type,
62
+ error: err.cause ?? err
63
+ };
64
+ } else if (err instanceof Error) {
65
+ evt = {
66
+ type: "process:error",
67
+ task: item,
68
+ timestamp: new Date(),
69
+ info: matched.data.info,
70
+ reason: "exception",
71
+ error: err
72
+ };
73
+ } else {
74
+ evt = {
75
+ type: "process:error",
76
+ task: item,
77
+ timestamp: new Date(),
78
+ info: matched.data.info,
79
+ reason: "exception",
80
+ error: new Error(`Unknown Error: ${err}`)
81
+ };
82
+ }
83
+ onEvent(evt);
84
+ if (item.attempt < matched.data.retry.maxAttempts) {
85
+ await new Promise((resolve)=>setTimeout(resolve, calculateToMs(getDuration(item.attempt, matched.data.retry.delay))));
86
+ }
87
+ item = {
88
+ ...item,
89
+ attempt: item.attempt + 1
90
+ };
91
+ }
92
+ }
93
+ }
94
+
95
+ //# sourceMappingURL=local-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tasks/local-task.ts"],"sourcesContent":["import { findRoute, type RouterContext } from \"rou3\";\nimport { isSonamuTaskError } from \"../errors\";\nimport type {\n SchedulerInfo,\n RetryConfig,\n RoutedTaskEvent,\n TaskEvent,\n TaskItem,\n TaskRouterContext,\n} from \"../types\";\nimport { routedAction } from \"./shared\";\nimport type { Duration } from \"date-fns\";\n\n// Local 실행일 떄 Retry 설정에서 duration을 체크하는 법.\nfunction getDuration(attempt: number, delay: RetryConfig[\"delay\"]): Duration {\n // duration이 함수일 경우, 시도 횟수를 넣어서 계산\n if (delay instanceof Function) {\n return delay(attempt);\n }\n\n return delay ?? { minutes: 1 };\n}\n\n// date를 기점으로 duration을 계산해서 ms로 변환.\nfunction calculateToMs(duration: Duration): number {\n const MS_PER_SECOND = 1000;\n const MS_PER_MINUTE = 60 * MS_PER_SECOND;\n const MS_PER_HOUR = 60 * MS_PER_MINUTE;\n const MS_PER_DAY = 24 * MS_PER_HOUR;\n const MS_PER_WEEK = 7 * MS_PER_DAY;\n const MS_PER_MONTH = 30 * MS_PER_DAY;\n const MS_PER_YEAR = 365 * MS_PER_DAY;\n\n return (\n (duration.years ?? 0) * MS_PER_YEAR +\n (duration.months ?? 0) * MS_PER_MONTH +\n (duration.weeks ?? 0) * MS_PER_WEEK +\n (duration.days ?? 0) * MS_PER_DAY +\n (duration.hours ?? 0) * MS_PER_HOUR +\n (duration.minutes ?? 0) * MS_PER_MINUTE +\n (duration.seconds ?? 0) * MS_PER_SECOND\n );\n}\n\n// Scheduler에서 Local Task가 돌아갈 때 실행되는 부분\nexport async function wrapLocalTask(\n router: RouterContext<TaskRouterContext & { info: SchedulerInfo }>,\n info: SchedulerInfo,\n onEvent: (data: TaskEvent) => void,\n item: TaskItem,\n) {\n // Router에서 Route를 찾아서\n const matched = findRoute(router, \"\", item.namespace);\n if (!matched) {\n onEvent({\n type: \"process:error\",\n task: item,\n timestamp: new Date(),\n info: info,\n reason: \"no_route\",\n });\n return;\n }\n\n // 재시도 처리를 함\n while (item.attempt <= matched.data.retry.maxAttempts) {\n try {\n await routedAction(matched, item);\n await (async () => {\n const event: RoutedTaskEvent = {\n type: \"process:complete\",\n task: item,\n timestamp: new Date(),\n info: matched.data.info,\n };\n\n onEvent(event);\n })();\n return;\n } catch (err) {\n let evt: RoutedTaskEvent;\n if (isSonamuTaskError(err)) {\n evt = {\n type: \"process:error\",\n task: item,\n timestamp: new Date(),\n info: matched.data.info,\n reason: err.type,\n error: err.cause ?? err,\n };\n } else if (err instanceof Error) {\n evt = {\n type: \"process:error\",\n task: item,\n timestamp: new Date(),\n info: matched.data.info,\n reason: \"exception\",\n error: err,\n };\n } else {\n evt = {\n type: \"process:error\",\n task: item,\n timestamp: new Date(),\n info: matched.data.info,\n reason: \"exception\",\n error: new Error(`Unknown Error: ${err}`),\n };\n }\n onEvent(evt);\n\n if (item.attempt < matched.data.retry.maxAttempts) {\n await new Promise((resolve) =>\n setTimeout(resolve, calculateToMs(getDuration(item.attempt, matched.data.retry.delay))),\n );\n }\n\n item = {\n ...item,\n attempt: item.attempt + 1,\n };\n }\n }\n}\n"],"names":["findRoute","isSonamuTaskError","routedAction","getDuration","attempt","delay","Function","minutes","calculateToMs","duration","MS_PER_SECOND","MS_PER_MINUTE","MS_PER_HOUR","MS_PER_DAY","MS_PER_WEEK","MS_PER_MONTH","MS_PER_YEAR","years","months","weeks","days","hours","seconds","wrapLocalTask","router","info","onEvent","item","matched","namespace","type","task","timestamp","Date","reason","data","retry","maxAttempts","event","err","evt","error","cause","Error","Promise","resolve","setTimeout"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Knex } from "knex";
2
+ import type { SchedulerInfo, UnroutedTaskEvent, RoutedTaskEvent, TaskRouterContext, TaskEvent } from "../types";
3
+ import { type RouterContext } from "rou3";
4
+ export declare function saveUnroutedTaskEvent(knex: Knex, data: UnroutedTaskEvent): Promise<number[]>;
5
+ export declare function saveRoutedTaskEvent<T extends RoutedTaskEvent>(knex: Knex, router: RouterContext<TaskRouterContext & {
6
+ info: SchedulerInfo;
7
+ }>, data: T): Promise<void>;
8
+ export declare function wrapRemoteTask(router: RouterContext<TaskRouterContext & {
9
+ info: SchedulerInfo;
10
+ }>, info: SchedulerInfo, onEvent: (data: TaskEvent) => void, knex: Knex): Promise<void>;
11
+ //# sourceMappingURL=remote-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-task.d.ts","sourceRoot":"","sources":["../../src/tasks/remote-task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EACV,aAAa,EAEb,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,SAAS,EACV,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,MAAM,CAAC;AAKrD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,qBAoC9E;AAGD,wBAAsB,mBAAmB,CAAC,CAAC,SAAS,eAAe,EACjE,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,CAAC,iBAAiB,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAClE,IAAI,EAAE,CAAC,iBA0GR;AAID,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,CAAC,iBAAiB,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAClE,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,EAClC,IAAI,EAAE,IAAI,iBAsHX"}