@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,191 @@
1
+ /**
2
+ * Types for background job UI components
3
+ */
4
+ import type { Snippet } from 'svelte';
5
+ export type JobStatus = 'pending' | 'ready' | 'running' | 'completed' | 'failed' | 'cancelled';
6
+ export type JobPriority = 'low' | 'normal' | 'high' | 'critical';
7
+ export type TimeoutBehavior = 'fail' | 'kill' | 'warn';
8
+ /**
9
+ * Job data structure for display
10
+ */
11
+ export interface JobData {
12
+ id: string;
13
+ queue: string;
14
+ objectType: string;
15
+ objectId: string | null;
16
+ method: string;
17
+ args: Record<string, unknown>;
18
+ status: JobStatus;
19
+ priority: number;
20
+ attempts: number;
21
+ maxAttempts: number;
22
+ timeout: number;
23
+ timeoutBehavior: TimeoutBehavior;
24
+ runAt: Date | string;
25
+ startedAt: Date | string | null;
26
+ completedAt: Date | string | null;
27
+ lastError: string | null;
28
+ resultPointer: string | null;
29
+ workerId: string | null;
30
+ createdAt: Date | string;
31
+ updatedAt: Date | string;
32
+ }
33
+ /**
34
+ * Job statistics for dashboard
35
+ */
36
+ export interface JobStats {
37
+ total: number;
38
+ pending: number;
39
+ ready: number;
40
+ running: number;
41
+ completed: number;
42
+ failed: number;
43
+ cancelled: number;
44
+ avgDuration: number | null;
45
+ successRate: number | null;
46
+ }
47
+ /**
48
+ * Queue statistics
49
+ */
50
+ export interface QueueStats {
51
+ name: string;
52
+ pending: number;
53
+ running: number;
54
+ completed24h: number;
55
+ failed24h: number;
56
+ avgDuration: number | null;
57
+ }
58
+ /**
59
+ * Filter options for job list
60
+ */
61
+ export interface JobFilter {
62
+ status?: JobStatus | JobStatus[] | 'all';
63
+ queue?: string;
64
+ objectType?: string;
65
+ search?: string;
66
+ limit?: number;
67
+ offset?: number;
68
+ }
69
+ /**
70
+ * Sort options for job list
71
+ */
72
+ export interface JobSort {
73
+ field: 'createdAt' | 'runAt' | 'priority' | 'status';
74
+ direction: 'asc' | 'desc';
75
+ }
76
+ /**
77
+ * JobList component props
78
+ */
79
+ export interface JobListProps {
80
+ /** Jobs to display */
81
+ jobs: JobData[];
82
+ /** Loading state */
83
+ loading?: boolean;
84
+ /** Filter state */
85
+ filter?: JobFilter;
86
+ /** Sort state */
87
+ sort?: JobSort;
88
+ /** Selectable rows */
89
+ selectable?: boolean;
90
+ /** Selected job IDs */
91
+ selected?: Set<string>;
92
+ /** Callback when selection changes */
93
+ onSelectionChange?: (selected: Set<string>) => void;
94
+ /** Callback when job is clicked */
95
+ onJobClick?: (job: JobData) => void;
96
+ /** Callback when retry is clicked */
97
+ onRetry?: (job: JobData) => void;
98
+ /** Callback when cancel is clicked */
99
+ onCancel?: (job: JobData) => void;
100
+ /** Empty state snippet */
101
+ empty?: Snippet;
102
+ }
103
+ /**
104
+ * JobDetail component props
105
+ */
106
+ export interface JobDetailProps {
107
+ /** Job to display */
108
+ job: JobData;
109
+ /** Show result data */
110
+ showResult?: boolean;
111
+ /** Callback when retry is clicked */
112
+ onRetry?: (job: JobData) => void;
113
+ /** Callback when cancel is clicked */
114
+ onCancel?: (job: JobData) => void;
115
+ /** Callback when delete is clicked */
116
+ onDelete?: (job: JobData) => void;
117
+ }
118
+ /**
119
+ * JobStats component props
120
+ */
121
+ export interface JobStatsProps {
122
+ /** Statistics data */
123
+ stats: JobStats;
124
+ /** Queue breakdown */
125
+ queues?: QueueStats[];
126
+ /** Loading state */
127
+ loading?: boolean;
128
+ /** Auto-refresh interval (ms, 0 = disabled) */
129
+ refreshInterval?: number;
130
+ }
131
+ /**
132
+ * JobActions component props
133
+ */
134
+ export interface JobActionsProps {
135
+ /** Job to perform actions on */
136
+ job: JobData;
137
+ /** Show retry button */
138
+ showRetry?: boolean;
139
+ /** Show cancel button */
140
+ showCancel?: boolean;
141
+ /** Show delete button */
142
+ showDelete?: boolean;
143
+ /** Callback when retry is clicked */
144
+ onRetry?: (job: JobData) => void;
145
+ /** Callback when cancel is clicked */
146
+ onCancel?: (job: JobData) => void;
147
+ /** Callback when delete is clicked */
148
+ onDelete?: (job: JobData) => void;
149
+ /** Compact mode */
150
+ compact?: boolean;
151
+ }
152
+ /**
153
+ * JobDashboard component props
154
+ */
155
+ export interface JobDashboardProps {
156
+ /** Statistics data */
157
+ stats: JobStats;
158
+ /** Queue breakdown */
159
+ queues?: QueueStats[];
160
+ /** Recent jobs */
161
+ recentJobs?: JobData[];
162
+ /** Failed jobs */
163
+ failedJobs?: JobData[];
164
+ /** Loading state */
165
+ loading?: boolean;
166
+ /** Callback when job is clicked */
167
+ onJobClick?: (job: JobData) => void;
168
+ /** Callback when retry is clicked */
169
+ onRetry?: (job: JobData) => void;
170
+ }
171
+ /**
172
+ * Helper function to get status variant for Badge
173
+ */
174
+ export declare function getStatusVariant(status: JobStatus): 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info';
175
+ /**
176
+ * Helper function to format duration
177
+ */
178
+ export declare function formatDuration(ms: number | null): string;
179
+ /**
180
+ * Helper function to format relative time
181
+ */
182
+ export declare function formatRelativeTime(date: Date | string | null): string;
183
+ /**
184
+ * Helper function to get priority label
185
+ */
186
+ export declare function getPriorityLabel(priority: number): string;
187
+ /**
188
+ * Helper function to get priority color class
189
+ */
190
+ export declare function getPriorityClass(priority: number): string;
191
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/svelte/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Helper function to get status variant for Badge
3
+ */
4
+ export function getStatusVariant(status) {
5
+ switch (status) {
6
+ case 'pending':
7
+ return 'default';
8
+ case 'ready':
9
+ return 'info';
10
+ case 'running':
11
+ return 'primary';
12
+ case 'completed':
13
+ return 'success';
14
+ case 'failed':
15
+ return 'error';
16
+ case 'cancelled':
17
+ return 'warning';
18
+ default:
19
+ return 'default';
20
+ }
21
+ }
22
+ /**
23
+ * Helper function to format duration
24
+ */
25
+ export function formatDuration(ms) {
26
+ if (ms === null || ms === undefined)
27
+ return '-';
28
+ if (ms < 1000)
29
+ return `${ms}ms`;
30
+ if (ms < 60000)
31
+ return `${(ms / 1000).toFixed(1)}s`;
32
+ if (ms < 3600000)
33
+ return `${(ms / 60000).toFixed(1)}m`;
34
+ return `${(ms / 3600000).toFixed(1)}h`;
35
+ }
36
+ /**
37
+ * Helper function to format relative time
38
+ */
39
+ export function formatRelativeTime(date) {
40
+ if (!date)
41
+ return '-';
42
+ const d = typeof date === 'string' ? new Date(date) : date;
43
+ const now = new Date();
44
+ const diff = now.getTime() - d.getTime();
45
+ if (diff < 0) {
46
+ // Future
47
+ const absDiff = Math.abs(diff);
48
+ if (absDiff < 60000)
49
+ return 'in a moment';
50
+ if (absDiff < 3600000)
51
+ return `in ${Math.round(absDiff / 60000)}m`;
52
+ if (absDiff < 86400000)
53
+ return `in ${Math.round(absDiff / 3600000)}h`;
54
+ return `in ${Math.round(absDiff / 86400000)}d`;
55
+ }
56
+ if (diff < 60000)
57
+ return 'just now';
58
+ if (diff < 3600000)
59
+ return `${Math.round(diff / 60000)}m ago`;
60
+ if (diff < 86400000)
61
+ return `${Math.round(diff / 3600000)}h ago`;
62
+ return `${Math.round(diff / 86400000)}d ago`;
63
+ }
64
+ /**
65
+ * Helper function to get priority label
66
+ */
67
+ export function getPriorityLabel(priority) {
68
+ if (priority >= 90)
69
+ return 'Critical';
70
+ if (priority >= 75)
71
+ return 'High';
72
+ if (priority >= 25)
73
+ return 'Normal';
74
+ return 'Low';
75
+ }
76
+ /**
77
+ * Helper function to get priority color class
78
+ */
79
+ export function getPriorityClass(priority) {
80
+ if (priority >= 90)
81
+ return 'priority-critical';
82
+ if (priority >= 75)
83
+ return 'priority-high';
84
+ if (priority >= 25)
85
+ return 'priority-normal';
86
+ return 'priority-low';
87
+ }
package/dist/ui.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { ModuleUISlot, SmrtModuleMeta } from '@happyvertical/smrt-types';
2
+ /**
3
+ * Jobs module UI slots
4
+ */
5
+ export declare const JOBS_UI_SLOTS: Record<string, ModuleUISlot>;
6
+ /**
7
+ * Jobs module metadata
8
+ */
9
+ export declare const JOBS_MODULE_META: SmrtModuleMeta;
10
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE9E;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAuDtD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAO9B,CAAC"}
package/dist/ui.js ADDED
@@ -0,0 +1,69 @@
1
+ const JOBS_UI_SLOTS = {
2
+ "job-dashboard": {
3
+ id: "job-dashboard",
4
+ label: "Job Dashboard",
5
+ description: "Combined overview panel for background jobs",
6
+ icon: "briefcase",
7
+ category: "admin",
8
+ order: 1,
9
+ propsInterface: "JobDashboardProps"
10
+ },
11
+ "job-list": {
12
+ id: "job-list",
13
+ label: "Job List",
14
+ description: "Filterable, sortable list of background jobs",
15
+ icon: "list",
16
+ category: "list",
17
+ order: 2,
18
+ propsInterface: "JobListProps"
19
+ },
20
+ "job-detail": {
21
+ id: "job-detail",
22
+ label: "Job Detail",
23
+ description: "Detailed view of a single job",
24
+ icon: "file-text",
25
+ category: "detail",
26
+ order: 3,
27
+ propsInterface: "JobDetailProps"
28
+ },
29
+ "job-stats": {
30
+ id: "job-stats",
31
+ label: "Job Stats",
32
+ description: "Statistics dashboard for job queues",
33
+ icon: "bar-chart",
34
+ category: "display",
35
+ order: 4,
36
+ propsInterface: "JobStatsProps"
37
+ },
38
+ "job-actions": {
39
+ id: "job-actions",
40
+ label: "Job Actions",
41
+ description: "Action buttons for job operations",
42
+ icon: "more-horizontal",
43
+ category: "action",
44
+ order: 5,
45
+ propsInterface: "JobActionsProps"
46
+ },
47
+ "job-status-badge": {
48
+ id: "job-status-badge",
49
+ label: "Job Status Badge",
50
+ description: "Status indicator for job states",
51
+ icon: "tag",
52
+ category: "display",
53
+ order: 6,
54
+ propsInterface: "JobStatusBadgeProps"
55
+ }
56
+ };
57
+ const JOBS_MODULE_META = {
58
+ name: "@happyvertical/smrt-jobs",
59
+ displayName: "Jobs",
60
+ description: "Background job processing with persistence and scheduling",
61
+ uiSlots: JOBS_UI_SLOTS,
62
+ models: ["Job", "JobQueue"],
63
+ collections: ["JobCollection", "JobQueueCollection"]
64
+ };
65
+ export {
66
+ JOBS_MODULE_META,
67
+ JOBS_UI_SLOTS
68
+ };
69
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sources":["../src/ui.ts"],"sourcesContent":["/**\n * Jobs Module UI Slot Declarations\n *\n * This file defines the UI extension points for the jobs module.\n * UI components are implemented in the ./svelte subpath.\n */\n\nimport type { ModuleUISlot, SmrtModuleMeta } from '@happyvertical/smrt-types';\n\n/**\n * Jobs module UI slots\n */\nexport const JOBS_UI_SLOTS: Record<string, ModuleUISlot> = {\n 'job-dashboard': {\n id: 'job-dashboard',\n label: 'Job Dashboard',\n description: 'Combined overview panel for background jobs',\n icon: 'briefcase',\n category: 'admin',\n order: 1,\n propsInterface: 'JobDashboardProps',\n },\n 'job-list': {\n id: 'job-list',\n label: 'Job List',\n description: 'Filterable, sortable list of background jobs',\n icon: 'list',\n category: 'list',\n order: 2,\n propsInterface: 'JobListProps',\n },\n 'job-detail': {\n id: 'job-detail',\n label: 'Job Detail',\n description: 'Detailed view of a single job',\n icon: 'file-text',\n category: 'detail',\n order: 3,\n propsInterface: 'JobDetailProps',\n },\n 'job-stats': {\n id: 'job-stats',\n label: 'Job Stats',\n description: 'Statistics dashboard for job queues',\n icon: 'bar-chart',\n category: 'display',\n order: 4,\n propsInterface: 'JobStatsProps',\n },\n 'job-actions': {\n id: 'job-actions',\n label: 'Job Actions',\n description: 'Action buttons for job operations',\n icon: 'more-horizontal',\n category: 'action',\n order: 5,\n propsInterface: 'JobActionsProps',\n },\n 'job-status-badge': {\n id: 'job-status-badge',\n label: 'Job Status Badge',\n description: 'Status indicator for job states',\n icon: 'tag',\n category: 'display',\n order: 6,\n propsInterface: 'JobStatusBadgeProps',\n },\n};\n\n/**\n * Jobs module metadata\n */\nexport const JOBS_MODULE_META: SmrtModuleMeta = {\n name: '@happyvertical/smrt-jobs',\n displayName: 'Jobs',\n description: 'Background job processing with persistence and scheduling',\n uiSlots: JOBS_UI_SLOTS,\n models: ['Job', 'JobQueue'],\n collections: ['JobCollection', 'JobQueueCollection'],\n};\n"],"names":[],"mappings":"AAYO,MAAM,gBAA8C;AAAA,EACzD,iBAAiB;AAAA,IACf,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,gBAAgB;AAAA,EAAA;AAAA,EAElB,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,gBAAgB;AAAA,EAAA;AAAA,EAElB,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,gBAAgB;AAAA,EAAA;AAAA,EAElB,aAAa;AAAA,IACX,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,gBAAgB;AAAA,EAAA;AAAA,EAElB,eAAe;AAAA,IACb,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,gBAAgB;AAAA,EAAA;AAAA,EAElB,oBAAoB;AAAA,IAClB,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,gBAAgB;AAAA,EAAA;AAEpB;AAKO,MAAM,mBAAmC;AAAA,EAC9C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,EACb,SAAS;AAAA,EACT,QAAQ,CAAC,OAAO,UAAU;AAAA,EAC1B,aAAa,CAAC,iBAAiB,oBAAoB;AACrD;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker-liveness-thread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-liveness-thread.d.ts","sourceRoot":"","sources":["../src/worker-liveness-thread.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ import { parentPort, workerData } from "node:worker_threads";
2
+ import { getDatabase } from "@happyvertical/sql";
3
+ import { t as tuneSqliteForConcurrency } from "./chunks/worker-liveness-DOTjoIjr.js";
4
+ async function runLivenessTicker(options) {
5
+ const db = await getDatabase({
6
+ url: options.url,
7
+ type: options.type
8
+ });
9
+ const looksSqlite = (options.type ?? "").toLowerCase() === "sqlite" || !options.type && /^file:|\.(db|sqlite)\b|:memory:/i.test(options.url);
10
+ if (looksSqlite) await tuneSqliteForConcurrency(db);
11
+ const renew = async () => {
12
+ const now = /* @__PURE__ */ new Date();
13
+ const expiresAt = new Date(
14
+ now.getTime() + options.leaseTtlMs
15
+ ).toISOString();
16
+ await db.query(
17
+ `UPDATE _smrt_workers
18
+ SET lease_expires_at = ?,
19
+ heartbeat_at = ?
20
+ WHERE worker_id = ?`,
21
+ expiresAt,
22
+ now.toISOString(),
23
+ options.workerKey
24
+ );
25
+ };
26
+ try {
27
+ await renew();
28
+ } catch (error) {
29
+ await db.close?.().catch(() => {
30
+ });
31
+ throw error;
32
+ }
33
+ const timer = setInterval(() => {
34
+ renew().catch(() => {
35
+ });
36
+ }, options.leaseTickMs);
37
+ let stopped = false;
38
+ return {
39
+ stop: async () => {
40
+ if (stopped) return;
41
+ stopped = true;
42
+ clearInterval(timer);
43
+ try {
44
+ await db.close?.();
45
+ } catch {
46
+ }
47
+ }
48
+ };
49
+ }
50
+ async function main() {
51
+ const ticker = await runLivenessTicker(workerData);
52
+ parentPort?.on("message", async (message) => {
53
+ if (message === "stop") {
54
+ await ticker.stop();
55
+ parentPort?.postMessage("stopped");
56
+ }
57
+ });
58
+ parentPort?.postMessage("ready");
59
+ }
60
+ main().catch((error) => {
61
+ parentPort?.postMessage({
62
+ type: "error",
63
+ message: error instanceof Error ? error.message : String(error)
64
+ });
65
+ });
66
+ //# sourceMappingURL=worker-liveness-thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-liveness-thread.js","sources":["../src/worker-liveness-ticker.ts","../src/worker-liveness-thread.ts"],"sourcesContent":["import { getDatabase } from '@happyvertical/sql';\nimport { tuneSqliteForConcurrency } from './worker-liveness.js';\n\n/**\n * Configuration for an off-loop liveness ticker (passed via `workerData`).\n */\nexport interface LivenessTickerOptions {\n /** Database URL the owning runner is using. */\n url: string;\n /** Optional explicit engine/type hint. */\n type?: string;\n /** This runner incarnation's worker key (the `_smrt_workers.worker_id`). */\n workerKey: string;\n /** Lease time-to-live in milliseconds. */\n leaseTtlMs: number;\n /** Renewal cadence in milliseconds. */\n leaseTickMs: number;\n}\n\nexport interface LivenessTicker {\n /** Stop renewing and close the connection. */\n stop: () => Promise<void>;\n}\n\n/**\n * Renew a worker's liveness lease from *outside* the handler event loop.\n *\n * Runs on a `node:worker_threads` thread (or, in tests, directly) with its own\n * database connection, so a CPU-bound synchronous handler on the main thread\n * cannot starve the renewal — the failure mode that made the old heartbeat\n * false-recover running jobs (#1474). A dead process stops renewing and the\n * lease expires within its TTL, which is how recovery detects death.\n */\nexport async function runLivenessTicker(\n options: LivenessTickerOptions,\n): Promise<LivenessTicker> {\n const db = await getDatabase({\n url: options.url,\n type: options.type as 'sqlite' | 'postgres' | 'duckdb' | undefined,\n });\n\n // The ticker's connection shares the SQLite file with the runner's main\n // connection; enable WAL + a busy timeout so renewals don't lose a lock race.\n const looksSqlite =\n (options.type ?? '').toLowerCase() === 'sqlite' ||\n (!options.type && /^file:|\\.(db|sqlite)\\b|:memory:/i.test(options.url));\n if (looksSqlite) await tuneSqliteForConcurrency(db);\n\n const renew = async (): Promise<void> => {\n const now = new Date();\n const expiresAt = new Date(\n now.getTime() + options.leaseTtlMs,\n ).toISOString();\n await db.query(\n `UPDATE _smrt_workers\n SET lease_expires_at = ?,\n heartbeat_at = ?\n WHERE worker_id = ?`,\n expiresAt,\n now.toISOString(),\n options.workerKey,\n );\n };\n\n try {\n // Renew immediately so the lease is fresh the moment the ticker starts.\n await renew();\n } catch (error) {\n // Don't leak the connection if the very first renewal fails.\n await db.close?.().catch(() => {});\n throw error;\n }\n\n const timer = setInterval(() => {\n renew().catch(() => {\n // Transient renewal failures are tolerated; the next tick retries and\n // the lease TTL absorbs a missed beat (TTL >= 3x tick).\n });\n }, options.leaseTickMs);\n\n let stopped = false;\n return {\n stop: async () => {\n if (stopped) return;\n stopped = true;\n clearInterval(timer);\n try {\n await db.close?.();\n } catch {\n // Best-effort connection teardown.\n }\n },\n };\n}\n","/**\n * Worker-thread entry for the off-loop liveness ticker.\n *\n * Thin shell: read {@link LivenessTickerOptions} from `workerData`, start the\n * ticker, and stop it on a `'stop'` message from the parent. All real logic\n * lives in {@link runLivenessTicker} so it can be unit-tested without spawning\n * a thread. Keep this file decorator-free so Node type-stripping can run the\n * `.ts` directly under vitest.\n */\nimport { parentPort, workerData } from 'node:worker_threads';\nimport {\n type LivenessTickerOptions,\n runLivenessTicker,\n} from './worker-liveness-ticker.js';\n\nasync function main(): Promise<void> {\n const ticker = await runLivenessTicker(workerData as LivenessTickerOptions);\n\n parentPort?.on('message', async (message) => {\n if (message === 'stop') {\n await ticker.stop();\n parentPort?.postMessage('stopped');\n }\n });\n\n // Signal the parent that the lease is seeded and renewal is running.\n parentPort?.postMessage('ready');\n}\n\nmain().catch((error) => {\n // Surface startup failure to the parent so the runner can fall back to\n // main-loop renewal rather than silently losing its lease.\n parentPort?.postMessage({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n });\n});\n"],"names":[],"mappings":";;;AAiCA,eAAsB,kBACpB,SACyB;AACzB,QAAM,KAAK,MAAM,YAAY;AAAA,IAC3B,KAAK,QAAQ;AAAA,IACb,MAAM,QAAQ;AAAA,EAAA,CACf;AAID,QAAM,eACH,QAAQ,QAAQ,IAAI,YAAA,MAAkB,YACtC,CAAC,QAAQ,QAAQ,mCAAmC,KAAK,QAAQ,GAAG;AACvE,MAAI,YAAa,OAAM,yBAAyB,EAAE;AAElD,QAAM,QAAQ,YAA2B;AACvC,UAAM,0BAAU,KAAA;AAChB,UAAM,YAAY,IAAI;AAAA,MACpB,IAAI,QAAA,IAAY,QAAQ;AAAA,IAAA,EACxB,YAAA;AACF,UAAM,GAAG;AAAA,MACP;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA,MACA,IAAI,YAAA;AAAA,MACJ,QAAQ;AAAA,IAAA;AAAA,EAEZ;AAEA,MAAI;AAEF,UAAM,MAAA;AAAA,EACR,SAAS,OAAO;AAEd,UAAM,GAAG,UAAU,MAAM,MAAM;AAAA,IAAC,CAAC;AACjC,UAAM;AAAA,EACR;AAEA,QAAM,QAAQ,YAAY,MAAM;AAC9B,UAAA,EAAQ,MAAM,MAAM;AAAA,IAGpB,CAAC;AAAA,EACH,GAAG,QAAQ,WAAW;AAEtB,MAAI,UAAU;AACd,SAAO;AAAA,IACL,MAAM,YAAY;AAChB,UAAI,QAAS;AACb,gBAAU;AACV,oBAAc,KAAK;AACnB,UAAI;AACF,cAAM,GAAG,QAAA;AAAA,MACX,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EAAA;AAEJ;AC9EA,eAAe,OAAsB;AACnC,QAAM,SAAS,MAAM,kBAAkB,UAAmC;AAE1E,cAAY,GAAG,WAAW,OAAO,YAAY;AAC3C,QAAI,YAAY,QAAQ;AACtB,YAAM,OAAO,KAAA;AACb,kBAAY,YAAY,SAAS;AAAA,IACnC;AAAA,EACF,CAAC;AAGD,cAAY,YAAY,OAAO;AACjC;AAEA,OAAO,MAAM,CAAC,UAAU;AAGtB,cAAY,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EAAA,CAC/D;AACH,CAAC;"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Configuration for an off-loop liveness ticker (passed via `workerData`).
3
+ */
4
+ export interface LivenessTickerOptions {
5
+ /** Database URL the owning runner is using. */
6
+ url: string;
7
+ /** Optional explicit engine/type hint. */
8
+ type?: string;
9
+ /** This runner incarnation's worker key (the `_smrt_workers.worker_id`). */
10
+ workerKey: string;
11
+ /** Lease time-to-live in milliseconds. */
12
+ leaseTtlMs: number;
13
+ /** Renewal cadence in milliseconds. */
14
+ leaseTickMs: number;
15
+ }
16
+ export interface LivenessTicker {
17
+ /** Stop renewing and close the connection. */
18
+ stop: () => Promise<void>;
19
+ }
20
+ /**
21
+ * Renew a worker's liveness lease from *outside* the handler event loop.
22
+ *
23
+ * Runs on a `node:worker_threads` thread (or, in tests, directly) with its own
24
+ * database connection, so a CPU-bound synchronous handler on the main thread
25
+ * cannot starve the renewal — the failure mode that made the old heartbeat
26
+ * false-recover running jobs (#1474). A dead process stops renewing and the
27
+ * lease expires within its TTL, which is how recovery detects death.
28
+ */
29
+ export declare function runLivenessTicker(options: LivenessTickerOptions): Promise<LivenessTicker>;
30
+ //# sourceMappingURL=worker-liveness-ticker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-liveness-ticker.d.ts","sourceRoot":"","sources":["../src/worker-liveness-ticker.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,CAAC,CA0DzB"}
@@ -0,0 +1,71 @@
1
+ import { detectEngine } from '@happyvertical/smrt-core';
2
+ import { DatabaseInterface } from '@happyvertical/sql';
3
+ type DatabaseEngine = ReturnType<typeof detectEngine>;
4
+ /** Mark a worker key as live in this process. */
5
+ export declare function registerLiveWorker(workerKey: string): void;
6
+ /** Remove a worker key from this process's live set. */
7
+ export declare function unregisterLiveWorker(workerKey: string): void;
8
+ /** Whether a worker key is live in this process. */
9
+ export declare function isLiveWorker(workerKey: string): boolean;
10
+ /** Snapshot of every worker key live in this process. */
11
+ export declare function liveWorkerKeys(): Set<string>;
12
+ /**
13
+ * Whether a worker is alive: live in *this* process (synchronous truth, never
14
+ * starved), or holding a fresh database lease in some process. `null`/unknown
15
+ * worker keys are never alive.
16
+ */
17
+ export declare function isWorkerAlive(workerKey: string | null | undefined, freshLeaseKeys: Set<string>): boolean;
18
+ /**
19
+ * Build a per-incarnation-unique worker key.
20
+ *
21
+ * Recovery treats a worker key as the unit of liveness, so the key must be
22
+ * unique per process incarnation: a runner that crashes and restarts under the
23
+ * same configured `id` must get a *new* key, otherwise its orphaned `running`
24
+ * jobs would look owned by the live restart and never be recovered. We append
25
+ * a random token to the (optional) configured id, which also keeps the
26
+ * human-facing runner id stable for logs/events.
27
+ */
28
+ export declare function createWorkerKey(baseId: string): string;
29
+ /**
30
+ * The connection URL, honoring adapters that leave `db.url` empty and carry the
31
+ * real URL on `db.config.url`. Used consistently for engine detection, the
32
+ * in-memory check, and the URL handed to the off-loop thread so they never
33
+ * disagree.
34
+ */
35
+ export declare function resolveUrl(db: DatabaseInterface): string;
36
+ /**
37
+ * Tune a SQLite connection for the off-loop liveness topology.
38
+ *
39
+ * The runner's main connection and the off-loop ticker's connection both touch
40
+ * the same file. Stock libsql/SQLite opens in rollback-journal mode with no busy
41
+ * timeout, so the instant two connections contend it returns `SQLITE_BUSY` —
42
+ * surfacing as a flaky "Failed to execute raw query" under CI load. WAL lets
43
+ * readers run concurrently with the single writer, and `busy_timeout` makes a
44
+ * contended writer wait for the lock instead of failing immediately. Both are
45
+ * idempotent and file-level (WAL persists for every connection to the file).
46
+ *
47
+ * Best-effort: a PRAGMA failure must never break startup — the in-process live
48
+ * set keeps same-process recovery correct regardless. Callers gate this on a
49
+ * SQLite engine so it is never issued to Postgres.
50
+ */
51
+ export declare function tuneSqliteForConcurrency(db: DatabaseInterface): Promise<void>;
52
+ /** Resolve the database engine for a connection. */
53
+ export declare function resolveEngine(db: DatabaseInterface): DatabaseEngine;
54
+ /**
55
+ * Whether a connection points at an in-memory SQLite database. In-memory
56
+ * databases are single-process (nothing to recover cross-process) and a second
57
+ * connection cannot see the same data, so the off-loop liveness thread is
58
+ * skipped for them.
59
+ */
60
+ export declare function isInMemory(db: DatabaseInterface): boolean;
61
+ /**
62
+ * Whether the off-loop liveness thread can run against this connection.
63
+ *
64
+ * Requires a second independent connection to the same data: true for Postgres
65
+ * and file-backed SQLite. In-memory SQLite cannot be reached from another
66
+ * connection, and DuckDB is single-writer per file — both fall back to
67
+ * main-loop lease renewal + the in-process live set.
68
+ */
69
+ export declare function offLoopEligible(db: DatabaseInterface): boolean;
70
+ export {};
71
+ //# sourceMappingURL=worker-liveness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-liveness.d.ts","sourceRoot":"","sources":["../src/worker-liveness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAgDtD,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,wDAAwD;AACxD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,yDAAyD;AACzD,wBAAgB,cAAc,IAAI,GAAG,CAAC,MAAM,CAAC,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,OAAO,CAGT;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,CAGxD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,EAAE,EAAE,iBAAiB,GAAG,cAAc,CAOnE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAOzD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAK9D"}