@happyvertical/smrt-jobs 0.30.0

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 (92) hide show
  1. package/AGENTS.md +71 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +151 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/background-policy.d.ts +121 -0
  8. package/dist/background-policy.d.ts.map +1 -0
  9. package/dist/chunks/runner-DV8FBO0y.js +1642 -0
  10. package/dist/chunks/runner-DV8FBO0y.js.map +1 -0
  11. package/dist/chunks/worker-liveness-DOTjoIjr.js +65 -0
  12. package/dist/chunks/worker-liveness-DOTjoIjr.js.map +1 -0
  13. package/dist/error-redaction.d.ts +48 -0
  14. package/dist/error-redaction.d.ts.map +1 -0
  15. package/dist/index.d.ts +13 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +926 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/job-builder.d.ts +94 -0
  20. package/dist/job-builder.d.ts.map +1 -0
  21. package/dist/job-handle.d.ts +71 -0
  22. package/dist/job-handle.d.ts.map +1 -0
  23. package/dist/logger-extension.d.ts +58 -0
  24. package/dist/logger-extension.d.ts.map +1 -0
  25. package/dist/manifest.json +1327 -0
  26. package/dist/object-extension.d.ts +68 -0
  27. package/dist/object-extension.d.ts.map +1 -0
  28. package/dist/playground.d.ts +2 -0
  29. package/dist/playground.d.ts.map +1 -0
  30. package/dist/playground.js +179 -0
  31. package/dist/playground.js.map +1 -0
  32. package/dist/runner.d.ts +189 -0
  33. package/dist/runner.d.ts.map +1 -0
  34. package/dist/runner.js +15 -0
  35. package/dist/runner.js.map +1 -0
  36. package/dist/schedule-runner.d.ts +151 -0
  37. package/dist/schedule-runner.d.ts.map +1 -0
  38. package/dist/smrt-job-event.d.ts +54 -0
  39. package/dist/smrt-job-event.d.ts.map +1 -0
  40. package/dist/smrt-job.d.ts +215 -0
  41. package/dist/smrt-job.d.ts.map +1 -0
  42. package/dist/smrt-knowledge.json +508 -0
  43. package/dist/smrt-worker.d.ts +72 -0
  44. package/dist/smrt-worker.d.ts.map +1 -0
  45. package/dist/stale-recovery.d.ts +34 -0
  46. package/dist/stale-recovery.d.ts.map +1 -0
  47. package/dist/svelte/components/JobActions.svelte +103 -0
  48. package/dist/svelte/components/JobActions.svelte.d.ts +23 -0
  49. package/dist/svelte/components/JobActions.svelte.d.ts.map +1 -0
  50. package/dist/svelte/components/JobDashboard.svelte +199 -0
  51. package/dist/svelte/components/JobDashboard.svelte.d.ts +27 -0
  52. package/dist/svelte/components/JobDashboard.svelte.d.ts.map +1 -0
  53. package/dist/svelte/components/JobDetail.svelte +256 -0
  54. package/dist/svelte/components/JobDetail.svelte.d.ts +17 -0
  55. package/dist/svelte/components/JobDetail.svelte.d.ts.map +1 -0
  56. package/dist/svelte/components/JobList.svelte +360 -0
  57. package/dist/svelte/components/JobList.svelte.d.ts +28 -0
  58. package/dist/svelte/components/JobList.svelte.d.ts.map +1 -0
  59. package/dist/svelte/components/JobStats.svelte +242 -0
  60. package/dist/svelte/components/JobStats.svelte.d.ts +15 -0
  61. package/dist/svelte/components/JobStats.svelte.d.ts.map +1 -0
  62. package/dist/svelte/components/JobStatusBadge.svelte +23 -0
  63. package/dist/svelte/components/JobStatusBadge.svelte.d.ts +9 -0
  64. package/dist/svelte/components/JobStatusBadge.svelte.d.ts.map +1 -0
  65. package/dist/svelte/components/types.d.ts +9 -0
  66. package/dist/svelte/components/types.d.ts.map +1 -0
  67. package/dist/svelte/components/types.js +8 -0
  68. package/dist/svelte/i18n.d.ts +22 -0
  69. package/dist/svelte/i18n.d.ts.map +1 -0
  70. package/dist/svelte/i18n.js +22 -0
  71. package/dist/svelte/index.d.ts +25 -0
  72. package/dist/svelte/index.d.ts.map +1 -0
  73. package/dist/svelte/index.js +28 -0
  74. package/dist/svelte/playground.d.ts +329 -0
  75. package/dist/svelte/playground.d.ts.map +1 -0
  76. package/dist/svelte/playground.js +174 -0
  77. package/dist/svelte/types.d.ts +191 -0
  78. package/dist/svelte/types.d.ts.map +1 -0
  79. package/dist/svelte/types.js +87 -0
  80. package/dist/ui.d.ts +10 -0
  81. package/dist/ui.d.ts.map +1 -0
  82. package/dist/ui.js +69 -0
  83. package/dist/ui.js.map +1 -0
  84. package/dist/worker-liveness-thread.d.ts +2 -0
  85. package/dist/worker-liveness-thread.d.ts.map +1 -0
  86. package/dist/worker-liveness-thread.js +66 -0
  87. package/dist/worker-liveness-thread.js.map +1 -0
  88. package/dist/worker-liveness-ticker.d.ts +30 -0
  89. package/dist/worker-liveness-ticker.d.ts.map +1 -0
  90. package/dist/worker-liveness.d.ts +71 -0
  91. package/dist/worker-liveness.d.ts.map +1 -0
  92. package/package.json +93 -0
@@ -0,0 +1,68 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { JobBuilder } from './job-builder.js';
3
+ import { JobHandle } from './job-handle.js';
4
+ /**
5
+ * Options for the simple .bg() method
6
+ */
7
+ export interface BgOptions {
8
+ /** Queue name */
9
+ queue?: string;
10
+ /** Priority level */
11
+ priority?: 'critical' | 'high' | 'normal' | 'low' | number;
12
+ /** Delay before running (ms or string like '5m') */
13
+ delay?: string | number;
14
+ /** Maximum retries */
15
+ retries?: number;
16
+ /** Timeout in milliseconds */
17
+ timeout?: number;
18
+ }
19
+ /**
20
+ * Type for the extended SmrtObject with background job methods
21
+ */
22
+ export interface BackgroundCapable {
23
+ /**
24
+ * Simple background job submission
25
+ *
26
+ * @param method - Method name to invoke
27
+ * @param args - Arguments to pass to the method
28
+ * @param options - Job options
29
+ * @returns JobHandle for tracking the job
30
+ *
31
+ * @example
32
+ * const handle = await doc.bg('generateSummary', { format: 'md' });
33
+ */
34
+ bg<T = unknown>(method: string, args?: Record<string, unknown>, options?: BgOptions): Promise<JobHandle<T>>;
35
+ /**
36
+ * Fluent job builder for advanced options
37
+ *
38
+ * @param method - Method name to invoke
39
+ * @param args - Arguments to pass to the method
40
+ * @returns JobBuilder for fluent configuration
41
+ *
42
+ * @example
43
+ * const handle = await doc.background('generateSummary', { format: 'md' })
44
+ * .delay('5m')
45
+ * .retries(5)
46
+ * .priority('high')
47
+ * .enqueue();
48
+ */
49
+ background<T = unknown>(method: string, args?: Record<string, unknown>): JobBuilder<T>;
50
+ }
51
+ type SmrtObjectConstructor = new (...args: any[]) => SmrtObject;
52
+ type BackgroundCapableConstructor<T extends SmrtObjectConstructor> = T & {
53
+ new (...args: ConstructorParameters<T>): InstanceType<T> & BackgroundCapable;
54
+ };
55
+ /**
56
+ * Extend a SmrtObject class with background job methods
57
+ *
58
+ * @param BaseClass - The SmrtObject class to extend
59
+ * @returns Extended class with .bg() and .background() methods
60
+ *
61
+ * @example
62
+ * const BackgroundDocument = withBackgroundJobs(Document);
63
+ * const doc = new BackgroundDocument({ ... });
64
+ * const handle = await doc.bg('generateSummary', { format: 'md' });
65
+ */
66
+ export declare function withBackgroundJobs<T extends SmrtObjectConstructor>(BaseClass: T): BackgroundCapableConstructor<T>;
67
+ export default withBackgroundJobs;
68
+ //# sourceMappingURL=object-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-extension.d.ts","sourceRoot":"","sources":["../src/object-extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3E,OAAO,EACL,UAAU,EAIX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,QAAQ,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC3D,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;OAUG;IACH,EAAE,CAAC,CAAC,GAAG,OAAO,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE,SAAS,GAClB,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzB;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,CAAC,GAAG,OAAO,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,UAAU,CAAC,CAAC,CAAC,CAAC;CAClB;AAkCD,KAAK,qBAAqB,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,UAAU,CAAC;AAChE,KAAK,4BAA4B,CAAC,CAAC,SAAS,qBAAqB,IAAI,CAAC,GAAG;IACvE,KAAK,GAAG,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC;CAC9E,CAAC;AAiIF;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,qBAAqB,EAChE,SAAS,EAAE,CAAC,GACX,4BAA4B,CAAC,CAAC,CAAC,CAqBjC;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default } from './svelte/playground.js';
2
+ //# sourceMappingURL=playground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,179 @@
1
+ import { JOBS_MODULE_META } from "./ui.js";
2
+ const noop = () => {
3
+ };
4
+ const sampleJobs = [
5
+ {
6
+ id: "job-publish-1",
7
+ queue: "content",
8
+ objectType: "@happyvertical/smrt-content:Article",
9
+ objectId: "article-aurora-kitchen",
10
+ method: "publish",
11
+ args: { force: false },
12
+ status: "running",
13
+ priority: 80,
14
+ attempts: 1,
15
+ maxAttempts: 3,
16
+ timeout: 6e5,
17
+ timeoutBehavior: "fail",
18
+ runAt: "2026-03-21T16:15:00.000Z",
19
+ startedAt: "2026-03-21T16:15:15.000Z",
20
+ completedAt: null,
21
+ lastError: null,
22
+ resultPointer: null,
23
+ workerId: "worker-content-1",
24
+ createdAt: "2026-03-21T16:14:50.000Z",
25
+ updatedAt: "2026-03-21T16:15:20.000Z"
26
+ },
27
+ {
28
+ id: "job-review-2",
29
+ queue: "governance",
30
+ objectType: "@happyvertical/smrt-content:GovernancePolicy",
31
+ objectId: "policy-facts",
32
+ method: "recalculateReadiness",
33
+ args: { profileKey: "publication" },
34
+ status: "failed",
35
+ priority: 95,
36
+ attempts: 3,
37
+ maxAttempts: 3,
38
+ timeout: 3e5,
39
+ timeoutBehavior: "fail",
40
+ runAt: "2026-03-21T15:40:00.000Z",
41
+ startedAt: "2026-03-21T15:40:02.000Z",
42
+ completedAt: "2026-03-21T15:41:11.000Z",
43
+ lastError: "Relationship column missing during readiness sync.",
44
+ resultPointer: null,
45
+ workerId: "worker-governance-2",
46
+ createdAt: "2026-03-21T15:39:30.000Z",
47
+ updatedAt: "2026-03-21T15:41:11.000Z"
48
+ },
49
+ {
50
+ id: "job-export-3",
51
+ queue: "exports",
52
+ objectType: "@happyvertical/smrt-content:ArticleCollection",
53
+ objectId: null,
54
+ method: "buildStaticFeed",
55
+ args: { destination: "cdn" },
56
+ status: "completed",
57
+ priority: 40,
58
+ attempts: 1,
59
+ maxAttempts: 2,
60
+ timeout: 9e5,
61
+ timeoutBehavior: "warn",
62
+ runAt: "2026-03-21T14:30:00.000Z",
63
+ startedAt: "2026-03-21T14:30:00.000Z",
64
+ completedAt: "2026-03-21T14:31:25.000Z",
65
+ lastError: null,
66
+ resultPointer: "results/exports/build-static-feed-3.json",
67
+ workerId: "worker-export-1",
68
+ createdAt: "2026-03-21T14:29:52.000Z",
69
+ updatedAt: "2026-03-21T14:31:25.000Z"
70
+ }
71
+ ];
72
+ const sampleStats = {
73
+ total: 3421,
74
+ pending: 24,
75
+ ready: 13,
76
+ running: 4,
77
+ completed: 3340,
78
+ failed: 31,
79
+ cancelled: 9,
80
+ avgDuration: 18450,
81
+ successRate: 0.976
82
+ };
83
+ const sampleQueues = [
84
+ {
85
+ name: "content",
86
+ pending: 8,
87
+ running: 2,
88
+ completed24h: 412,
89
+ failed24h: 4,
90
+ avgDuration: 22800
91
+ },
92
+ {
93
+ name: "governance",
94
+ pending: 5,
95
+ running: 1,
96
+ completed24h: 188,
97
+ failed24h: 7,
98
+ avgDuration: 31200
99
+ },
100
+ {
101
+ name: "exports",
102
+ pending: 11,
103
+ running: 1,
104
+ completed24h: 94,
105
+ failed24h: 1,
106
+ avgDuration: 52200
107
+ }
108
+ ];
109
+ const loadJobDashboard = () => import("./svelte/components/JobDashboard.svelte");
110
+ const loadJobDetail = () => import("./svelte/components/JobDetail.svelte");
111
+ const loadJobStatusBadge = () => import("./svelte/components/JobStatusBadge.svelte");
112
+ const playground = {
113
+ packageName: "@happyvertical/smrt-jobs",
114
+ displayName: JOBS_MODULE_META.displayName,
115
+ description: JOBS_MODULE_META.description,
116
+ moduleMeta: JOBS_MODULE_META,
117
+ entries: [
118
+ {
119
+ id: "job-dashboard",
120
+ title: "Job Dashboard",
121
+ description: "Operational overview for background job queues with recent and failed work.",
122
+ loadComponent: loadJobDashboard,
123
+ order: 1,
124
+ props: {
125
+ stats: sampleStats,
126
+ queues: sampleQueues,
127
+ recentJobs: sampleJobs,
128
+ failedJobs: sampleJobs.filter((job) => job.status === "failed"),
129
+ onJobClick: noop,
130
+ onRetry: noop,
131
+ onCancel: noop,
132
+ onViewAll: noop,
133
+ onViewFailed: noop
134
+ },
135
+ modes: {
136
+ mock: {
137
+ label: "Mock"
138
+ }
139
+ }
140
+ },
141
+ {
142
+ id: "job-detail",
143
+ title: "Job Detail",
144
+ description: "Detailed execution view for a single background job with retry and cancellation actions.",
145
+ loadComponent: loadJobDetail,
146
+ order: 2,
147
+ props: {
148
+ job: sampleJobs[1],
149
+ onRetry: noop,
150
+ onDelete: noop
151
+ },
152
+ modes: {
153
+ mock: {
154
+ label: "Mock"
155
+ }
156
+ }
157
+ },
158
+ {
159
+ id: "job-status-badge",
160
+ title: "Job Status Badge",
161
+ description: "Compact status treatment used throughout the jobs surface.",
162
+ loadComponent: loadJobStatusBadge,
163
+ order: 3,
164
+ props: {
165
+ status: "running",
166
+ size: "md"
167
+ },
168
+ modes: {
169
+ mock: {
170
+ label: "Mock"
171
+ }
172
+ }
173
+ }
174
+ ]
175
+ };
176
+ export {
177
+ playground as default
178
+ };
179
+ //# sourceMappingURL=playground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.js","sources":["../src/svelte/playground.ts"],"sourcesContent":["import { JOBS_MODULE_META } from '../ui.js';\n\nconst noop = () => {};\n\nconst sampleJobs = [\n {\n id: 'job-publish-1',\n queue: 'content',\n objectType: '@happyvertical/smrt-content:Article',\n objectId: 'article-aurora-kitchen',\n method: 'publish',\n args: { force: false },\n status: 'running',\n priority: 80,\n attempts: 1,\n maxAttempts: 3,\n timeout: 600000,\n timeoutBehavior: 'fail',\n runAt: '2026-03-21T16:15:00.000Z',\n startedAt: '2026-03-21T16:15:15.000Z',\n completedAt: null,\n lastError: null,\n resultPointer: null,\n workerId: 'worker-content-1',\n createdAt: '2026-03-21T16:14:50.000Z',\n updatedAt: '2026-03-21T16:15:20.000Z',\n },\n {\n id: 'job-review-2',\n queue: 'governance',\n objectType: '@happyvertical/smrt-content:GovernancePolicy',\n objectId: 'policy-facts',\n method: 'recalculateReadiness',\n args: { profileKey: 'publication' },\n status: 'failed',\n priority: 95,\n attempts: 3,\n maxAttempts: 3,\n timeout: 300000,\n timeoutBehavior: 'fail',\n runAt: '2026-03-21T15:40:00.000Z',\n startedAt: '2026-03-21T15:40:02.000Z',\n completedAt: '2026-03-21T15:41:11.000Z',\n lastError: 'Relationship column missing during readiness sync.',\n resultPointer: null,\n workerId: 'worker-governance-2',\n createdAt: '2026-03-21T15:39:30.000Z',\n updatedAt: '2026-03-21T15:41:11.000Z',\n },\n {\n id: 'job-export-3',\n queue: 'exports',\n objectType: '@happyvertical/smrt-content:ArticleCollection',\n objectId: null,\n method: 'buildStaticFeed',\n args: { destination: 'cdn' },\n status: 'completed',\n priority: 40,\n attempts: 1,\n maxAttempts: 2,\n timeout: 900000,\n timeoutBehavior: 'warn',\n runAt: '2026-03-21T14:30:00.000Z',\n startedAt: '2026-03-21T14:30:00.000Z',\n completedAt: '2026-03-21T14:31:25.000Z',\n lastError: null,\n resultPointer: 'results/exports/build-static-feed-3.json',\n workerId: 'worker-export-1',\n createdAt: '2026-03-21T14:29:52.000Z',\n updatedAt: '2026-03-21T14:31:25.000Z',\n },\n];\n\nconst sampleStats = {\n total: 3421,\n pending: 24,\n ready: 13,\n running: 4,\n completed: 3340,\n failed: 31,\n cancelled: 9,\n avgDuration: 18450,\n successRate: 0.976,\n};\n\nconst sampleQueues = [\n {\n name: 'content',\n pending: 8,\n running: 2,\n completed24h: 412,\n failed24h: 4,\n avgDuration: 22800,\n },\n {\n name: 'governance',\n pending: 5,\n running: 1,\n completed24h: 188,\n failed24h: 7,\n avgDuration: 31200,\n },\n {\n name: 'exports',\n pending: 11,\n running: 1,\n completed24h: 94,\n failed24h: 1,\n avgDuration: 52200,\n },\n];\n\nconst loadJobDashboard = () => import('./components/JobDashboard.svelte');\nconst loadJobDetail = () => import('./components/JobDetail.svelte');\nconst loadJobStatusBadge = () => import('./components/JobStatusBadge.svelte');\n\nexport default {\n packageName: '@happyvertical/smrt-jobs',\n displayName: JOBS_MODULE_META.displayName,\n description: JOBS_MODULE_META.description,\n moduleMeta: JOBS_MODULE_META,\n entries: [\n {\n id: 'job-dashboard',\n title: 'Job Dashboard',\n description:\n 'Operational overview for background job queues with recent and failed work.',\n loadComponent: loadJobDashboard,\n order: 1,\n props: {\n stats: sampleStats,\n queues: sampleQueues,\n recentJobs: sampleJobs,\n failedJobs: sampleJobs.filter((job) => job.status === 'failed'),\n onJobClick: noop,\n onRetry: noop,\n onCancel: noop,\n onViewAll: noop,\n onViewFailed: noop,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'job-detail',\n title: 'Job Detail',\n description:\n 'Detailed execution view for a single background job with retry and cancellation actions.',\n loadComponent: loadJobDetail,\n order: 2,\n props: {\n job: sampleJobs[1],\n onRetry: noop,\n onDelete: noop,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'job-status-badge',\n title: 'Job Status Badge',\n description: 'Compact status treatment used throughout the jobs surface.',\n loadComponent: loadJobStatusBadge,\n order: 3,\n props: {\n status: 'running',\n size: 'md',\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n ],\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { DatabaseInterface } from '@happyvertical/sql';
3
+ import { SmrtJob } from './smrt-job.js';
4
+ import { SmrtJobEvent } from './smrt-job-event.js';
5
+ /**
6
+ * TaskRunner configuration
7
+ */
8
+ export interface TaskRunnerConfig {
9
+ /** Worker ID (auto-generated if not provided) */
10
+ id?: string;
11
+ /** Number of concurrent jobs to process */
12
+ concurrency?: number;
13
+ /** Queues to process (default: ['default']) */
14
+ queues?: string[];
15
+ /** Polling interval in milliseconds */
16
+ pollInterval?: number;
17
+ /** Heartbeat interval in milliseconds */
18
+ heartbeatInterval?: number;
19
+ /** Maximum time to wait for jobs to complete on shutdown */
20
+ shutdownTimeout?: number;
21
+ /**
22
+ * @deprecated No longer used. Recovery keys on worker liveness, not per-job
23
+ * heartbeat staleness (#1474). Use {@link leaseTtlMs} / {@link leaseTickMs}.
24
+ */
25
+ staleJobThresholdMs?: number;
26
+ /** Worker liveness lease time-to-live in milliseconds */
27
+ leaseTtlMs?: number;
28
+ /** How often to renew the worker liveness lease, in milliseconds */
29
+ leaseTickMs?: number;
30
+ }
31
+ /**
32
+ * TaskRunner events
33
+ */
34
+ export interface TaskRunnerEvents {
35
+ 'job:started': (job: SmrtJob) => void;
36
+ 'job:event': (job: SmrtJob, event: SmrtJobEvent) => void;
37
+ 'job:progress': (job: SmrtJob, event: SmrtJobEvent) => void;
38
+ 'job:completed': (job: SmrtJob, result: unknown) => void;
39
+ 'job:failed': (job: SmrtJob, error: Error) => void;
40
+ 'job:retrying': (job: SmrtJob, error: Error, delay: number) => void;
41
+ 'runner:started': () => void;
42
+ 'runner:stopped': () => void;
43
+ 'runner:error': (error: Error) => void;
44
+ }
45
+ /**
46
+ * TaskRunner processes SMRT jobs by invoking methods on SmrtObjects
47
+ *
48
+ * Features:
49
+ * - Executes jobs via SmrtObject method invocation
50
+ * - Configurable concurrency and timeout behavior
51
+ * - Automatic retry with configurable strategies
52
+ * - Job context logging for visibility
53
+ * - Embedded mode (in-process) or standalone (CLI)
54
+ */
55
+ export declare class TaskRunner extends EventEmitter {
56
+ readonly id: string;
57
+ /**
58
+ * Per-incarnation-unique worker key. Stored as the `worker_id` on claimed
59
+ * jobs and in `_smrt_workers`, so a restart of a runner sharing the same
60
+ * configured `id` does not look like it still owns the previous
61
+ * incarnation's orphaned jobs. The human-facing {@link id} stays stable for
62
+ * events/logs.
63
+ */
64
+ private readonly workerKey;
65
+ private readonly config;
66
+ private readonly effectiveLeaseTtlMs;
67
+ private collection;
68
+ private eventCollection;
69
+ private workerCollection;
70
+ private workersTableVerified;
71
+ private lastRecoverySweepAt;
72
+ private running;
73
+ private activeJobs;
74
+ private pollTimer;
75
+ private heartbeatTimer;
76
+ private leaseTimer;
77
+ private livenessWorker;
78
+ private shutdownPromise;
79
+ private db;
80
+ private logger;
81
+ constructor(config?: TaskRunnerConfig);
82
+ /**
83
+ * Initialize the runner with database connection
84
+ */
85
+ initialize(db: DatabaseInterface): Promise<void>;
86
+ /**
87
+ * Start processing jobs
88
+ */
89
+ start(): Promise<void>;
90
+ /**
91
+ * Stop processing jobs (graceful shutdown)
92
+ */
93
+ stop(): Promise<void>;
94
+ /**
95
+ * Check if runner is running
96
+ */
97
+ isRunning(): boolean;
98
+ /**
99
+ * Get count of active jobs
100
+ */
101
+ activeJobCount(): number;
102
+ /**
103
+ * Start the polling loop
104
+ */
105
+ private startPolling;
106
+ /**
107
+ * Poll for and process jobs
108
+ */
109
+ private poll;
110
+ /**
111
+ * Process a single job
112
+ */
113
+ private processJob;
114
+ /**
115
+ * Apply a terminal/retry state transition to a job only if this worker still
116
+ * owns it and it is still `running`. Returns whether the write applied.
117
+ *
118
+ * This closes the completion-vs-recovery race: if recovery already failed a
119
+ * job out from under a finishing handler (a genuine zombie), the handler's
120
+ * outcome is dropped rather than resurrecting the row.
121
+ */
122
+ private writeOwnedJob;
123
+ /**
124
+ * Execute a job by invoking the method on the SmrtObject
125
+ */
126
+ private executeJob;
127
+ /**
128
+ * Handle job execution error
129
+ */
130
+ private handleJobError;
131
+ private createExecutionContext;
132
+ private appendJobEvent;
133
+ /**
134
+ * Whether the `_smrt_workers` table exists. Cached once positive — the table
135
+ * never disappears mid-run, so this avoids a probe query on every poll.
136
+ */
137
+ private workersTableReady;
138
+ /**
139
+ * Recover jobs orphaned by dead/restarted workers.
140
+ *
141
+ * A `running` job is recovered only when its owning worker is *not alive*
142
+ * (issue #1474): not live in this process and holding no fresh lease in
143
+ * `_smrt_workers`. This is independent of the handler event loop, so a worker
144
+ * whose handler holds the loop synchronously keeps a fresh lease (renewed off
145
+ * the loop by the liveness thread) or stays in this process's live set, and is
146
+ * never false-recovered. The live set takes precedence over a stale lease, and
147
+ * a runner never recovers its own active jobs.
148
+ *
149
+ * Recovery is swept at most once per lease tick (not every poll), since
150
+ * detection is TTL-bound anyway — this bounds the per-poll database load.
151
+ */
152
+ private recoverStaleJobs;
153
+ /**
154
+ * Renew this worker's liveness lease.
155
+ *
156
+ * In Stage 1 this runs on the main event loop, so it provides cross-process
157
+ * detection no weaker than the old per-job heartbeat. Stage 2 moves the
158
+ * renewal to an off-loop worker thread so a synchronous handler can no longer
159
+ * starve it. Same-process correctness never depends on this timer — the
160
+ * in-memory live set covers it.
161
+ */
162
+ private startLeaseRenewal;
163
+ /**
164
+ * Spawn the off-loop liveness thread. It opens its own connection and renews
165
+ * this worker's lease on its own thread (unstarvable by handler CPU). Returns
166
+ * false if the thread can't be resolved or fails to start, so the caller can
167
+ * fall back to main-loop renewal.
168
+ */
169
+ private startLivenessThread;
170
+ private handleLivenessThreadLoss;
171
+ /** Stop the liveness thread (graceful, with a short bound), if running. */
172
+ private stopLivenessThread;
173
+ /**
174
+ * Per-job heartbeat loop — telemetry only ("last activity" for the UI). It no
175
+ * longer gates recovery (that is the worker lease), so a blocked loop missing
176
+ * a heartbeat is harmless.
177
+ */
178
+ private startHeartbeat;
179
+ /**
180
+ * Wait for active jobs to complete with timeout
181
+ */
182
+ private waitForActiveJobs;
183
+ }
184
+ /**
185
+ * Create a TaskRunner instance
186
+ */
187
+ export declare function createTaskRunner(config?: TaskRunnerConfig): TaskRunner;
188
+ export default TaskRunner;
189
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
package/dist/runner.js ADDED
@@ -0,0 +1,15 @@
1
+ import { T, l, T as T2 } from "./chunks/runner-DV8FBO0y.js";
2
+ import "node:events";
3
+ import "node:worker_threads";
4
+ import "@happyvertical/jobs";
5
+ import "@happyvertical/logger";
6
+ import "@happyvertical/smrt-core";
7
+ import "@happyvertical/smrt-tenancy";
8
+ import "@happyvertical/utils";
9
+ import "./chunks/worker-liveness-DOTjoIjr.js";
10
+ export {
11
+ T as TaskRunner,
12
+ l as createTaskRunner,
13
+ T2 as default
14
+ };
15
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -0,0 +1,151 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { DatabaseInterface } from '@happyvertical/sql';
3
+ /**
4
+ * ScheduleRunner configuration
5
+ */
6
+ export interface ScheduleRunnerConfig {
7
+ /** Runner ID (auto-generated if not provided) */
8
+ id?: string;
9
+ /** Polling interval in milliseconds (default: 60000 - 1 minute) */
10
+ pollInterval?: number;
11
+ /** Maximum schedules to process per poll */
12
+ batchSize?: number;
13
+ /**
14
+ * @deprecated No longer used. Slot reconciliation keys on worker liveness
15
+ * (the `_smrt_workers` lease), not per-job heartbeat staleness (#1474).
16
+ */
17
+ staleJobThresholdMs?: number;
18
+ /**
19
+ * @deprecated No longer used. See {@link staleJobThresholdMs}.
20
+ */
21
+ taskHeartbeatInterval?: number;
22
+ }
23
+ /**
24
+ * ScheduleRunner events
25
+ */
26
+ export interface ScheduleRunnerEvents {
27
+ 'schedule:triggered': (schedule: ScheduleInfo) => void;
28
+ 'schedule:error': (schedule: ScheduleInfo, error: Error) => void;
29
+ 'schedule:completed': (scheduleId: string) => void;
30
+ 'schedule:failed': (scheduleId: string, error: string) => void;
31
+ 'runner:started': () => void;
32
+ 'runner:stopped': () => void;
33
+ 'runner:error': (error: Error) => void;
34
+ }
35
+ /**
36
+ * Schedule info for events
37
+ */
38
+ export interface ScheduleInfo {
39
+ id: string;
40
+ agentType: string;
41
+ agentId: string | null;
42
+ cron: string;
43
+ }
44
+ /**
45
+ * ScheduleRunner polls for due agent schedules and creates jobs for them
46
+ *
47
+ * This runner works in conjunction with TaskRunner:
48
+ * 1. ScheduleRunner checks for due schedules based on cron expressions
49
+ * 2. When a schedule is due, it creates a SmrtJob for the agent
50
+ * 3. TaskRunner picks up and executes the job
51
+ * 4. On job completion/failure, call handleJobCompletion() to update the schedule
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const scheduleRunner = new ScheduleRunner({ pollInterval: 30000 });
56
+ * await scheduleRunner.initialize(db);
57
+ * await scheduleRunner.start();
58
+ *
59
+ * // Wire up TaskRunner events to update schedule state
60
+ * taskRunner.on('job:completed', (job) => {
61
+ * const scheduleId = job.args?._scheduleId;
62
+ * if (scheduleId) scheduleRunner.handleJobCompletion(scheduleId, true);
63
+ * });
64
+ * taskRunner.on('job:failed', (job, error) => {
65
+ * const scheduleId = job.args?._scheduleId;
66
+ * if (scheduleId) scheduleRunner.handleJobCompletion(scheduleId, false, error.message);
67
+ * });
68
+ *
69
+ * // Graceful shutdown
70
+ * process.on('SIGTERM', () => scheduleRunner.stop());
71
+ * ```
72
+ */
73
+ export declare class ScheduleRunner extends EventEmitter {
74
+ readonly id: string;
75
+ private readonly config;
76
+ private jobCollection;
77
+ private workerCollection;
78
+ private running;
79
+ private pollTimer;
80
+ private db;
81
+ private logger;
82
+ constructor(config?: ScheduleRunnerConfig);
83
+ /**
84
+ * Initialize the runner with database connection
85
+ */
86
+ initialize(db: DatabaseInterface): Promise<void>;
87
+ /**
88
+ * Start processing schedules
89
+ */
90
+ start(): Promise<void>;
91
+ /**
92
+ * Stop processing schedules
93
+ */
94
+ stop(): Promise<void>;
95
+ /**
96
+ * Check if runner is running
97
+ */
98
+ isRunning(): boolean;
99
+ /**
100
+ * Handle job completion for a scheduled job.
101
+ *
102
+ * Call this from TaskRunner's job:completed / job:failed events
103
+ * when the job has a `_scheduleId` in its args.
104
+ */
105
+ handleJobCompletion(scheduleId: string, success: boolean, errorMessage?: string): Promise<void>;
106
+ /**
107
+ * Start the polling loop
108
+ */
109
+ private startPolling;
110
+ /**
111
+ * Poll for due schedules and create jobs
112
+ */
113
+ private poll;
114
+ /**
115
+ * Reconcile stuck schedule slots against running jobs.
116
+ *
117
+ * This handles two failure modes:
118
+ * - a running job's owning worker is no longer alive (dead/restarted)
119
+ * - a schedule slot remains occupied even though no running job still exists
120
+ *
121
+ * Staleness keys on worker *liveness* (issue #1474), not per-job heartbeat
122
+ * freshness: a job whose `worker_id` is live in this process or holds a fresh
123
+ * lease in `_smrt_workers` is healthy even if its handler is holding the loop
124
+ * synchronously. ScheduleRunner has no in-process active-job set, so this is
125
+ * its entire correctness mechanism.
126
+ */
127
+ private recoverStaleScheduleState;
128
+ private getScheduleIdFromJobArgs;
129
+ /**
130
+ * Trigger a schedule by creating a job
131
+ */
132
+ private triggerSchedule;
133
+ }
134
+ /**
135
+ * Validate a standard 5-field cron expression: field count plus per-field
136
+ * value ranges. Throws a descriptive `Error` on the first invalid field.
137
+ *
138
+ * Exposed so callers (and the agents package, which owns schedule creation)
139
+ * can reject a bad cron at write time rather than letting an out-of-range
140
+ * field silently never match (S5 audit #1402).
141
+ *
142
+ * @param cron - The cron expression to validate.
143
+ * @returns The trimmed, whitespace-split fields when valid.
144
+ */
145
+ export declare function validateCronExpression(cron: string): string[];
146
+ /**
147
+ * Create a ScheduleRunner instance
148
+ */
149
+ export declare function createScheduleRunner(config?: ScheduleRunnerConfig): ScheduleRunner;
150
+ export default ScheduleRunner;
151
+ //# sourceMappingURL=schedule-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-runner.d.ts","sourceRoot":"","sources":["../src/schedule-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAW5D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IACvD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjE,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,gBAAgB,CAAqC;IAC7D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,EAAE,CAAkC;IAC5C,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,GAAE,oBAAyB;IAU7C;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;;OAKG;IACG,mBAAmB,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IAgDhB;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;YACW,IAAI;IAyBlB;;;;;;;;;;;;OAYG;YACW,yBAAyB;IA4IvC,OAAO,CAAC,wBAAwB;IA0BhC;;OAEG;YACW,eAAe;CA0G9B;AAwGD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAa7D;AAwGD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,cAAc,CAEhB;AAED,eAAe,cAAc,CAAC"}